公众号对接ChatGPT(Python实现)
微信公众号提供了一定的交互能力,那我们是否能够接入最近挺火的的ChatGPT?
实际上这与对接图灵机器人是一样的。
「准备工作」
个人公众号
内网穿透(便于本地调试)
「数据转发原理」
当在微信公众号后台发送消息时,数据会转发到微信服务器上,如果在公众号后台配置了接口信息,那么微信服务器会将数据转发到开发者服务器。由开发者服务器做出响应, 再经过微信服务器转发到微信公众号客户端
由于需要在公众号后台配置接口,所以并不能直接把本地启动的服务直接配置到公众号后台。因此需要使用内网穿透工具 将本地启动的服务映射到一个公网IP
内网穿透工具:量子互联
量子互联官网:https://www.uulap.com/nattunnel
配置如下
1.登录量子互联控制台
2.开通隧道(Http协议)
3.配置自定义域名
阿里云域名解析配置
「微信公众号配置」
「微信校验原理」
当在公众后后台配置好URL地址后,所有通过公众号发送的消息都会转发到该地址。并且URL会携带四个参数signature、timestamp、nonce、echostr
signature是对timestamp, nonce, 以及token(约定好的令牌信息)这三个参数进行sha1加密, 如果校验通过,那么就返回echostr给微信服务器。说明此次请求确实是微信服务器发过来的
使用Flask框架搭建一个本地Web服务, 并且端口号为80, 导入第三方库wechatpy完成数据安全校验
示例代码如下:
from flask import Flask, request
from wechatpy.utils import check_signature
from wechatpy.exceptions import InvalidSignatureException
app = Flask(__name__)
@app.route("/", methods=["GET", "POST"])
def index():
if (request.method == "GET"):
signature = request.args.get('signature')
timestamp = request.args.get('timestamp')
nonce = request.args.get('nonce')
echostr = request.args.get('echostr')
token = "12345678"
try:
check_signature(token, signature, timestamp, nonce)
except InvalidSignatureException:
# 处理异常情况或忽略
return "校验失败"
# 校验成功
return echostr
if (request.method == "POST"):
xml_str = request.data
# 解析xml格式数据
msg = parse_message(xml_str)
xml_str = request.data
# 解析xml格式数据
msg = parse_message(xml_str)
# 1.目标用户信息
target = msg.target
# 2.发送用户信息
source = msg.source
# 3.消息类型
msgType = msg.type
# 4.消息内容
msgCcontent = msg.content
print(msgCcontent)
reply = TextReply()
reply.source = target
reply.target = source
reply.content = "返回数据测试"
print(reply.content)
# 包装成XML格式的数据
xml = reply.render()
return xml
if __name__ == '__main__':
app.run(port=80)
用户通过公众号发送消息经由微信服务器转发到本地服务器的数据格式是XML(POST请求)因此需要接受并解析微信服务器转发的数据
示例
from wechatpy import parse_message
xml_str = request.data
# 解析xml格式数据
msg = parse_message(xml_str)
同样的, 响应数据也应该包装成XML格式
示例代码
from wechatpy.replies import TextReply
# 响应内容
reply = TextReply()
reply.source = target
reply.target = source
reply.content = '你好! 陈师兄!'
# 包装成XML格式的数据
xml = reply.render()
最后一步便是对接ChatGPT, 要不就是官方有提供接口调用(目前好像没有官方接口),要不就是抓包逆向接口(模拟请求)
这里直接采用Github上的一些脚本
下载第三方包
pip install pychatgp
完整代码
from flask import Flask, request
from wechatpy.utils import check_signature
from wechatpy.exceptions import InvalidSignatureException
from wechatpy import parse_message
from wechatpy.replies import TextReply
from pychatgpt import ChatGPT
app = Flask(__name__)
session_token = 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIn0..weVgk67lchseK8Pi.S_QOlVksDHDxk4nMBPHqwv59TAlRRXFvYQv4jIBNC50YD7MB_kmdUKRkZsIjEZhtBf8IXluKNtHWJGWcG1mwfz4KtrOSnRkHKYHpk7QHDK3JUBqeNc_2bx6TreLeogUT0tczB7KNlvUY7jWzagrV0gCLoDbkQk7aAlxSTEDS51BY20vciyrw0FkpD4e9APlWip9ugNd41UlBOi5HUa4QEYV6YEnUhU2peuN72ljTisxNKWKRrN5e6MRksGud1TPmVgYWu6BgmMO2HEpbc4sBjiUBbWw4mz3p9X5WW_n9t6f9ur_HQnCeGEalciWTyT4rhTa_fHjiwRKaOynUeH1_FQ1nqAwO6bHvMosNJ4VPO6oYrlENyd3HlPjYxKggZZdTiVMF_QeJxhuPOs8W3QnqRalxXrIPJs4UZbFUjoUcPsTMK3NydLFxZvNdwlvMoCaAfkgNeIW-JwOJ6hSi1c4K8jGJh2okriuCHt9yKUHbLABpk3c59XUJT2qVojCgpIrJfawheJVUl5P_RbEpEUQWE67PdUQS-j3kxCh0boLGSMt7rS6ivLeOmu4-hCQypL3p5-MNpHSldPQ3Y0AQKvqTt84x7YnTzDXVhzK-Q31bEDC1HYxC2cmPl04nLXfIzXdgRKURqjsdVfPorwhu552WiJVTfe9XTibXOzUjZp8mCZBN26-tLl6xCeBK23awoP3WQXFN8Q6s_RIZrEjnesep-IvRZrYou3hnW1vvSLBVtNFXiGOSdEZumMOEIUQmtfzonmWPs2OHDMkte82nnNOkEXSV6-PinjwO5-veOEmsyteXmRhV8x4EqUjhnLGNBL_6o4KdC7r_BioOZJ0okOxJPijWWmQgwTuSUa_SziJvD6RgM47qYv8F373LE9XIE4pzSkXoEYFq0kz4i4CRB5wx95iMaQBlswODC3_oGcveOa-BgBOU-41UWeFAFvQpZaXmEIJjMRKH6vzzzQygqIvdy8cL92xCf5j2Zj8u4cqV9x6F4XMi7ojvPXj0_5HLNXjBWg1x0uFFSqd4F6xyVyaOfL11M0pCCOn0G6G6vgYP2XAIGVGkh0z42kIiO4NcpdpLfxIzGV3mvlLHzRnq5i8Pg4hFs6Gqq__kA5PVBjuH6l8kkU0tqncqhUvvkDr0LV3LUtqDll85bllYCQzGX2I6ihf9HcdE8AtcL5YqEjeY-f2SMsRQ99IttCRZU06DLXev6h03U15AEoSLm8bXJ1Gs70AOsv-joaNbtpdiRT5AR1lYg0xdMUF3eGM4vGJ1G2uNWuCZXso8sKa_khAznU7e082-AERaxIitHpVQeLDuZRjmlnTfobbfsQ8ycM3qr6prWPf2PNhODrx2uDibpZK-5KXVicpstr0F4AoHVQN8tDlwRVoVX0VVCaWcyYkdWL_3wVUi1-1aVUfp53MrLIgRVujc-vTwTXuEIJAEA-nICVddiKoA4KKmBzJZRRwge3Nz0U_1XW0ddb07ro425j8bLxgn7YTXd0xLv4vFTRCboGRAUlIBxzEeh3giwrWk-UeX2eicsjiGXBJkpjsAVDWqp46nW_m7IUg5iS8OSuDAyCJkg7ug7JEgSCTDSEvzlZyfpJ6edyOqSTQHmrRnjPVIiNbNht9TZUM6uID4-T_yUYDw7_ym04e0NM6XIlih2b5itOQYHsp-Mx80xtri70fbWGIjf6TAcFoYBCc54X2VGxI5zTqiju15G0Wz6Y30b4bh5Uhr534-i6PaBhhFIIjZR2aqQVyCUEBgDIgfNfcrGp61766wy4xSG9kw0kl3AZlDxv5TPtqiZIxCZV6jrw6lGScFobuW4E47ZRiyZR7g3srE3bLfd-Do1g0fuZmFrQTTQD_8utx-0jE4C9_WX4aRV9potKvDn9h4tbybpYPyK-vAKBbV5mwuT-ALpRyj9OJGMd5KpTkAB5RyOHJeJE6EL5N798Mo7AhuNnXMgHd4wn70FePwjxhj1bVc_q39jY6ZyJvqNkbOHPZv77xfLuXHAqcQlUEfPpekEu4OoaCLWgU_xBy_JD-nQ0gQz5U3bnXDQHabXYcTgSLYH2jhZMjxc1VkrvD9mM3DZGdB3HNWueVhAZq5rtZkQGsR_IJ4Ur1l4ehC8WuO4jbgsS6DdYpAGqoi7w5yzt0yT06r3-9xa2pbLM5GwoL3UTSucHp4vTiinKc3_jYgb-UHDywS7Xb1IT4TON-ZPQescL19d-gWZWHwcHoulE0Q6WlBXwOrNiIc2gQmSQlcL8MK_cEqf7XYhmjrC0lo2Q1IItA59M_TdfeD9IkirlUc-M_q03efjlj59HP0g4QAOMhYBwkKGnNfjZFGwx-AbgeNFA.G1e--z56Fn0ZBhSpSSlzKw; Path=/; Expires=Sun, 08 Jan 2023 13:14:49 GMT; HttpOnly; Secure; SameSite=Lax' # `__Secure-next-auth.session-token` cookie from https://chat.openai.com/chat
api = ChatGPT(session_token)
@app.route("/", methods=["GET", "POST"])
def index():
if (request.method == "GET"):
signature = request.args.get('signature')
timestamp = request.args.get('timestamp')
nonce = request.args.get('nonce')
echostr = request.args.get('echostr')
token = "12345678"
try:
check_signature(token, signature, timestamp, nonce)
except InvalidSignatureException:
# 处理异常情况或忽略
return "校验失败"
# 校验成功
return echostr
if (request.method == "POST"):
xml_str = request.data
# 解析xml格式数据
msg = parse_message(xml_str)
xml_str = request.data
# 解析xml格式数据
msg = parse_message(xml_str)
# 1.目标用户信息
target = msg.target
# 2.发送用户信息
source = msg.source
# 3.消息类型
msgType = msg.type
# 4.消息内容
msgCcontent = msg.content
print(msgCcontent)
reply = TextReply()
reply.source = target
reply.target = source
reply.content = api.send_message(msgCcontent)
print(reply.content)
# 包装成XML格式的数据
xml = reply.render()
return xml
if __name__ == '__main__':
app.run(port=80)
测试效果
微信服务器默认会重试3次, 但是由于接口响应超时, 就会提示公众号服务故障。
不知道微信公众号能设置重试次数, 就暂时没继续深究了。
白丁学者 » 公众号对接ChatGPT(Python实现)