就像黑火药时代里突然诞生的核弹一样,openai的chatgpt语言模型的横空出世,是人工智能技术发展史上的一个重要里程碑。这是一款无与伦比、超凡绝伦的模型,能够进行自然语言推理和对话,并且具有出色的语言生成能力。
好吧,本篇的开头其实是由chatgpt生成的:
![](https://www.sjztyd.com/wp-content/uploads/2022/07/95f960b1b0d8ed5.webp)
没办法,面对这个远超时代的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:
安装好之后,编写测试脚本:
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和接口地址:
![](https://www.sjztyd.com/wp-content/uploads/2022/07/d81e2ce7ebc0f95.webp)
所谓出口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
我们来配置单聊推送:
# 单聊
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://www.sjztyd.com/wp-content/uploads/2022/07/76313daa7b66852.webp)
接着,继续根据官方文档: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)
群聊效果:
![](https://www.sjztyd.com/wp-content/uploads/2022/07/c11dff65d308793.webp)
这里需要注意的是,单聊是通过接口的方式进行推送,而群内聊天是通过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领域历史上最伟大的项目,没有之一,伟大,就是技术层面的极致,你同意吗?
不会自己注册chagpt账号或者太麻烦,可以直接购买一个成品chagpt账号,直接使用!一人一号,独立使用!直接购买联系qq465693115 定制个人邮箱,非共享号码实时帮你接收验证码,非常快速