把盏言欢,款款而谈,ChatGPT结合钉钉机器人(outgoing回调)打造人工智能群聊/单聊场景,基于Python3.10

news2024/12/23 23:36:09

就像黑火药时代里突然诞生的核弹一样,OpenAI的ChatGPT语言模型的横空出世,是人工智能技术发展史上的一个重要里程碑。这是一款无与伦比、超凡绝伦的模型,能够进行自然语言推理和对话,并且具有出色的语言生成能力。

好吧,本篇的开头其实是由ChatGPT生成的:

在这里插入图片描述

没办法,面对这个远超时代的AI产品,我们能说什么呢?顶礼膜拜?惊为天人?任何言语对于描述ChatGPT来说已经是苍白无力的,而辞海中的形容词在面对ChatGPT时也已经鞭长莫及。

一句话:言语不能赞其伟大。

本次我们利用ChatGPT的开放API接入钉钉群聊/单聊机器人,让钉钉机器人具备进行自然语言推理和对话的能力,所谓化腐朽为神奇,不过如此。

注册和使用OpenAi的ChatGPT

首先注册OpenAi平台:https://beta.openai.com/ ,由于ChatGPT过于火爆,导致很多地区无法正常注册,这里推荐使用北美地区的代理IP,与此同时,一定要注意,如果之后希望使用后端的API接口方式调用ChatGPT,就不要使用谷歌或者微软的三方账号进行登录,否则无法通过邮箱和秘钥交换OpenAi平台的access_token,切记。

同时,接受验证码手机号也必须是北美地区的手机号,这里推荐一个北美地区的接码平台:https://sms.qisms.com/index 非常好用。

注册成功之后,这里推荐github上开源大神rawandahmad698已经封装好的开源SDK,避免重复造轮子:https://github.com/rawandahmad698/PyChatGPT

安装SDK:

pip3 install chatgptpy --upgrade

安装好之后,编写测试脚本:

chat = Chat(email="OpenAi邮箱", password="OpenAi密码",proxies="代理地址")  
  
answer = chat.ask("你好")  
  
print(answer)

注意,运行代码之前,一定要使用代理proxies,并且确保是北美地区的IP地址。

程序返回:

