跳到主要内容

DeBox 机器人 Go SDK Webhook 使用文档

源码仓库:

本文只讲 Webhook 模式。

1. Webhook 与 Long Polling(严格互斥)

DeBox 机器人收消息有两种方式:

  1. Webhook:DeBox 主动 POST 回调到你的服务。
  2. Long Polling:你的程序调用 getUpdates 主动拉取。

严格互斥规则:

  • 只要在开放平台配置了 Webhook URL,消息将优先且仅投递到 Webhook。
  • 此时 GetUpdates/GetUpdatesChan 作为收消息主链路会失效(拿不到或几乎拿不到消息)。

结论:

  • 选择 Webhook,就不要再用 Long Polling 收消息。
  • 若要切回 Long Polling,必须先清空开放平台 Webhook 配置。

2. 什么时候用 Webhook

建议在以下场景使用:

  • 服务部署在公网 HTTP/HTTPS
  • 追求低延迟、高吞吐
  • 希望采用事件推送模型

3. 开放平台配置

在 DeBox 机器人控制台配置 Webhook URL,例如:

  • https://your-domain.com/bot/webhook

同时请注意:

  • App Domain 需正确配置可信域名
  • Webhook URL 必须是可公网访问的稳定地址
  • 修改 Webhook URL 后,Webhook Key 会更新

4. SDK 接入示例(按《DeBox 机器人 开发总览》推荐方式)

这一节采用与《DeBox 机器人 开发总览》一致的方式:

  • 服务端接收 DeBox 的 Webhook 回调
  • 校验请求头 X-API-KEY(Webhook Key)
  • 解析回调消息
  • 使用 Go SDK 回发消息

4.1 回调请求结构

DeBox 会向你的 Webhook URL 发送 POST application/json,常见字段如下:

{
"from_user_id": "u_xxx",
"to_user_id": "u_bot",
"language": "zh",
"group_id": "cc0onr82",
"mention_users": "u_bot",
"message": "hello",
"message_raw": "@bot hello"
}

4.2 完整示例(Gin + Go SDK)

package main

import (
"net/http"
"os"

"github.com/gin-gonic/gin"
boxbotapi "github.com/debox-pro/debox-chat-go-sdk/boxbotapi"
)

type WebhookPayload struct {
FromUserID string `json:"from_user_id"`
ToUserID string `json:"to_user_id"`
Language string `json:"language"`
GroupID string `json:"group_id"`
MentionUsers string `json:"mention_users"`
Message string `json:"message"`
MessageRaw string `json:"message_raw"`
}

func main() {
webhookKey := os.Getenv("DEBOX_WEBHOOK_KEY")
apiKey := os.Getenv("DEBOX_BOT_API_KEY")
apiSecret := os.Getenv("DEBOX_BOT_API_SECRET")

if webhookKey == "" || apiKey == "" {
panic("缺少必要环境变量:DEBOX_WEBHOOK_KEY / DEBOX_BOT_API_KEY")
}

bot, err := boxbotapi.NewBotAPI(apiKey, apiSecret)
if err != nil {
panic(err)
}

r := gin.Default()
r.POST("/bot/webhook", func(c *gin.Context) {
// 1) 严格校验回调来源
if c.GetHeader("X-API-KEY") != webhookKey {
c.JSON(http.StatusUnauthorized, gin.H{"error": "invalid webhook key"})
return
}

// 2) 解析 webhook body
var payload WebhookPayload
if err := c.ShouldBindJSON(&payload); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

// 3) 根据 group_id 判断会话类型,并回消息
chatType := "private"
chatID := payload.FromUserID
if payload.GroupID != "" {
chatType = "group"
chatID = payload.GroupID
}

reply := boxbotapi.NewMessage(chatID, chatType, "已收到: "+payload.Message)
reply.ParseMode = boxbotapi.ModeRichText
if _, err := bot.Send(reply); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

c.JSON(http.StatusOK, gin.H{"ok": true})
})

_ = r.Run(":8080")
}

5. 常见问题

  • 配了 Webhook 但收不到消息:
    • 先检查 Webhook URL 可达性、服务日志、X-API-KEY 校验逻辑。
  • 同时开 Webhook 和 Long Polling:
    • 必须二选一,Webhook 开启时 Polling 收消息链路视为无效。
  • 本地开发无公网域名:
    • 可用隧道工具临时暴露本地端口进行联调。

6. 相关文档