币聊机器人 API 说明

机器人 API

在 App 里创建机器人、拿到 Token 后,即可用普通 HTTP 请求发消息、改消息、接 Webhook。下面按调用顺序写了常用接口和字段,示例里的域名是 https://api.bi.ink,可按你实际环境替换。

上手

1. Token

在 App 内创建机器人后,记下 bot_token,每个请求都要带在 Header 里(见下一节)。

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"

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,二选一。

请求头

所有机器人接口都要求在 Header 里携带:

http
Authorization: Bearer YOUR_BOT_TOKEN

消息类型

message_type 取值与 JSON 骨架如下(group_id / target_user_id 按会话类型选一个)。

文本 text

纯文字。

json
{
  "group_id": "group_123",
  "message_type": "text",
  "content": "这是一条文本消息"
}
字段 类型 说明 必填
message_type string 固定 text
content string 正文

图片 image

JPG / PNG / GIF 等,需先有 file_id

json
{
  "group_id": "group_123",
  "message_type": "image",
  "content": "可选说明",
  "file_id": "file_123456"
}
字段 类型 说明 必填
message_type string 固定 image
file_id string 上传接口返回
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 上传接口返回
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 上传接口返回
content string 说明,可空

文件 file

任意附件类型。

json
{
  "group_id": "group_123",
  "message_type": "file",
  "content": "可选说明",
  "file_id": "file_123456"
}
字段 类型 说明 必填
message_type string 固定 file
file_id string 上传接口返回
content string 说明,可空

贴纸 sticker

file_id 即可,服务端会解析资源。

json
{
  "group_id": "group_123",
  "message_type": "sticker",
  "file_id": "sticker_123456"
}

联系人 contact

分享名片,file_id 此处为用户相关标识(与业务约定一致)。

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

按钮与回复

内联键盘

发消息时在 extra.inline_keyboard 里放二维数组,每项为 text + callback_data

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. 用户点了按钮,你的 Webhook 会收到 event_typecallback_query 的 JSON。
  2. 里面会有 callback_id(形如 cb_userId_xxx)、callback_data、原消息 message_id、点击人 sender_id
  3. 在约 30 秒内请求 POST /bot/answercallback,把 callback_id 回给服务端;需要的话再调 editmessage 改文案或清掉键盘。

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

text:提示文案;show_alerttrue 时用弹窗,否则多为轻提示;url 可选,给按钮跳转用。

回复某条消息

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

在机器人后台配置 URL 后,用户发消息、点按钮、有人进群等事件会以 POST JSON 推到你的地址。下面列常见 event_type

event_type 含义 大致时机
private_message 私聊 用户私聊机器人
group_message 群聊 群内 @ 机器人或命令等(以产品规则为准)
member_joined 新成员入群 机器人所在群有新成员
callback_query 按钮 用户点击内联按钮

私聊示例

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

接口列表

上传文件

POST /bot/uploadfile,multipart 字段名 file。成功返回里带 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"
  }
}

发消息

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,不含群主等敏感字段。

应答按钮

POST /bot/answercallback,收到 callback_query 后尽快调用。

json
{
  "callback_id": "cb_user123_abc12345",
  "text": "操作成功",
  "show_alert": false,
  "url": ""
}
字段 类型 说明 必填
callback_id string Webhook 里原样带回
text string 提示文案
show_alert bool 是否弹窗
url string 打开链接

命令菜单

设置:POST /bot/botapisetcommands

json
{
  "commands": [
    {"command": "start", "description": "开始使用"},
    {"command": "help", "description": "帮助"},
    {"command": "price", "description": "查价"}
  ]
}

读取:POST /bot/botapigetcommands

群成员禁言

路径 作用
POST /bot/mutemember 禁言
POST /bot/unmutemember 解除禁言

当前不提供「拉取完整群成员列表」类接口,避免与隐私策略冲突;需要定向操作时请用业务侧已知的用户 ID。

示例代码

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

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:
            return result['data']['file_id']
        raise RuntimeError(result.get('msg', 'upload failed'))

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"}
                ]
            ]
        }
    }
    return requests.post(url, json=data, headers=headers).json()

Python:Flask 收 Webhook

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.get('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)
    return 'OK', 200

def answer_callback(callback_id, text, show_alert):
    requests.post(
        f"{API_BASE_URL}/bot/answercallback",
        json={"callback_id": callback_id, "text": text, "show_alert": show_alert},
        headers={"Authorization": f"Bearer {BOT_TOKEN}", "Content-Type": "application/json"},
    )

def edit_message(message_id, content, extra):
    requests.post(
        f"{API_BASE_URL}/bot/editmessage",
        json={"message_id": message_id, "content": content, "extra": extra},
        headers={"Authorization": f"Bearer {BOT_TOKEN}", "Content-Type": "application/json"},
    )

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
}

Node:Express 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' && event.content === '/start') {
        await axios.post(`${API_BASE_URL}/bot/sendmessage`, {
            target_user_id: event.sender_id,
            message_type: 'text',
            content: '欢迎使用'
        }, { headers: { Authorization: `Bearer ${BOT_TOKEN}` } });
    } else if (event.event_type === 'callback_query') {
        await axios.post(`${API_BASE_URL}/bot/answercallback`, {
            callback_id: event.callback_id,
            text: '收到',
            show_alert: false
        }, { headers: { Authorization: `Bearer ${BOT_TOKEN}` } });
    }
    res.status(200).send('OK');
});

app.listen(3000);