完整的机器人开发指南,包含所有消息类型、API 接口和代码示例
在 APP 中创建机器人后,获取 bot_token,用于 API 认证。
发送图片、视频、音频等媒体消息前,需要先上传文件获取 file_id:
curl -X POST "https://api.bi.ink/bot/uploadfile" \ -H "Authorization: Bearer YOUR_BOT_TOKEN" \ -F "file=@/path/to/image.jpg"
上传接口返回 file_id,发送消息时传递 file_id 即可。
curl -X POST "https://api.bi.ink/bot/sendmessage" \
-H "Authorization: Bearer YOUR_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"group_id": "group_123",
"message_type": "text",
"content": "Hello, World! 👋"
}'
group_id,发送私聊消息使用 target_user_id
所有机器人 API 请求都需要在 Header 中携带认证信息:
Authorization: Bearer YOUR_BOT_TOKEN
机器人支持发送以下类型的消息:
在消息中添加按钮,用户点击后触发回调事件
{
"group_id": "group_123",
"message_type": "text",
"content": "请选择操作:",
"extra": {
"inline_keyboard": [
[
{"text": "确认", "callback_data": "confirm"},
{"text": "取消", "callback_data": "cancel"}
],
[
{"text": "查看详情", "callback_data": "detail"}
]
]
}
}
按钮回调的完整工作流程如下:
extra.inline_keyboard 添加按钮callback_query 事件,包含:
callback_id:回调ID(格式:cb_userId_uniqueId)callback_data:按钮的 callback_data 值message_id:消息IDsender_id:点击按钮的用户ID/bot/answercallback 接口响应,必须在30秒内响应{
"event_type": "callback_query",
"message_id": "msg_abc123",
"sender_id": "user_xxx",
"sender_username": "john",
"sender_display_name": "John Doe",
"group_id": "group_123",
"group_title": "测试群组",
"message_type": "callback",
"content": "confirm",
"timestamp": 1732636800,
"callback_id": "cb_user123_abc12345",
"callback_data": "confirm"
}
curl -X POST "https://api.bi.ink/bot/answercallback" \
-H "Authorization: Bearer YOUR_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"callback_id": "cb_user123_abc12345",
"text": "操作成功!",
"show_alert": false
}'
text:提示文字,会在按钮上显示或弹窗显示(根据 show_alert 决定)show_alert:true 显示弹窗,false 显示提示(默认)url:可选,点击按钮后打开的URL回复指定的消息
{
"group_id": "group_123",
"message_type": "text",
"content": "这是回复内容",
"reply_to_id": "msg_123456"
}
引用指定的消息
{
"group_id": "group_123",
"message_type": "text",
"content": "这是引用内容",
"quote_message_id": "msg_123455"
}
当用户与机器人交互时,系统会向你的 Webhook URL 发送 POST 请求
| 事件类型 | 说明 | 触发时机 |
|---|---|---|
private_message |
私聊消息 | 用户向机器人发送私聊消息 |
group_message |
群组消息 | 用户在群组中@机器人或发送命令 |
member_joined |
成员加入 | 新成员加入机器人所在的群组 |
callback_query |
按钮回调 | 用户点击消息中的按钮 |
{
"event_type": "private_message",
"message_id": "msg_abc123",
"sender_id": "user_xxx",
"sender_username": "john",
"sender_display_name": "John Doe",
"group_id": "",
"group_username": "",
"group_title": "",
"message_type": "text",
"content": "你好",
"timestamp": 1732636800,
"callback_id": "",
"callback_data": ""
}
端点:POST /bot/uploadfile
说明:上传文件,支持图片、视频、音频、文档等文件。返回 file_id。
curl -X POST "https://api.bi.ink/bot/uploadfile" \ -H "Authorization: Bearer YOUR_BOT_TOKEN" \ -F "file=@/path/to/file.jpg"
{
"code": 200,
"msg": "文件上传成功",
"data": {
"file_id": "file_123456"
}
}
| 参数 | 类型 | 说明 | 必需 |
|---|---|---|---|
file |
file | 上传的文件 | ✅ |
端点:POST /bot/sendmessage
说明:向指定会话发送消息。发送媒体消息时只需传递 file_id,后端会自动获取文件信息。
端点:POST /bot/editmessage
说明:编辑已发送的消息
{
"message_id": "msg_xxx",
"content": "✅ 您已确认操作",
"extra": {
"inline_keyboard": []
}
}
端点:POST /bot/deletemessage
说明:删除消息,支持单条和批量删除。
{
"message_id": "msg_xxx"
}
批量删除示例:
{
"message_ids": ["msg_123", "msg_456", "msg_789"]
}
群聊需要管理权限或赋予相关操作权限,私聊中参与者可以删除任何消息。
端点:POST /bot/getme
说明:获取当前机器人的基本信息
端点:POST /bot/getgroup
说明:获取指定群组的详细信息(不包含群主ID等隐私信息)
端点:POST /bot/answercallback
说明:响应按钮点击事件,必须在收到 callback_query 事件后30秒内响应
{
"callback_id": "cb_user123_abc12345",
"text": "操作成功!",
"show_alert": false,
"url": ""
}
| 字段 | 类型 | 说明 | 必需 |
|---|---|---|---|
callback_id |
string | 回调ID(从Webhook的callback_query事件中获取) | ✅ |
text |
string | 提示文字(可选) | ❌ |
show_alert |
bool | 是否显示弹窗(true=弹窗,false=提示) | ❌ |
url |
string | 打开的URL(可选) | ❌ |
端点:POST /bot/botapisetcommands
说明:设置机器人命令菜单
{
"commands": [
{"command": "start", "description": "开始使用机器人"},
{"command": "help", "description": "查看帮助信息"},
{"command": "price", "description": "查询代币价格"}
]
}
端点:POST /bot/botapigetcommands
说明:获取机器人已设置的命令菜单
| 端点 | 说明 |
|---|---|
POST /bot/mutemember |
禁言群成员 |
POST /bot/unmutemember |
解除禁言 |
import requests
def send_text_message(bot_token, group_id, content):
url = "https://api.bi.ink/bot/sendmessage"
headers = {
"Authorization": f"Bearer {bot_token}",
"Content-Type": "application/json"
}
data = {
"group_id": group_id,
"message_type": "text",
"content": content
}
response = requests.post(url, json=data, headers=headers)
return response.json()
import requests
# 1. 上传文件获取 file_id
def upload_file(bot_token, file_path):
url = "https://api.bi.ink/bot/uploadfile"
headers = {
"Authorization": f"Bearer {bot_token}"
}
with open(file_path, 'rb') as f:
files = {'file': f}
response = requests.post(url, files=files, headers=headers)
result = response.json()
if result.get('code') == 200:
# 机器人上传返回 file_id
return result['data']['file_id']
else:
raise Exception(f"上传失败: {result.get('msg')}")
# 2. 发送图片消息(只需传 file_id,后端自动获取文件信息)
def send_image_message(bot_token, group_id, file_id, caption=""):
url = "https://api.bi.ink/bot/sendmessage"
headers = {
"Authorization": f"Bearer {bot_token}",
"Content-Type": "application/json"
}
data = {
"group_id": group_id,
"message_type": "image",
"file_id": file_id,
"content": caption
}
response = requests.post(url, json=data, headers=headers)
return response.json()
# 完整示例:上传并发送图片
file_id = upload_file(bot_token, "/path/to/image.jpg")
send_image_message(bot_token, "group_123", file_id, "这是一张图片")
def send_message_with_buttons(bot_token, group_id, content):
url = "https://api.bi.ink/bot/sendmessage"
headers = {
"Authorization": f"Bearer {bot_token}",
"Content-Type": "application/json"
}
data = {
"group_id": group_id,
"message_type": "text",
"content": content,
"extra": {
"inline_keyboard": [
[
{"text": "确认", "callback_data": "confirm"},
{"text": "取消", "callback_data": "cancel"}
]
]
}
}
response = requests.post(url, json=data, headers=headers)
return response.json()
import requests
from flask import Flask, request
app = Flask(__name__)
BOT_TOKEN = "your_bot_token"
API_BASE_URL = "https://api.bi.ink"
@app.route('/webhook', methods=['POST'])
def webhook():
event = request.json
if event['event_type'] == 'callback_query':
callback_id = event['callback_id']
callback_data = event['callback_data']
message_id = event['message_id']
sender_id = event['sender_id']
# 处理不同的按钮点击
if callback_data == 'confirm':
# 响应回调
answer_callback(callback_id, '操作已确认!', False)
# 编辑消息,清除按钮
edit_message(message_id, '✅ 操作已确认', {'inline_keyboard': []})
elif callback_data == 'cancel':
answer_callback(callback_id, '操作已取消', False)
elif callback_data.startswith('verify:'):
# 处理验证逻辑
parts = callback_data.split(':')
target_user_id = parts[1]
answer = parts[2]
if sender_id == target_user_id:
# 验证通过
answer_callback(callback_id, '验证通过!', True)
else:
answer_callback(callback_id, '这不是你的验证题目!', True)
return 'OK', 200
def answer_callback(callback_id, text, show_alert):
"""响应按钮回调"""
url = f"{API_BASE_URL}/bot/answercallback"
headers = {
"Authorization": f"Bearer {BOT_TOKEN}",
"Content-Type": "application/json"
}
data = {
"callback_id": callback_id,
"text": text,
"show_alert": show_alert
}
requests.post(url, json=data, headers=headers)
def edit_message(message_id, content, extra):
"""编辑消息"""
url = f"{API_BASE_URL}/bot/editmessage"
headers = {
"Authorization": f"Bearer {BOT_TOKEN}",
"Content-Type": "application/json"
}
data = {
"message_id": message_id,
"content": content,
"extra": extra
}
requests.post(url, json=data, headers=headers)
package main
import (
"bytes"
"encoding/json"
"net/http"
)
func sendMessage(botToken, groupID, content string) error {
url := "https://api.bi.ink/bot/sendmessage"
data := map[string]interface{}{
"group_id": groupID,
"message_type": "text",
"content": content,
}
jsonData, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
req.Header.Set("Authorization", "Bearer "+botToken)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
return nil
}
const express = require('express');
const axios = require('axios');
const app = express();
app.use(express.json());
const BOT_TOKEN = 'your_bot_token';
const API_BASE_URL = 'https://api.bi.ink';
app.post('/webhook', async (req, res) => {
const event = req.body;
if (event.event_type === 'private_message') {
// 处理私聊消息
if (event.content === '/start') {
await sendMessage(event.sender_id, '欢迎使用机器人!');
}
} else if (event.event_type === 'callback_query') {
// 处理按钮回调
const callbackId = event.callback_id;
const callbackData = event.callback_data;
const senderId = event.sender_id;
const messageId = event.message_id;
// 根据 callback_data 处理不同的按钮点击
if (callbackData === 'confirm') {
// 确认操作
await answerCallback(callbackId, '操作已确认!', false);
// 可以编辑原消息,更新按钮状态
await editMessage(messageId, '✅ 操作已确认', { inline_keyboard: [] });
} else if (callbackData === 'cancel') {
// 取消操作
await answerCallback(callbackId, '操作已取消', false);
} else if (callbackData.startsWith('verify:')) {
// 处理验证按钮(示例)
const parts = callbackData.split(':');
const targetUserId = parts[1];
const answer = parts[2];
if (senderId === targetUserId) {
// 验证逻辑...
await answerCallback(callbackId, '验证通过!', true);
} else {
await answerCallback(callbackId, '这不是你的验证题目!', true);
}
}
}
res.status(200).send('OK');
});
async function sendMessage(targetUserId, content) {
await axios.post(`${API_BASE_URL}/bot/sendmessage`, {
target_user_id: targetUserId,
message_type: 'text',
content: content
}, {
headers: {
'Authorization': `Bearer ${BOT_TOKEN}`
}
});
}
async function answerCallback(callbackId, text, showAlert) {
await axios.post(`${API_BASE_URL}/bot/answercallback`, {
callback_id: callbackId,
text: text,
show_alert: showAlert
}, {
headers: {
'Authorization': `Bearer ${BOT_TOKEN}`
}
});
}
app.listen(3000, () => {
console.log('Webhook server running on port 3000');
});