打造智能钉钉机器人:借助智谱GLM-4-Flash实现高效智能回复(文末附源码)

news2025/3/12 11:24:50

文章目录

  • 前言
  • 一、准备工作
    • (一)钉钉机器人
    • (二)智谱 GLM-4-Flash
    • (三)内网穿透工具 cpolar
    • (四)需要准备的工具和环境
  • 二、钉钉机器人的创建与配置
      • 步骤1:创建钉钉机器人
      • 步骤2:将机器人加入群聊
      • 步骤3:配置服务器相关信息
  • 三、开发环境准备
    • (一) 本地开发环境搭建
      • 步骤1:创建 Python环境
      • 步骤2:安装必要的依赖库
    • (二) 获取 API 密钥
  • 四、消息接收与处理
    • (一)接收钉钉消息
    • (二)解析消息内容
    • (三)验证消息合法性
  • 五、调用大模型生成答案
    • (一)处理用户指令
    • (二)发送回复消息
  • 六、运行与测试
    • (一)本地运行
        • 艾特机器人并发送“地震播报”
        • 艾特机器人并发送“北京天气”
        • 艾特机器人并询问问题
  • 总结
  • 附录


前言

        在当今数字化办公的时代,钉钉作为一款广泛使用的办公协作工具,其机器人功能为企业和团队带来了诸多便利。通过创建自定义钉钉机器人,我们可以实现自动化消息推送、智能问答等功能,极大地提高工作效率。而智谱 GLM-4-Flash 作为一款强大的语言模型,能够生成高质量的文本内容,为我们的机器人赋予更智能的回复能力。本文将详细介绍如何从零开始打造一个智能钉钉机器人,实现调用智谱 API 来生成智能回复的全过程。


一、准备工作

        在开始打造智能钉钉机器人之前,我们需要对一些基础知识有所了解,并准备好必要的工具和环境。

(一)钉钉机器人

        钉钉机器人是一种可以自动接收和处理钉钉群消息的工具,它通过 webhook 接口与钉钉进行通信。机器人可以被添加到钉钉群聊中,当群成员艾特机器人时,机器人会接收到消息并根据预设的逻辑进行处理和回复。钉钉机器人广泛应用于自动化办公、信息推送、智能问答等场景,能够帮助企业提高工作效率和协作体验。

(二)智谱 GLM-4-Flash

        GLM-4-Flash,智谱AI发布的矩阵模型。它能够生成高质量的文本内容,适用于多种自然语言处理任务,如文本生成、问答系统、文本摘要等。通过调用智谱 GLM-4-Flash 的 API 接口,我们可以将用户的输入传递给模型,并获取模型生成的回答内容,从而实现智能回复功能。

(三)内网穿透工具 cpolar

        内网穿透是一种技术,它允许外部网络访问内网中的服务。在本地开发环境中,我们通常处于内网,无法直接被钉钉服务器访问。因此,我们需要使用内网穿透工具 cpolar 来创建一个隧道,将本地端口映射到公网,使得钉钉服务器可以通过公网地址访问到本地运行的服务。

(四)需要准备的工具和环境

        在开始开发之前,我们需要准备以下工具和环境:

  • 钉钉开发者账号:注册钉钉开发者账号,用于创建机器人和获取 webhook token。
  • 智谱 GLM-4-Flash 账号:注册智谱平台账号,创建项目并获取 API 密钥。
  • 内网穿透工具 cpolar:下载并安装 cpolar 客户端,用于本地开发环境的内网穿透。
  • 天气 API 账号(可选):如果需要实现天气查询功能,可以注册天气 API 服务,获取用户 ID 和密钥。
  • Python 开发环境:安装 Python 环境(推荐 Python 3.8+),并安装必要的 Python 库。

二、钉钉机器人的创建与配置

注意:需要在有开发者权限的组织才可以进行下面步骤,若发现自己没有开发者权限请联系管理员或自行创建组织测试,本博客选择后者
在这里插入图片描述