[OpenAI] Email address: ********  
[OpenAI] Password: *********  
[OpenAI] Using proxy: {'http': 'http://localhost:4780', 'https': 'http://localhost:4780'}  
[OpenAI] Beginning auth process  
[OpenAI][1] Making request to https://chat.openai.com/auth/login  
[OpenAI][1] Request was successful  
[OpenAI][2] Beginning part two  
[OpenAI][2] Grabbing CSRF token from https://chat.openai.com/api/auth/csrf  
[OpenAI][2] Request was successful  
[OpenAI][2] CSRF Token: 1b1357a34e4b0b9a74e999372fe0413ab981c9a72e030a54b3bf172bd6176c5e  
[OpenAI][3] Beginning part three  
[OpenAI][3] Making request to https://chat.openai.com/api/auth/signin/auth0?prompt=login  
[OpenAI][3] Request was successful  
[OpenAI][3] Callback URL: https://auth0.openai.com/authorize?client_id=TdJIcbe16WoTHtN95nyywh5E4yOo6ItG&scope=openid%20email%20profile%20offline_access%20model.request%20model.read%20organization.read&response_type=code&redirect_uri=https%3A%2F%2Fchat.openai.com%2Fapi%2Fauth%2Fcallback%2Fauth0&audience=https%3A%2F%2Fapi.openai.com%2Fv1&prompt=login&state=RJt9U13ATPmlt795xMNohQZcUNOytZNvHoq3JI8HGZ4&code_challenge=Pq97ptna00Ybak2dUmIMhR3eqmXZnZz-Fij7otMMw7U&code_challenge_method=S256  
[OpenAI][4] Making request to https://auth0.openai.com/authorize?client_id=TdJIcbe16WoTHtN95nyywh5E4yOo6ItG&scope=openid%20email%20profile%20offline_access%20model.request%20model.read%20organization.read&response_type=code&redirect_uri=https%3A%2F%2Fchat.openai.com%2Fapi%2Fauth%2Fcallback%2Fauth0&audience=https%3A%2F%2Fapi.openai.com%2Fv1&prompt=login&state=RJt9U13ATPmlt795xMNohQZcUNOytZNvHoq3JI8HGZ4&code_challenge=Pq97ptna00Ybak2dUmIMhR3eqmXZnZz-Fij7otMMw7U&code_challenge_method=S256  
[OpenAI][4] Request was successful  
[OpenAI][4] Current State: hKFo2SA5VzlqUDA0Mkl5TnQtNUpYcGRBU0ZfRkhQVUY1eVpWV6Fur3VuaXZlcnNhbC1sb2dpbqN0aWTZIGMzU0xvbThRUXFxMTczeVg4bF8zRFZnYVNOM2M3Q0RFo2NpZNkgVGRKSWNiZTE2V29USHROOTVueXl3aDVFNHlPbzZJdEc  
[OpenAI][5] Making request to https://auth0.openai.com/u/login/identifier?state=hKFo2SA5VzlqUDA0Mkl5TnQtNUpYcGRBU0ZfRkhQVUY1eVpWV6Fur3VuaXZlcnNhbC1sb2dpbqN0aWTZIGMzU0xvbThRUXFxMTczeVg4bF8zRFZnYVNOM2M3Q0RFo2NpZNkgVGRKSWNiZTE2V29USHROOTVueXl3aDVFNHlPbzZJdEc  
[OpenAI][5] Request was successful  
[OpenAI][5] No captcha detected  
[OpenAI][6] Making request to https://auth0.openai.com/u/login/identifier  
[OpenAI][6] Email found  
[OpenAI][7] Entering password...  
[OpenAI][7] Password was correct  
[OpenAI][7] Old state: hKFo2SA5VzlqUDA0Mkl5TnQtNUpYcGRBU0ZfRkhQVUY1eVpWV6Fur3VuaXZlcnNhbC1sb2dpbqN0aWTZIGMzU0xvbThRUXFxMTczeVg4bF8zRFZnYVNOM2M3Q0RFo2NpZNkgVGRKSWNiZTE2V29USHROOTVueXl3aDVFNHlPbzZJdEc  
[OpenAI][7] New State: c3SLom8QQqq173yX8l_3DVgaSN3c7CDE  
[OpenAI][8] Making request to https://auth0.openai.com/authorize/resume?state=c3SLom8QQqq173yX8l_3DVgaSN3c7CDE  
[OpenAI][8] All good  
[OpenAI][8] Access Token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UaEVOVUpHTkVNMVFURTRNMEZCTWpkQ05UZzVNRFUxUlRVd1FVSkRNRU13UmtGRVFrRXpSZyJ9.eyJodHRwczovL2FwaS5vcGVuYWkuY29tL3Byb2ZpbGUiOnsiZW1haWwiOiJ6Y3hleTI5MTFAb3V0bG9vay5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZ2VvaXBfY291bnRyeSI6IlVTIn0sImh0dHBzOi8vYXBpLm9wZW5haS5jb20vYXV0aCI6eyJ1c2VyX2lkIjoidXNlci1IcHQ2SXF6R0k0RW43V213dGdzaUVOUjUifSwiaXNzIjoiaHR0cHM6Ly9hdXRoMC5vcGVuYWkuY29tLyIsInN1YiI6ImF1dGgwfDYzOTA3ZWRiMTQzYTFkZjQxMzk5Yzc0YyIsImF1ZCI6WyJodHRwczovL2FwaS5vcGVuYWkuY29tL3YxIiwiaHR0cHM6Ly9vcGVuYWkuYXV0aDAuY29tL3VzZXJpbmZvIl0sImlhdCI6MTY3MDQ1OTkzNywiZXhwIjoxNjcwNTQ2MzM3LCJhenAiOiJUZEpJY2JlMTZXb1RIdE45NW55eXdoNUU0eU9vNkl0RyIsInNjb3BlIjoib3BlbmlkIGVtYWlsIHByb2ZpbGUgbW9kZWwucmVhZCBtb2RlbC5yZXF1ZXN0IG9yZ2FuaXphdGlvbi5yZWFkIG9mZmxpbmVfYWNjZXNzIn0.PtXKhJqwudNKLIkNRc5OO6T7Tsl8ydZ8WWnCJ3Ax2c40CQibRTiGLDmfvk2gW5pVIkOpKldWYs6Jrd8UVi0Ih9VMDwS9JL6HpZKsoRaIhy6r6l7AW5vMMQN-l0ntCsgefQeGIrwtCTUsIklN8dyZDkRkympC2AzRkayAcFvFckXTHi_J5Fivr5J7We_OM4cGFJEKTLkaSw6MnYku-uYwAKPVEpFsF7fLnUBRQxn5Zz90FhdeLYEg4IUjPWKPp1iMbp_fa9qhwwtKBwogtrIVzq2t8NdUotoNYgoo2uV2xjQWC2m4V4C_xgkSzLj2TTtRJMOYKGH-lHWs2_yRQF0wOg  
[OpenAI][9] Saving access token...  
[OpenAI][8] Saved access token

