0


微信公众号订阅号(未认证)接入chatgpt最新gpt-4o模型实现AI聊天详细教程(免费体验)

微信公众号订阅号(未认证)接入chatgpt最新gpt-4o模型实现AI聊天详细教程(免费体验)

前言

众说周知,微信未经过认证的订阅号在接口权限上面有非常大的限制,例如:只能回复用户消息而不能主动推送;回复消息只能在三次微信推送的15秒内;回复用户消息有字符限制等等。这里主要是为了平衡国内调用openai接口的速度和微信公众号限制。

可关注公众号体验
个人公众号

原文地址:微信公众号订阅号(未认证)接入gpt-4o模型实现AI聊天详细教程(免费体验)

一、准备工作

  • 申请一个个人订阅号(很简单,不说了)
  • 到微信公众号的管理界面,点击 设置与开发 —> 基本配置开启服务器配置,自定义令牌,选择明文模式。微信公众号服务器配置
  • 如下所示,填写到配置文件中
#wechatmpwechatmp:#这里就是服务器配置中自己填写的 令牌(Token)token: xxxxxxxxxxxx

#chatgptchatgpt:model: gpt-4o
  # openAI 的接口apikey:- sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  #oepnai 接口基础地址 https://openai.xxx.com/ 或者使用自己的代理地址baseUrl: https://openai.xxxx.com/

二、验证服务器配置中的服务器URL

当我们填写服务器配置的URL时候,是需要验证URL地址的,验证代码如下:

  • Controller
@GetMapping("")publicResponseEntity<Object>checkSignature(WeChatBean weChatBean){//验证是否为微信消息String signatureHashcode = weChatService.checkWeChatSignature(weChatBean);if(!signatureHashcode.equals(weChatBean.getSignature())){returnResponseEntity.ok("非法数据");}//微信公众号接口认证if(StringUtils.isNotBlank(weChatBean.getEchostr())){returnResponseEntity.ok(weChatBean.getEchostr());}returnResponseEntity.ok(null);}
  • Service
@OverridepublicStringcheckWeChatSignature(WeChatBean weChatBean){String hashSignature =null;if(StringUtils.isBlank(weChatBean.getTimestamp())||StringUtils.isBlank(weChatBean.getNonce())){return hashSignature;}
        hashSignature =SignatureUtils.generateEventMessageSignature(wechatMpConfig.getToken(),
                weChatBean.getTimestamp(), weChatBean.getNonce());return hashSignature;}

三、 接受订阅号用户对话,调用openai接口

1、微信回复的处理

  • 过滤掉不是文本的对话信息(暂时只处理文本对话)
if(!params.get("MsgType").equals("text")){returngetReplyWeChat(weChatBean.getOpenid(), params.get("ToUserName"),"暂时只支持接收文本信息");}

对于处理ChatGPT接口回复逻辑,这里主要分为两方面:

  1. 当前对话是第一次调用,即:问问题
//调用chatgptfinalString msgKey =String.format(CommonConstant.CHAT_WX_USER_MSG_REPLY_KEY, msgId);if(!redisCacheUtils.hasKey(msgKey)){
            redisCacheUtils.setCacheObject(msgKey, success,30,TimeUnit.SECONDS);AsyncManager.me().execute(newTimerTask(){@Overridepublicvoidrun(){if(StringUtils.isNotBlank(content)){
                        redisCacheUtils.deleteObject(waitKey);
                        chatgptService.singleChatStreamToWX(weChatBean.getOpenid(), msgId, content);}}});}while(messageCountMap.containsKey(msgId)){String replay =checkMessageCountMap(msgId, currentMsgCount, start, toUserName, weChatBean);if(null!= replay){return replay;}Object o = redisCacheUtils.getCacheObject(msgKey);if(!success.equals(String.valueOf(o))){
                messageCountMap.remove(msgId);
                redisCacheUtils.deleteObject(Arrays.asList(msgKey, waitKey));returngetReplyWeChat(weChatBean.getOpenid(), toUserName,String.valueOf(o));}}
  1. 当前对话是为了取出openai的回答,即:输入 “继续”