步骤1:创建钉钉机器人

  1. 登录钉钉开发者后台:https://developers.dingtalk.com/。
  2. 在开发者后台的导航栏中找到“机器人”选项,点击进入机器人管理页面。
  3. 点击“创建应用”按钮,选择“自定义机器人”。
  4. 填写机器人名称(如“智能助手”)、描述(如“基于智谱 GLM-4-Flash 的智能回复机器人”)等基本信息。

在这里插入图片描述


步骤2:将机器人加入群聊

  1. 打开钉钉应用,进入你希望添加机器人的群聊。
  2. 点击群设置,找到“机器人”选项。
  3. 点击“添加机器人”,选择刚才创建的机器人。
  4. 确认添加后,机器人将自动加入群聊。
    在这里插入图片描述

完成创建后,会生成一个 webhook access_token,这是后续开发中与钉钉进行通信的关键凭证,务必妥善保存。
在这里插入图片描述


步骤3:配置服务器相关信息

  1. 访问 cpolar 官方网站(https://cpolar.com/),根据自己的操作系统下载并安装 cpolar 客户端。
  2. 打开 cpolar 客户端,登录账号。创建一个隧道,将本地端口(如 8080)映射到公网。
  3. 记录下 cpolar 提供的公网地址(如 http://your-public-address:8080)。
    在这里插入图片描述

  1. 配置钉钉服务器出口 IP:
  2. 在钉钉开发者后台的机器人开发管理设置页面,找到“消息接收地址”配置项。
  3. 将 cpolar 提供的公网 IP 地址填写到配置框中。
  4. 提示在这里有公网IP或者云服务器的也可以直接填入公网IP地址,这里做本地测试所以使用内网穿透展示
    在这里插入图片描述

三、开发环境准备

在开始开发智能钉钉机器人之前,我们需要确保开发环境已经搭建好,并安装了必要的依赖库。以下是详细的环境创建和依赖安装步骤:

(一) 本地开发环境搭建

步骤1:创建 Python环境

本博客为隔离开发环境,使用Anaconda 来管理 Python 环境,也推荐大家这样做。
Anaconda安装教程:https://blog.csdn.net/pdsu_Zhe/article/details/129432873

  1. 创建新的 Anaconda 环境
conda create -n dingtalk_bot python=3.10
  1. 激活环境:
conda activate dingtalk_bot

步骤2:安装必要的依赖库

在激活的环境中,使用 pip 安装以下依赖库:

  • requests:用于发送 HTTP 请求。
  • hmac、hashlib、base64:用于签名验证。
  • socket:用于创建服务器端口,接收钉钉发送的消息。
  • zhipuai:智谱 GLM-4-Flash 的 Python SDK,用于调用大模型。
pip install requests hmac hashlib base64 socket zhipuai

(二) 获取 API 密钥

1、智谱 GLM-4-Flash API 密钥

  • 访问智谱AI开放平台(https://bigmodel.cn/),注册账号并登录。
  • 在平台中创建一个项目,获取 API 密钥。
  • 将 API 密钥保存到本地,后续代码中会用到。

在这里插入图片描述

2、其他功能API密钥
由于博主在开发地震相关的,所以接入了中国地震台网的全球最新地震信息API,大家有需要的API可以自行搜索方法,这里不在讲述。


四、消息接收与处理

(一)接收钉钉消息

使用 Python 的 socket 模块创建一个服务器端口,监听钉钉发送的消息。

def handle_client(client_socket):
    request_data = client_socket.recv(20000)
    print(f"接收到的消息:{request_data}")
    client_socket.close()

if __name__ == "__main__":
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(("", 8080))
    server_socket.listen(120)
    print("服务器启动,等待连接...")
    while True:
        client_socket, client_address = server_socket.accept()
        print(f"[{client_address}] 用户连接上了")
        handle_client(client_socket)

(二)解析消息内容

解析钉钉发送的消息,提取用户 ID、签名、时间戳和消息内容。

def getPost(request_data):
    request_data = str(request_data, encoding="utf8").split('\r\n')
    items = []
    for item in request_data[1:-2]:
        items.append(item.split(':'))
    post_useful = dict(items)
    post_mes = json.loads(request_data[-1])
    post_sign = post_useful.get('Sign').strip()
    post_timestamp = post_useful.get('Timestamp').strip()
    post_userid = post_mes.get('senderId').strip()
    post_mes = post_mes.get('text').get('content').strip()
    return post_userid, post_sign, post_timestamp, post_mes

(三)验证消息合法性


def initKey(post_userid, post_sign, post_timestamp, post_mes):
    app_secret = '你的app_secret'  # 替换为你的 app_secret
    string_to_sign = f'{post_timestamp}\n{app_secret}'
    hmac_code = hmac.new(app_secret.encode('utf-8'), string_to_sign.encode('utf-8'), digestmod=hashlib.sha256).digest()
    sign = base64.b64encode(hmac_code).decode('utf-8')
    if post_sign == sign:
        print("消息验证通过")
        return True
    else:
        print("消息验证失败")
        return False

五、调用大模型生成答案

(一)处理用户指令

根据用户发送的消息内容,调用相应的处理逻辑。

from zhipuai import ZhipuAI

client = ZhipuAI(api_key="你的GLM_API_KEY")  # 替换为你的智谱 API 密钥

def selectMes(post_userid, post_mes):
    if post_mes == "地震播报":
        earthquake_data = "地震等级: 5.0, 地震时间: 2025-03-09 10:00, 位置: 四川省"  # 替换为实际的地震数据获取逻辑
        response = client.chat.completions.create(
            model="glm-4-flash",
            messages=[
                {"role": "system", "content": "生成地震播报文本"},
                {"role": "user", "content": earthquake_data}
            ]
        )
        answer = response.choices[0].message.content
    elif "天气" in post_mes:
        province, place = "四川", "成都"  # 替换为实际的省份和地点提取逻辑
        weather_data = f"{province} {place} 的天气数据"  # 替换为实际的天气数据获取逻辑
        response = client.chat.completions.create(
            model="glm-4-flash",
            messages=[
                {"role": "system", "content": "生成天气预报文本"},
                {"role": "user", "content": weather_data}
            ]
        )
        answer = response.choices[0].message.content
    else:
        response = client.chat.completions.create(
            model="glm-4-flash",
            messages=[
                {"role": "system", "content": "你是一个智能助手,能够回答各种问题。"},
                {"role": "user", "content": post_mes}
            ]
        )
        answer = response.choices[0].message.content
    return sendText(post_userid, answer)

(二)发送回复消息

import requests
import json

def sendText(post_userid, send_mes):
    webhook = "https://oapi.dingtalk.com/robot/send?access_token=你的token"  # 替换为你的钉钉 webhook token
    header = {"Content-Type": "application/json", "Charset": "UTF-8"}
    message_json = json.dumps({
        "msgtype": "text",
        "text": {
            "content": send_mes
        },
        "at": {
            "atDingtalkIds": [post_userid],
            "isAtAll": False
        }
    })
    response = requests.post(url=webhook, data=message_json, headers=header)
    if response.status_code == 200:
        print("消息发送成功")
    else:
        print("消息发送失败")

六、运行与测试

(一)本地运行

启动本地服务器,确保机器人能够正常接收和处理消息。运行以下代码:

if __name__ == "__main__":
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(("", 8080))
    server_socket.listen(120)
    print("服务器启动,等待连接...")
    while True:
        client_socket, client_address = server_socket.accept()
        print(f"[{client_address}] 用户连接上了")
        handle_client(client_socket)

该代码启动一个监听 8080 端口的服务器,等待钉钉发送的消息。

测试机器人功能:
在钉钉群聊中艾特机器人,测试不同指令的响应情况。例如:

艾特机器人并发送“地震播报”

在这里插入图片描述

艾特机器人并发送“北京天气”

在这里插入图片描述

艾特机器人并询问问题

在这里插入图片描述


总结

通过本文的介绍,我们从零开始打造了一个智能钉钉机器人,实现了调用智谱 GLM-4-Flash API 来生成智能回复的全过程。这个机器人可以根据用户的指令,自动获取地震数据、天气信息,并生成相应的播报内容,极大地提高了办公效率和协作体验。


附录

这里只提供大模型智能回复代码,若需其他功能的相关逻辑代码,可以联系我交流学习。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@author: Richard Zhang
@time: 2025/3/7 19:55 
@file: DingTalk.py
@describe: TODO
"""
# -*- coding: GBK -*-
import requests
import json
import time
import hmac
import hashlib
import base64
import socket
from multiprocessing import Process
from zhipuai import ZhipuAI

# 配置
GLM_API_KEY = "your_api_key"  # 替换为你的智谱GLM-4-Flash API密钥


# 初始化智谱GLM-4-Flash客户端
client = ZhipuAI(api_key=GLM_API_KEY)
model_name = "glm-4-flash"  # 模型名称

def handle_client(client_socket):
    # 获取socket
    request_data = client_socket.recv(20000)
    post_userid, post_sign, post_timestamp, post_mes = getPost(request_data)
    # 回应socket
    initKey(post_userid, post_sign, post_timestamp, post_mes)
    # 关闭socket
    client_socket.close()


def getPost(request_data):
    request_data = str(request_data, encoding="utf8").split('\r\n')
    items = []
    for item in request_data[1:-2]:
        items.append(item.split(':'))
    post_useful = dict(items)
    post_mes = json.loads(request_data[-1])
    post_sign = post_useful.get('Sign').strip()
    post_timestamp = post_useful.get('Timestamp').strip()
    post_userid = post_mes.get('senderId').strip()
    post_mes = post_mes.get('text').get('content').strip()
    return post_userid, post_sign, post_timestamp, post_mes


def initKey(post_userid, post_sign, post_timestamp, post_mes):
    whtoken = "your_webhook_token" # 替换为你的webhook_token
    timestamp = str(round(time.time() * 1000))
    app_secret = 'your_app_secret' # 替换为你的app_secret
    app_secret_enc = app_secret.encode('utf-8')
    string_to_sign = '{}\n{}'.format(post_timestamp, app_secret)
    string_to_sign_enc = string_to_sign.encode('utf-8')
    hmac_code = hmac.new(app_secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
    sign = base64.b64encode(hmac_code).decode('utf-8')

    if (abs(int(post_timestamp) - int(timestamp)) < 3600000 and post_sign == sign):
        webhook = "https://oapi.dingtalk.com/robot/send?access_token=" + whtoken + "&timestamp=" + timestamp + "&sign=" + sign
        header = {"Content-Type": "application/json", "Charset": "UTF-8"}
        message_json = json.dumps(selectMes(post_userid, post_mes))
        info = requests.post(url=webhook, data=message_json, headers=header)
        print(info)
    else:
        print("Warning:Not DingDing's post")


def selectMes(post_userid, post_mes):

    # 将用户输入传递给大模型生成回答
    response = client.chat.completions.create(
        model=model_name,
        messages=[
            {"role": "system", "content": "你是一个智能助手,能够回答各种问题。"},
            {"role": "user", "content": post_mes}
            ]
        )
    answer = response.choices[0].message.content

    # 返回文本消息
    return sendText(post_userid, answer)


def sendText(post_userid, send_mes):
    message = {
        "msgtype": "text",
        "text": {
            "content": send_mes
        },
        "at": {
            "atDingtalkIds": [post_userid],
            "isAtAll": False
        }
    }
    return message


if __name__ == "__main__":
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(("", 8080))
    server_socket.listen(120)
    while True:
        client_socket, client_address = server_socket.accept()
        print("[%s, %s]用户连接上了" % client_address)
        handle_client_process = Process(target=handle_client, args=(client_socket,))
        handle_client_process.start()
        client_socket.close()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2313721.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Mermaid语法绘制的C语言程序从Linux移植到Windows的流程图

以下是使用Mermaid语法绘制的C语言程序从Linux移植到Windows的流程图&#xff1a; graph TDA[开始移植] --> B[代码兼容性检查]B --> C[检查系统调用差异\nfork/exec -> CreateProcess]B --> D[检查文件路径格式\n/ vs \\]B --> E[检查依赖库兼容性\nPOSIX vs …

入门到入土,Java学习 day16(算法1)

利用循环遍历来判断是否相等 二分查找/折半查找 前提条件&#xff1a;数组中的数据有序 每次排除一般的查找范围 用min,max,mid来处理&#xff0c;最大加最小除2&#xff0c;比较&#xff0c;然后得到在中间左边还是右边然后更新最大最小 public class Two {// 二分查找方法…

Vulnhub 靶机 VulnOSv2 write up opendocman cms 32075 sql注入 账号密码 ssh连接 37292.c 脏牛提权

Vulnhub 靶机 VulnOSv2 write up opendocman cms 32075 sql注入 账号密码 ssh连接 37292.c 脏牛提权 一、信息收集 1、首先拿到靶场先扫一下ip arp-scan -l 3、 2、指纹扫描 nmap -sS -sV 192.168.66.178nmap -p- -sV -A 192.168.66.253 PORT STATE SERVICE VERSION 22…

Unity辅助工具_头部与svn

Unity调用者按钮增加PlaySideButton using QQu; using UnityEditor; using UnityEngine; [InitializeOnLoad] public class PlaySideButton {static PlaySideButton(){UnityEditorToolbar.RightToolbarGUI.Add(OnRightToolbarGUI);UnityEditorToolbar.LeftToolbarGUI.Add(OnLe…

DeepLabv3+改进8:在主干网络中添加SIM注意力机制|助力涨点

🔥【DeepLabv3+改进专栏!探索语义分割新高度】 🌟 你是否在为图像分割的精度与效率发愁? 📢 本专栏重磅推出: ✅ 独家改进策略:融合注意力机制、轻量化设计与多尺度优化 ✅ 即插即用模块:ASPP+升级、解码器 PS:订阅专栏提供完整代码 论文简介 在本文中,我们提出了…

电路原理(电容 集成电路NE555)

电容 1.特性&#xff1a;充放电&#xff0c;隔直流&#xff0c;通交流 2.电容是通过聚集正负电荷来存储电能的 3.电容充放电过程可等效为导通回路 4.多电容并联可以把容量叠加&#xff0c;但是多电容串联就不会&#xff0c;只会叠加电容的耐压值。 6.电容充放电时相当于通路&a…

函数式编程的核心

函数式编程 函数式编程&#xff08;funcitonal programming&#xff09;其实是个很古老的概念。 高阶函数和内存分析 函数式一阶公民 函数式编程最鲜明的特点就是&#xff1a;函数式一等公民&#xff0c;指的是函数与其他数据类型一样&#xff0c;处于平等地位&#xff0c;可…

【易康eCognition实验教程】006:在影像上添加文本

在某些情况下&#xff0c;希望能在影像上面显示文本文字&#xff0c;例如&#xff0c;一个地图的名称或者是多时相影像分析的年或月的显示。此外&#xff0c;文本如果作为一个规则集导出的部分则可以被纳入数字影像中。如下图所示&#xff1a; 若要添加文本&#xff0c;在影像视…

C++【类和对象】(超详细!!!)

C【类和对象】 1.运算符重载2.赋值运算符重载3.日期类的实现 1.运算符重载 (1).C规定类类型运算符使用时&#xff0c;必须转换成调用运算符重载。 (2).运算符重载是具有特殊名字的函数&#xff0c;名字等于operator加需要使用的运算符&#xff0c;具有返回类型和参数列表及函数…

如何简单预估大模型运行所需的显存

模型消耗的显存主要来源于模型参数&#xff0c;前向/反向&#xff0c;梯度以及优化器…… 1、为什么显存很重要 显存就是显卡的“仓库”和“高速公路”。 容量越大&#xff0c;能存储的图形数据就越多&#xff0c;就能支持更高分辨率、更高纹理质量的游戏或图形程序。 速度越…

python基础知识补充

一.区分列表、元组、集合、字典&#xff1a; 二.输出&#xff1a; <1>格式化输出字符串&#xff1a; 格式符号转换%s字符串%d有符号的十进制整数%f浮点数%c字符%u无符号十进制整数%o八进制整数%x十六进制整数&#xff08;小写ox&#xff09;%X十六进制整数(大写OX)%e科…

STM32-I2C通信外设

目录 一&#xff1a;I2C外设简介 二&#xff1a;I2C外设数据收发 三&#xff1a;I2C的复用端口 四&#xff1a;主机发送和接收 五&#xff1a;硬件I2C读写MPU6050 相关函数&#xff1a; 1.I2C_ GenerateSTART 2.I2C_ GenerateSTOP 3.I2C_ AcknowledgeConfig 4.I2C…

【脚本】Linux一键扩大虚拟内存的大小

Linux增加虚拟内存其实很简单 就那几个命令&#xff0c;free、mkswap、swapon 但是方便起见我写成了脚本 使用方法 进入你的目录&#xff0c; nano ./install_swap.sh 下面的脚本全文复制&#xff0c;粘贴进去之后&#xff0c;按ctrlx后按y保存 然后运行以下命令 sudo bash …

信号隔离器 0-20mA/0-10V模拟信号隔离模块变送器 一进二出高精度

信号隔离器 0-20mA/0-10V模拟信号隔离模块变送器 一进二出高精度https://item.taobao.com/item.htm?ftt&id766022047828 型号 一进二出 0-20mA 转0-20mA/0-10V MS-C12 一进二出 0-10V 转 0-20mA/0-10V MS-V12 信号隔离器 单组输出 MS-C1/V1 双组输出 MS-C12/V12 用于…

Nat. Methods | scPerturb——单细胞扰动数据的标准化资源与统计分析方法

《Nature Methods》提出scPerturb资源平台&#xff0c;整合44个单细胞扰动数据集&#xff08;涵盖转录组、表观组、蛋白组读值&#xff09;&#xff0c;并通过能量统计量&#xff08;E-statistics&#xff09;量化扰动效应&#xff0c;旨在解决单细胞扰动数据的互操作性差、缺乏…

【易康eCognition实验教程】005:影像波段组合显示与单波段显示

文章目录 一、加载多波段影像二、单波段显示三、彩色显示一、加载多波段影像 二、单波段显示 如果导入的影像数据具有三个或者更多的波段,影像场景将自动以RGB(红绿蓝)模式默认显示,如上图所示。在视图设置(View Settings)窗口中使用单波段灰度显示(Single LayuerGrays…

使用Process Explorer、Dependency Walker和PE信息查看工具快速排查dll动态库因库与库版本不一致导致的加载失败问题

目录 1、问题说明 2、使用Process Explorer查看目标dll动态库有没有动态加载起来 3、使用Dependency Walker查看xxpadll.dll库的库依赖关系&#xff0c;找到xxpadll.dll加载失败的原因 4、使用PE信息查看工具查看目标dll库的时间戳 5、关于xxsipstack2.dll中调用xxdatanet…

Git的命令学习——适用小白版

浅要了解一下Git是什么&#xff1a; Git是目前世界上最先进的的分布式控制系统。Git 和其他版本控制系统的主要差别在于&#xff0c;Git 只关心文件数据的整体是否发生变化&#xff0c;而大多数其他系统则只关心文件内容的具体差异。Git 并不保存这些前后变化的差异数据。实际上…

如何安全处置旧设备?

每年&#xff0c;数百万台旧设备因老化、故障或被新产品取代而被丢弃&#xff0c;这些设备上存储的数据可能带来安全风险。 如果设备没有被正确删除数据&#xff0c;这些数据往往仍可被恢复。因此&#xff0c;安全处置旧设备至关重要。 旧设备可能包含的敏感数据 旧设备中可能…

Java 学习记录:基础到进阶之路(一)

今天&#xff0c;让我们深入到 Java 项目构建、基础语法及核心编程概念的领域&#xff0c;一探究竟。 软件安装及环境配置请查看之前更新的博客有着详细的介绍&#xff1a; IDEA软件安装&环境配置&中文插件-CSDN博客 目录 1.Java 项目构建基础 1.项目中的 SRC 目录…