🤖 机器人开发文档

完整的机器人开发指南,包含所有消息类型、API 接口和代码示例

📑 目录

🚀 快速开始

1. 获取 Bot Token

在 APP 中创建机器人后,获取 bot_token,用于 API 认证。

2. 上传文件(如需要)

发送图片、视频、音频等媒体消息前,需要先上传文件获取 file_id

Bash
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 即可。

3. 发送第一条消息

Bash
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 中携带认证信息:

HTTP
Authorization: Bearer YOUR_BOT_TOKEN

💬 消息类型

机器人支持发送以下类型的消息:

📝 文本消息 (text)

发送纯文本消息

JSON
{
  "group_id": "group_123",
  "message_type": "text",
  "content": "这是一条文本消息"
}
字段 类型 说明 必需
message_type string 固定值:"text"
content string 消息文本内容

🖼️ 图片消息 (image)

发送图片,支持 JPG、PNG、GIF 等格式

JSON
{
  "group_id": "group_123",
  "message_type": "image",
  "content": "这是一张图片",
  "file_id": "file_123456"
}

只需传递 file_id(通过上传接口获取)。

字段 类型 说明 必需
message_type string 固定值:"image"
file_id string 文件 ID(通过文件上传接口获取)
content string 图片描述(可选)

🎥 视频消息 (video)

发送视频文件,支持 MP4、MOV 等格式

JSON
{
  "group_id": "group_123",
  "message_type": "video",
  "content": "这是一个视频",
  "file_id": "file_123456"
}
字段 类型 说明 必需
message_type string 固定值:"video"
file_id string 视频文件 ID(通过文件上传接口获取)
content string 视频描述(可选)

🎵 音频消息 (audio)

发送音频文件,支持 MP3、WAV、M4A 等格式

JSON
{
  "group_id": "group_123",
  "message_type": "audio",
  "content": "这是一段音频",
  "file_id": "file_123456"
}
字段 类型 说明 必需
message_type string 固定值:"audio"
file_id string 音频文件 ID(通过文件上传接口获取)
content string 音频描述(可选)

📄 文件消息 (file)

发送任意类型的文件

JSON
{
  "group_id": "group_123",
  "message_type": "file",
  "content": "这是一个文件",
  "file_id": "file_123456"
}
字段 类型 说明 必需
message_type string 固定值:"file"
file_id string 文件 ID(通过文件上传接口获取)
content string 文件描述(可选)

😊 贴纸消息 (sticker)

发送贴纸/表情包

JSON
{
  "group_id": "group_123",
  "message_type": "sticker",
  "file_id": "sticker_123456"
}
💡 提示: 只需传递 file_id,后端会自动获取文件URL。

👤 联系人消息 (contact)

分享联系人名片

JSON
{
  "group_id": "group_123",
  "message_type": "contact",
  "file_id": "user_123456"
}

🎯 交互功能

内联键盘(Inline Keyboard)

在消息中添加按钮,用户点击后触发回调事件

JSON
{
  "group_id": "group_123",
  "message_type": "text",
  "content": "请选择操作:",
  "extra": {
    "inline_keyboard": [
      [
        {"text": "确认", "callback_data": "confirm"},
        {"text": "取消", "callback_data": "cancel"}
      ],
      [
        {"text": "查看详情", "callback_data": "detail"}
      ]
    ]
  }
}

按钮回调完整流程

按钮回调的完整工作流程如下:

  1. 发送带按钮的消息:在发送消息时,通过 extra.inline_keyboard 添加按钮
  2. 用户点击按钮:用户点击消息中的按钮
  3. 接收回调事件:机器人通过 Webhook 收到 callback_query 事件,包含:
    • callback_id:回调ID(格式:cb_userId_uniqueId
    • callback_data:按钮的 callback_data
    • message_id:消息ID
    • sender_id:点击按钮的用户ID
  4. 响应回调:机器人调用 /bot/answercallback 接口响应,必须在30秒内响应

Webhook 回调事件示例

JSON
{
  "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"
}

响应回调示例

Bash
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
  }'

响应参数说明

回复消息

回复指定的消息

JSON
{
  "group_id": "group_123",
  "message_type": "text",
  "content": "这是回复内容",
  "reply_to_id": "msg_123456"
}

引用消息

引用指定的消息

JSON
{
  "group_id": "group_123",
  "message_type": "text",
  "content": "这是引用内容",
  "quote_message_id": "msg_123455"
}

📡 Webhook 事件

当用户与机器人交互时,系统会向你的 Webhook URL 发送 POST 请求

事件类型

事件类型 说明 触发时机
private_message 私聊消息 用户向机器人发送私聊消息
group_message 群组消息 用户在群组中@机器人或发送命令
member_joined 成员加入 新成员加入机器人所在的群组
callback_query 按钮回调 用户点击消息中的按钮

Webhook 请求示例

JSON
{
  "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": ""
}

📚 API 参考

上传文件

端点:POST /bot/uploadfile

说明:上传文件,支持图片、视频、音频、文档等文件。返回 file_id

Bash
curl -X POST "https://api.bi.ink/bot/uploadfile" \
  -H "Authorization: Bearer YOUR_BOT_TOKEN" \
  -F "file=@/path/to/file.jpg"
JSON
{
  "code": 200,
  "msg": "文件上传成功",
  "data": {
    "file_id": "file_123456"
  }
}
参数 类型 说明 必需
file file 上传的文件

发送消息

端点:POST /bot/sendmessage

说明:向指定会话发送消息。发送媒体消息时只需传递 file_id,后端会自动获取文件信息。

编辑消息

端点:POST /bot/editmessage

说明:编辑已发送的消息

JSON
{
  "message_id": "msg_xxx",
  "content": "✅ 您已确认操作",
  "extra": {
    "inline_keyboard": []
  }
}

删除消息

端点:POST /bot/deletemessage

说明:删除消息,支持单条和批量删除。

JSON
{
  "message_id": "msg_xxx"
}

批量删除示例:

JSON
{
  "message_ids": ["msg_123", "msg_456", "msg_789"]
}

群聊需要管理权限或赋予相关操作权限,私聊中参与者可以删除任何消息。

获取机器人信息

端点:POST /bot/getme

说明:获取当前机器人的基本信息

获取群组信息

端点:POST /bot/getgroup

说明:获取指定群组的详细信息(不包含群主ID等隐私信息)

响应按钮回调

端点:POST /bot/answercallback

说明:响应按钮点击事件,必须在收到 callback_query 事件后30秒内响应

JSON
{
  "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

说明:设置机器人命令菜单

JSON
{
  "commands": [
    {"command": "start", "description": "开始使用机器人"},
    {"command": "help", "description": "查看帮助信息"},
    {"command": "price", "description": "查询代币价格"}
  ]
}

获取命令菜单

端点:POST /bot/botapigetcommands

说明:获取机器人已设置的命令菜单

群组管理

端点 说明
POST /bot/mutemember 禁言群成员
POST /bot/unmutemember 解除禁言
💡 隐私保护: 为保护用户隐私,机器人 API 不提供获取群成员列表功能(参考 Telegram Bot API 的隐私保护策略)。

💻 代码示例

Python 示例:发送文本消息

Python
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()

Python 示例:上传文件并发送图片消息

Python
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, "这是一张图片")

Python 示例:发送带按钮的消息

Python
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()

Python 示例:处理按钮回调

Python
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)

Go 示例:发送消息

Go
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
}

JavaScript/Node.js 示例:Webhook 服务器

JavaScript
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');
});