if(StringUtils.isNotBlank(content)&& content.equals("继续")){while(messageCountMap.containsKey(msgId)){String replay =checkMessageCountMap(msgId, currentMsgCount, start, toUserName, weChatBean);if(null!= replay){return replay;}if(redisCacheUtils.hasKey(waitKey)){Object o = redisCacheUtils.getCacheObject(waitKey);Integer contentLength =getByteSize(String.valueOf(o));
                    messageCountMap.remove(msgId);if(contentLength <2048){
                        redisCacheUtils.deleteObject(waitKey);returngetReplyWeChat(weChatBean.getOpenid(), toUserName,String.valueOf(o));}else{String replyContent =String.valueOf(o).substring(0,580);
                        redisCacheUtils.setCacheObject(waitKey,String.valueOf(o).replace(replyContent,""),60,TimeUnit.MINUTES);returngetReplyWeChat(weChatBean.getOpenid(), toUserName, replyContent +"\n  (公众号回复字符限制,输入\"继续\"查看后续内容)");}}}return success;}

这里两处的 while循环操作,主要是为了尽可能的在三次微信消息推送的15秒内给出ChatGPT的回答,而不是让用户多次输入继续。

2、调用openai接口处理

  • 调用接口分为单轮对话和多轮对话(这里使用了开源的openai调用sdk)
<dependency><groupId>com.unfbx</groupId><artifactId>chatgpt-java</artifactId><version>1.1.5</version></dependency>
/**
     * 多轮会话
     * @param openId 用户openid 
     * @param msgId 消息id
     * @param content 问话内容
     */@OverridepublicvoidmultiChatStreamToWX(String openId,String msgId,String content){OpenAiStreamClient streamClient =getStreamClient();WeChatEventSourceListener weChatEventSourceListener =newWeChatEventSourceListener(openId, msgId);//获取历史会话记录List<Message> messages =getWxMessageList(openId, content);ChatCompletion chatCompletion =ChatCompletion.builder().stream(true).messages(messages).build();
        streamClient.streamChatCompletion(chatCompletion, weChatEventSourceListener);}/**
     * 单轮会话
     * @param openId 用户openid 
     * @param msgId 消息id
     * @param content 问话内容
     */@OverridepublicvoidsingleChatStreamToWX(String openId,String msgId,String content){OpenAiStreamClient streamClient =getStreamClient();WeChatEventSourceListener weChatEventSourceListener =newWeChatEventSourceListener(openId, msgId);Message message =Message.builder().role(BaseMessage.Role.USER).content(content).build();ChatCompletion chatCompletion =ChatCompletion.builder().stream(true).messages(Arrays.asList(message)).build();
        streamClient.streamChatCompletion(chatCompletion, weChatEventSourceListener);}
  • 这里处理opeAI接口接口返回,都是使用sse的形式,因此所有的结果处理都是在WeChatEventSourceListener中
publicWeChatEventSourceListener(String openId,String msgId){this.openId = openId;this.msgId = msgId;this.sb =newStringBuffer();}@OverridepublicvoidonClosed(@NotNullEventSource eventSource){
        log.info("OpenAI关闭sse连接...");//缓存回复到redis
        redisCacheUtils.setCacheObject(waitKey, sb.toString(),60,TimeUnit.MINUTES);
        redisCacheUtils.setCacheObject(msgKey, sb.toString(),60,TimeUnit.SECONDS);
        eventSource.cancel();}@OverridepublicvoidonEvent(@NotNullEventSource eventSource,@NullableString id,@NullableString type,@NotNullString data){
        log.debug("OpenAI返回数据:{}", data);if(!"[DONE]".equals(data)){ChatCompletionResponse response =JSON.parseObject(data,ChatCompletionResponse.class);if(null== response.getChoices().get(0).getFinishReason()){String content = response.getChoices().get(0).getDelta().getContent();
                sb.append(content);}}else{
            log.info("OpenAI返回数据结束了");}}

结束语

以上只是实现了简单的订阅号对话openai,下面是本项目开源地址

项目开源地址: wechatgpt 微信订阅号对接gpt-4o模型


本文转载自: https://blog.csdn.net/cmy768330962/article/details/137102183
版权归原作者 取个好一点的名字真的是太难了 所有, 如有侵权,请联系我们删除。

“微信公众号订阅号(未认证)接入chatgpt最新gpt-4o模型实现AI聊天详细教程(免费体验)”的评论:

还没有评论