在网上搜索了一圈,发现大部分文章都是使用COW将大模型接入微信的,很少看到如何接入钉钉,因此自己结合实际情况写出这篇文章。
想要将自己本地搭建的大模型接入钉钉,我们需要先明确接入要有哪些过程,这个过程可以分为三个环节:
首先,向钉钉发起对话的“问候”;
其次,将钉钉接收到的消息巧妙地“转交”给大模型;
最后,将大模型的智慧结晶“回馈”给钉钉。
下面,我们将逐一分析这三个步骤。首先,关于向钉钉平台发送消息,关键在于确定消息的接收对象。这就需要我们首先创建一个钉钉机器人,作为消息传递的媒介和接口。
没有本地大模型可以参考这篇文章创建,或者直接接入网上的大模型API。
[保姆级教程]从0开始本地大模型搭建私用知识库(第一部分:安装)_fastgpt ollama-CSDN博客
一、创建钉钉机器人
1、登陆钉钉开放平台
2、进入平台后,我们选择右上角的“我的后台”,进入后即可看到下面的内容。
3、点击上图中的“创建”按钮,即可进入机器人创建界面。
4、点击上图右上角的“创建应用”,在打开的页面中输入你的应用名称,和应用描述,还可以给它上传一个头像。
5、点击保存按钮后,会跳转到一个新界面,在这个界面,我们给创建的应用添加机器人功能。如下图,点击“机器人”下面的添加即可。
6、添加完机器人后,接下来我们需要配置机器人的想信息。这步一看就会,不细说,只说明一点。在最后会要求选择消息接收模式,要选择Stream模式。
因为:使用Stream模式,无需注册公网回调地址。这就省去了很多麻烦。Stream 模式接入,钉钉开放平台将通过 Websocket 连接与应用程序通讯
7、将发布后机器人添加到你的群里。
二、消息通信
这部分包括了3点,1)接收钉钉消息;2)将消息转发给大模型处理;3)将结果返回钉钉
我是通过python代码来实现这部分的(不懂python的可以发给AI让它给你解释),下面我通过代码来讲解各个部分的实现要求。代码可用,如果不想读的直接复制,修改其中几个参数即可。
# 导入Flask框架,用于创建Web应用
from flask import Flask, request, jsonify
# 导入threading模块,用于多线程处理
import threading
# 导入asyncio模块,用于异步编程
import asyncio
# 导入dingtalk_stream模块,用于处理钉钉消息流
import dingtalk_stream
# 从dingtalk_stream模块中导入AckMessage类,用于确认消息处理状态
from dingtalk_stream import AckMessage
# 导入requests模块,用于发送HTTP请求
import requests
# 导入json模块,用于处理JSON数据
import json
# 创建一个Flask应用实例
app = Flask(__name__)
# 钉钉应用的App Key和App Secret,用于身份验证
APP_KEY = '1234dfgthyh56d'
APP_SECRET = 'fgiushrw9ruhgregjfdlspd'
# 钉钉Webhook的URL,用于发送消息
webhook_url = "https://tyuiolbnm,67899ojnbnji0okjbvgyuik"
# 定义一个事件处理器类,继承dingtalk_stream.EventHandler
class MyEventHandler(dingtalk_stream.EventHandler):
# 异步处理事件消息的方法
async def process(self, event: dingtalk_stream.EventMessage):
# 打印事件类型、ID、出生时间和数据
print(event.headers.event_type, event.headers.event_id, event.headers.event_born_time, event.data)
# 创建一个异步任务,将数据发送到fastgpt并返回给钉钉
asyncio.create_task(send_data_to_fastgpt_and_back_to_dingtalk(event.data))
# 返回消息处理状态和响应
return AckMessage.STATUS_OK, 'OK'
# 定义一个回调处理器类,继承dingtalk_stream.CallbackHandler
class MyCallbackHandler(dingtalk_stream.CallbackHandler):
# 异步处理回调消息的方法
async def process(self, message: dingtalk_stream.CallbackMessage):
# 打印消息主题和数据
print(message.headers.topic, message.data)
# 创建一个异步任务,将数据发送到fastgpt并返回给钉钉
asyncio.create_task(send_data_to_fastgpt_and_back_to_dingtalk(message.data))
# 返回消息处理状态和响应
return AckMessage.STATUS_OK, 'OK'
# 定义一个函数,用于启动钉钉客户端
def start_dingtalk_client():
# 创建钉钉凭证对象
credential = dingtalk_stream.Credential(APP_KEY, APP_SECRET)
# 创建钉钉流客户端
client = dingtalk_stream.DingTalkStreamClient(credential)
# 注册所有事件处理器
client.register_all_event_handler(MyEventHandler())
# 注册聊天机器人消息的回调处理器
client.register_callback_handler(dingtalk_stream.ChatbotMessage.TOPIC, MyCallbackHandler())
# 持续运行客户端
client.start_forever()
# 定义一个异步函数,用于将数据发送到fastgpt并返回给钉钉
async def send_data_to_fastgpt_and_back_to_dingtalk(data):
# fastgpt API的URL
url = 'http://127.0.0.1:3000/api/v1/chat/completions'
# 设置请求头
headers = {
'Authorization': 'Bearer fastgpt-e6gfreyuenjskgjorjgoi54ogmrfnvdvd',
'Content-Type': 'application/json'
}
try:
# 构建API请求数据
api_data = {
"model": "gemma2:2b",
"chatId": data.get('senderStaffId', ''),
"messages": [
{
"role": "user",
"content": data.get('text', {}).get('content', '') if isinstance(data.get('text'), dict) else ''
},
]
}
# 发送POST请求到fastgpt API
response = requests.post(url, headers=headers, json=api_data)
# 打印发送者的StaffId
print(data.get('senderStaffId', ''))
# 检查响应状态码
if response.status_code != 200:
print(f"发送数据到fastgpt失败: {response.status_code} - {response.text}")
else:
print("数据成功发送到fastgpt。")
# 解析响应数据
response_data = response.json()
message_content = response_data.get('choices', [{}])[0].get('message', {}).get('content', '')
# 如果有消息内容,则发送到钉钉
if message_content:
await send_dingding(message_content, webhook_url)
else:
print("无法从数据中提取消息内容,无法发送消息回钉钉。")
# 如果在发送数据到fastgpt时发生网络相关的异常,捕获该异常并打印错误信息
except requests.exceptions.RequestException as e:
print(f"在发送数据到fastgpt时发生错误: {e}")
# 定义一个异步函数,用于将消息发送到钉钉
async def send_dingding(message, webhook_url):
# 设置请求头,指明发送的内容类型为JSON
headers = {'Content-Type': 'application/json'}
# 构建要发送的数据,包括消息类型和文本内容
data = {
"msgtype": "text",
"text": {
"content": message
}
}
try:
# 使用requests模块发送POST请求到钉钉的Webhook URL
response = requests.post(webhook_url, headers=headers, data=json.dumps(data))
# 打印钉钉响应的内容
print(response.text)
# 如果发送过程中发生网络相关的异常,捕获该异常并打印错误信息
except requests.exceptions.RequestException as e:
print(f"发送消息到钉钉失败: {e}")
# 创建并启动一个线程,用于运行钉钉Stream客户端
thread = threading.Thread(target=start_dingtalk_client)
thread.start()
# 定义Flask路由,当访问根路径时执行index函数
@app.route('/')
def index():
# 返回一个简单的字符串,表示钉钉Stream客户端正在运行
return 'DingTalk Stream client is running.'
# 当该脚本被直接运行时(而不是作为模块导入),执行以下代码
if __name__ == '__main__':
# 创建一个新的异步事件循环
loop = asyncio.new_event_loop()
# 将新创建的事件循环设置为当前线程的默认事件循环
asyncio.set_event_loop(loop)
# 运行事件循环,直到调用stop()方法
loop.run_forever()
重点参数说明:
APP_KEY = '1234dfgthyh56d'
APP_SECRET = 'fgiushrw9ruhgregjfdlspd'
webhook_url = "https://tyuiolbnm,67899ojnbnji0okjbvgyuik"
上面这3个参数均来自于刚刚创建的钉钉机器人。位置如下图:
APP_KEY 和 APP_SECRET在这里。
webhook_url 在你将机器人添加进群后才可以用,打开群设置,在里面找到你添加的机器人。,点击后即可看到。
url = 'http://127.0.0.1:3000/api/v1/chat/completions'
'Authorization': 'Bearer fastgpt-e6gfreyuenjskgjorjgoi54ogmrfnvdvd'
这两个参数是连接大模型使用的。我是本地部署的fastgpt,如果你选择使用在线大模型,也会有这两个参数,在你申请的地方找找。
注意:如果使用的大模型不是本地部署的fastgpt平台,那么在后面的给大模型传参时格式可能需要调整。
修改完如上5个参数后,启动程序。在群里@你的机器人给它发送消息尝试下吧。