從建立企業內部應用到在釘釘群裡收到第一條 AI 回覆(Stream 模式,免公網 IP,含 4 個報錯修法)
dingtalk-stream SDK 收發訊息 → 接大模型 API → 在釘釘群裡 @ 機器人收到 AI 回覆。全程不需要公網 IP、不需要配回撥 URL,比企業微信那套 AES 回撥簡單一個量級。文末 4 個常見報錯和修法。
open-dev.dingtalk.com(釘釘開發者後臺)→ 應用開發 → 企業內部應用 → 建立應用AppKey 和 AppSecret(AppSecret 只顯示一次,關閉後需重置才能再看)官方 Python SDK(dingtalk-stream)把 WebSocket 長連線、心跳、斷線重連都封裝好了。安裝並儲存下面程式碼為 bot.py:
pip install dingtalk-stream
import logging
import dingtalk_stream
from dingtalk_stream import AckMessage
def setup_logger():
logger = logging.getLogger()
handler = logging.StreamHandler()
handler.setFormatter(
logging.Formatter('%(asctime)s %(name)-8s %(levelname)-8s %(message)s'))
logger.addHandler(handler)
logger.setLevel(logging.INFO)
return logger
class EchoHandler(dingtalk_stream.ChatbotHandler):
async def process(self, callback: dingtalk_stream.CallbackMessage):
message = dingtalk_stream.ChatbotMessage.from_dict(callback.data)
content = message.text.content.strip()
self.logger.info('收到消息: %s' % content)
self.reply_text('收到:' + content, message)
return AckMessage.STATUS_OK, 'OK'
def main():
logger = setup_logger()
credential = dingtalk_stream.Credential('你的AppKey', '你的AppSecret')
client = dingtalk_stream.DingTalkStreamClient(credential)
client.register_callback_handler(
dingtalk_stream.chatbot.ChatbotMessage.TOPIC, EchoHandler(logger))
client.start_forever()
if __name__ == '__main__':
main()
執行 python bot.py,日誌出現 连接成功 後,到釘釘群裡 @机器人 發一句「你好」,應該收到「收到:你好」。
把 EchoHandler 換成呼叫大模型 API。以 DeepSeek 為例(官網 platform.deepseek.com 充值後建立 API Key,價格在官網定價頁實時可查,本文釋出時 deepseek-chat 輸出約 2 元/百萬 tokens):
import requests
API_KEY = '你的DeepSeek API Key'
def ask_ai(text):
resp = requests.post(
'https://api.deepseek.com/chat/completions',
headers={'Authorization': 'Bearer ' + API_KEY},
json={
'model': 'deepseek-chat',
'messages': [{'role': 'user', 'content': text}],
},
timeout=30)
return resp.json()['choices'][0]['message']['content']
class AIHandler(dingtalk_stream.ChatbotHandler):
async def process(self, callback: dingtalk_stream.CallbackMessage):
message = dingtalk_stream.ChatbotMessage.from_dict(callback.data)
content = message.text.content.strip()
self.logger.info('收到: %s' % content)
answer = ask_ai(content)
self.reply_text(answer, message)
return AckMessage.STATUS_OK, 'OK'
把第 2 步程式碼裡的 EchoHandler 換成 AIHandler,重啟指令碼,再 @ 機器人提問,收到的就是模型回答。
@机器人 提問,收到回覆即說明全流程可用messages 陣列再發給模型(注意控制長度,超長就只保留最近幾輪)content.strip() 後建議再 replace('@机器人','') 去掉字首,避免把機器人名字餵給模型開發機跑通後,把指令碼放到伺服器,用 systemd 託管(斷線自動拉起,SDK 自身也會自動重連):
sudo tee /etc/systemd/system/dingtalk-bot.service <<'EOF'
[Unit]
Description=DingTalk AI Bot
After=network-online.target
[Service]
WorkingDirectory=/opt/dingbot
ExecStart=/usr/bin/python3 /opt/dingbot/bot.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now dingtalk-bot
sudo journalctl -u dingtalk-bot -f
注意:AppKey/AppSecret 建議從環境變數或金鑰檔案讀,別硬編碼進 git 倉庫。
下一步可以做的:把機器人接進 知識庫檢索(先查內部文件再回答),或者接到 企業審批/工單系統(收到訊息後調內部 API 幹活)。這類「IM + AI + 內部系統」的串聯,正是 Mule Agent 平臺擅長的場景——多個 IM 統一接一個 AI 大腦,一個後臺管理。
AppKey/AppSecret 填錯,或複製時帶了空格/換行。
應用沒釋出,或機器人沒加進當前群。
機器人「訊息接收模式」選成了 HTTP 回撥(需要公網 URL),或者根本沒配接收訊息。
ChatbotMessage.TOPIC(拼寫帶 Chatbot 的 o)。reply_text 必須在 process 回撥裡呼叫——釘釘的回覆上下文只在該回撥內有效;另外大模型 API 超時也會導致回不上。
ask_ai 的 timeout 設 30 秒以上;如果模型要算很久,先回一句「正在處理…」,再非同步算完補發(Stream 模式支援主動發訊息)。