首次运行程序会通过代理自动登录OpenAi平台,并且换取token,最后将token存储在本地。

随后返回ChatGPT的信息:

➜  mydemo git:(master) ✗ /opt/homebrew/bin/python3.10 "/Users/liuyue/wodfan/work/mydemo/test_chatgpt.py"  
Using proxies: http://localhost:4780  
你好,很高兴为你提供帮助。有什么需要我帮忙的吗?

至此,ChatGPT接口就调试好了。

配置钉钉Dingding机器人

随后,我们来配置C端的机器人,注意这里一定要使用支持outgoing回调的企业机器人,而不是普通的机器人,参考文档:https://open.dingtalk.com/document/group/enterprise-created-chatbot

创建好企业机器人之后,获取机器人应用的Key和秘钥,同时配置好出口IP和接口地址:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6GqtLjXp-1670464668780)(https://v3u.cn/v3u/Public/js/editor/attached/20221208091235_27510.png)]

所谓出口IP即调用钉钉服务合法的ip,消息接受地址是接受C端信息的地址,这里我们使用异步非阻塞的Tornado框架来构建接受信息服务:

import hmac  
import hashlib  
import base64  
import json  
import tornado  
  
from tornado.options import define, options  
define('port', default=8000, help='default port',type=int)  
  
class Robot(tornado.web.RequestHandler):  
  
    async def post(self):  
  
  
        timestamp = self.request.headers.get('timestamp', None)  
  
        sign = self.request.headers.get('sign', None)  
        app_secret = '钉钉机器人秘钥'  
        app_secret_enc = app_secret.encode('utf-8')  
        string_to_sign = '{}\n{}'.format(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()  
        my_sign = base64.b64encode(hmac_code).decode('utf-8')  
        if sign != my_sign:  
            return self.finish({"errcode":1,"msg":"签名有误"})  
        data = json.loads(self.request.body)  
        text = data['text']["content"]  
        atUsers = data.get("atUsers",None)  
        uid = data.get("senderStaffId",None)  
        return self.finish({"errcode":0,"msg":text})  
  
urlpatterns = [  
    (r"/robot_chat/",Robot),  
]  
  
  
# 创建Tornado实例  
application = tornado.web.Application(urlpatterns,debug=True)  
  
  
if __name__ == "__main__":  
    tornado.options.parse_command_line()  
    application.listen(options.port)  
    tornado.ioloop.IOLoop.instance().start()

这里我们通过Robot异步控制器来接受所有来自钉钉客户端的信息,即人类对机器人说的话,需要注意的是,后端服务需要对请求头中的timestamp和sign进行验证,以判断是否是来自钉钉的合法请求,避免其他仿冒钉钉调用开发者的HTTPS服务传送数据。

所以这里一旦签名有问题,就结束逻辑:



timestamp = self.request.headers.get('timestamp', None)  
  
sign = self.request.headers.get('sign', None)  
app_secret = '钉钉机器人秘钥'  
app_secret_enc = app_secret.encode('utf-8')  
string_to_sign = '{}\n{}'.format(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()  
my_sign = base64.b64encode(hmac_code).decode('utf-8')  
if sign != my_sign:  
    return self.finish({"errcode":1,"msg":"签名有误"})


最后该接口会返回发信人id(uid)以及具体信息内容(text)。

至此,后端接受服务就配置好了。

下面就是后端推送服务,首先,根据官方文档:https://open.dingtalk.com/document/orgapp-server/obtain-the-access_token-of-an-internal-app?spm=ding_open_doc.document.0.0.5f255239xgW3zE#topic-2056397

需要获取钉钉接口的token:

def get_token(self):  
  
        res = requests.post("https://api.dingtalk.com/v1.0/oauth2/accessToken",data=json.dumps({"appKey":self._appKey,"appSecret":self._appSecret}),headers={"Content-Type":"application/json"})  
  
        token = res.json()["accessToken"]  
  
        return token

随后,根据文档:https://open.dingtalk.com/document/group/chatbots-send-one-on-one-chat-messages-in-batches?spm=ding_open_doc.document.0.0.22e749acXECz5m#topic-2080109

我们来配置单聊推送:

# 单聊  
    def send_message(self,uid,message):  
  
        res = requests.post("https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend",data=json.dumps({"robotCode":self._appKey,"userIds":[uid],"msgKey":"sampleText","msgParam":'{"content":"'+message+'"}'}),headers={"Content-Type":"application/json","x-acs-dingtalk-access-token":self._token})  
  
        print(res.text)

具体效果:

接着,继续根据官方文档:https://open.dingtalk.com/document/robots/guide-to-user-access-for-intra-enterprise-robot-group-chat

配置群聊推送方法:

# 群聊  
    def send_user(self,uid,message):  
  
        data = {  
        "at": {  
            "atUserIds": [  
                uid  
            ]  
        },  
        "text": {  
            "content": message  
        },  
        "msgtype": "text"  
        }  
  
        res = requests.post(self._webhook,data=json.dumps(data),headers={"Content-Type":"application/json"})  
  
        print(res.text)

群聊效果:

这里需要注意的是,单聊是通过接口的方式进行推送,而群内聊天是通过webhook方式进行推送,关于webhook,请移玉步至:使用python3.7配置开发钉钉群自定义机器人(2020年新版攻略)

完整代码:

import requests  
import json  
  
from pychatgpt import Chat  
  
class DingDing:  
  
  
    def __init__(self,appKey=None,appSecret=None) -> None:  
  
        self._appKey = appKey  
  
        self._appSecret = appSecret  
          
        self._token = self.get_token()  
  
        # 机器人webhook地址  
        self._webhook = ""  
  
          
  
  
    def get_token(self):  
  
        res = requests.post("https://api.dingtalk.com/v1.0/oauth2/accessToken",data=json.dumps({"appKey":self._appKey,"appSecret":self._appSecret}),headers={"Content-Type":"application/json"})  
  
        token = res.json()["accessToken"]  
  
        return token  
  
    # 单聊  
    def send_message(self,uid,message):  
  
        res = requests.post("https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend",data=json.dumps({"robotCode":self._appKey,"userIds":[uid],"msgKey":"sampleText","msgParam":'{"content":"'+message+'"}'}),headers={"Content-Type":"application/json","x-acs-dingtalk-access-token":self._token})  
  
        print(res.text)  
  
    # 群聊  
    def send_user(self,uid,message):  
  
        data = {  
        "at": {  
            "atUserIds": [  
                uid  
            ]  
        },  
        "text": {  
            "content": message  
        },  
        "msgtype": "text"  
        }  
  
        res = requests.post(self._webhook,data=json.dumps(data),headers={"Content-Type":"application/json"})  
  
        print(res.text)  
  
  
  
  
if __name__ == '__main__':  
  
    dingding = DingDing("appkey","appSecret")  
  
    #chat = Chat(email="OpenAi邮箱", password="OpenAi密码",proxies="代理地址")  
  
    #answer = chat.ask("你好")  
  
    # 单聊  
    #dingding.send_message('uid',answer)  
  
    # 群聊  
    #dingding.send_user('uid',answer)  
  
    #print(answer)

至此,后端推送服务就配置好了。

结语

最后,奉上Github项目地址,与众亲同飨:https://github.com/zcxey2911/Python_ChatGPT_ForDingding_OpenAi ,毫无疑问,ChatGPT是NLP领域历史上最伟大的项目,没有之一,伟大,就是技术层面的极致,你同意吗?

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

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

相关文章

资产扫描神器ARL增强改造

拉取项目首先从GitHub克隆到服务器上。git clone https://github.com/ki9mu/ARL-plus-docker/修改配置文件因为ARL在配置文件里设置了黑名单,有时候项目为GOV或者EDU之类的时候无法进行扫描,所以在这里修改一下配置文件就可以解除限制。cd ARL-plus-dock…

Spring Boot3.0 GA系列全新版本-全新体验-学习案例1

SpringBoot3.0 GA 2022-11-24这是伟大的一天,Spring Boot进入了3.0时代,并会叩开JDK全面升级的浪潮 文章目录SpringBoot3.0 GA技术支持一、新建第一个mode?1.1、打开IDEA,新建项目1.2、选择 版本 和 依赖1.3、查看项目结构1.4、配…

vscode配置remote ssh

1. 安装插件 设置界面 右键最左边tab栏: 主体: vscode 插件: Remote SSH Linux主体: vscode-server 插件: C/C, CMake, CMake Tools, CodeLLDB, Rainbow Brackets, vscode-proto3, SVN 虚拟化主体: multipass linux发行版(比如ubuntu) 补充: multipass实例本地端口…

【C++ unordered_set set 和 unordered_map 和 map】

文章目录前言简单介绍哈希表,哈希结构什么时候用哈希表unordered_map操作likou第一题 两数之和unordered_set 基础操作unordered_set 实现总结前言 今天重新打开力扣,看到以前的签到题两数之和,以前的方法是双指针暴力解法,偶然看…

asp.net校园二手物品交易网站

目录 摘 要 Ⅰ Abstract Ⅱ 第一章 概述 1 1.1网站的开发背景 1 1.1.1学生二手物品交易置换网站的开发背景 1 1.1.2学生二手物品交易活动的现状 1 1.2 学生二手物品交易置换网站的研究方向和内容 2 1.2.1研究方向 2 1.2.2研究内容 2 1.3 学生二手物品交易置换网站的设计目标 2…

transformer中QKV的通俗理解(剩女与备胎的故事)

用vit的时候读了一下transformer的思想,前几天面试结束之后发现对QKV又有点忘记了, 写一篇文章来记录一下 参考链接: 哔哩哔哩:在线激情讲解transformer&Attention注意力机制(上)在线激情讲解transformer&Attention注意力机制(上&…

SpringCloud全系列知识(5)——微服务的部署(Docker)

微服务的部署(Docker) 一 初识Docker 1.项目部署问题 大型项目组件较多,运行环境较为复杂,部署和维护困难依赖关系复杂,容易出现兼容性问题开发,测试,生产环境有差异 2.解决依赖的兼容问题 …

[附源码]Python计算机毕业设计Django疫情期间小学生作业线上管理系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,我…

差分方程解的稳定性

Heine定理 存在的充要条件是: 取定义域内的任意数列,有 差分的定义 考虑离散型变量 一阶差分为: 二阶差分为: 线性差分方程的解 非齐次差分方程的解 满足初始条件的n阶非齐次线性差分方程 的解是存在且唯一的 非齐次线性差分方程的通解结构:齐次差分方程的解 线性相关与…

提升规则自治能力与原生分析能力、支持视频流接入处理

11 月, eKuiper 团队转入 1.8.0 版本的开发周期之中,目前已完成了一部分实用的新功能:添加了视频流 source,将边缘流式处理能力扩展到视频流领域,可以处理摄像头的视频流或者网络中的直播视频流;发布了通用…

[附源码]Python计算机毕业设计Django智能家电商城

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

苹果iOS 16.2/iPadOS 16.2 RC版发布:隔空投送10分钟限制全球上线

今日,苹果向用户推送了iOS 16.2/iPadOS 16.2 RC候选版更新,内部版本号为20C65。 本次更新主要包括以下改进和错误修复: 一、隔空投送10分钟限制在全球上线,原本的“所有人”选项改为“所有人,10分钟”,超过…

从事功能测试1年,裸辞1个月,找不到工作的“我”怎么办?

做功能测试一年多了裸辞职一个月了,大部分公司都要求有自动化测试经验,可是哪来的自动化测试呢? 我要是简历上写了吧又有欺诈性,不写他们给的招聘又要自动化优先,将项目带向自动化不是一个容易的事情,很多…

守护网络安全的第一道门—防火墙

防火墙作为网络安全领域的第一道门,可以有效的过滤和阻止未经允许的流量进出,选择性地阻止或允许数据包。防火墙通常用于帮助阻止恶意活动并防止专用网络内外的任何人进行未经授权的 Web 活动。在网络安全领域起到了至关重要的作用。 防火墙有什么作用…

引擎入门 | Unity UI简介–第2部分(6)

本期我们继续为大家进行Unity UI简介(第二部分)的后续教程 本篇内容 10.点击按钮时显示对话框 11.增加一个关闭按钮 文章末尾可免费获取教程源代码 本篇本篇Unity UI简介(第二部分)篇幅较长,分为八篇,…

eclipse+tomcat+spring mvc开发笔记

一:Tomcat安装 在.net web开发中,微软再一次向你展示了一站式马赛克配置,你只需要轻轻一点按钮,发射。。。一个带有bootstrap框架的页面就呈现在你的面前,在 java中就没有这么好的事情了,基本都是高清无码。 1. 下载地址 http://mirrors.hust.edu.cn/apache/tomcat/tomc…

v1.9.1 进行中:MQTT X CLI 支持自动重连及保存和读取本地文件

十一月初,MQTT X 团队发布了 1.9.0 版本:MQTT X CLI 命令行客户端实现支持 MQTT 的性能测试,桌面端应用新增了关于学习 MQTT 的帮助页面等,此外还进行了一些使用优化和问题修复。 目前,团队正专注于 1.9.1 版本的开发…

电脑上如何禁止一切弹窗广告?永久关闭桌面弹出广告

现在日常生活工作离不开电脑,在用电脑办公的时候,弹窗广告总会打扰我们的办公,即使关闭弹窗也无用,很是让人讨厌,电脑上如何禁止一切弹窗广告?本篇教程教您如何快速关闭弹窗广告。如果您在使用电脑过程中&a…

人机界面石油行业的应用:如何构建自动化石化罐区储运监控系统?

一、应用背景 在石油化工企业的生产过程中,运输和储存的大部分介质和产品都是流体,为了保证加工过程的正常运行,企业通常建有大量各种储藏罐的罐区。随着工业自动化技术的发展和计算机技术在罐区控制系统中的应用,罐区自动化系统…

antd-vue 累加表单编辑和删除

一、业务场景&#xff1a; 最近在使用Antd-Vue组件库的时候&#xff0c;发现在累加表单 时没有直接可以用的&#xff0c;必须自己在官网上手动合并几个才能实现&#xff0c;为了大家后面遇到和我一样的问题&#xff0c;给大家分享一下 二、具体实现步骤&#xff1a; <temp…