当前位置:   article > 正文

springoot 集成百度文心千帆大模型应用,搭建企业微信应用消息,实现企业微信被动消息聊天服务_springboot 文心一言

springboot 文心一言

一、IDEA构建springboot应用脚手架

引入springboot-coloud-star等基础依赖

 基础技能相信学java都会。

二、企业微信自建应用与后台服务实现交互

  1. 已需要下载PC版企业微信,并且注册自己的企业,主要为了获取企业ID等与企业微信服务打通,登录企业管理后台企业微信
  2. 选择自建应用,新建自己的应用,如下,我自建一个小应用就叫【文心一言】

3.点击我的企业,获取企业scorpId

 4.设置应用与自己的后台应用的消息接口API

 该接口API就是企业微信自建应用与我后台交互的关键,具体实现步骤如下:

  • 在springboot项目的配置文件中配置当前企业微信的企业sCorpID、sToken、sEncodingAESKey,后两项可以通过API接收消息界面动态随机获取,也可以自己生成。
  •  关键代码,按照企业微信自建应用消息的开发文档,必须实现两个请求方式为GET和POST的相同接口URL的接口:
  • GET请求:
  1. @GetMapping("/checkURL")
  2. public String validEntWeChatURL(HttpServletRequest request) {
  3. logger.info("AiManagerController validEntWeChatURL validEntWeChatURL={}", request);
  4. String sReplyEchoStr = null;
  5. //微信加签
  6. String sMsg_signature = request.getParameter("msg_signature");
  7. //解析url
  8. String sTimestamp = request.getParameter("timestamp");
  9. String SNonce = request.getParameter("nonce");
  10. String SEchostr = request.getParameter("echostr");
  11. try {
  12. sReplyEchoStr = cryptUtil.getCrypt().VerifyURL(sMsg_signature, sTimestamp, SNonce, SEchostr);
  13. } catch (AesException e) {
  14. logger.error("AiManagerController validEntWeChatURL err={}", e);
  15. }
  16. logger.info("AiManagerController validEntWeChatURL sReplyEchoStr={},微信验签成功!", sReplyEchoStr);
  17. return sReplyEchoStr;
  18. }

 POST请求

  1. /**
  2. * 接收企业微信的消息
  3. *
  4. * @param request
  5. * @return
  6. */
  7. @PostMapping("/checkURL")
  8. public String getEntWXMsg(HttpServletRequest request, HttpServletResponse response) {
  9. String respMsg = "";
  10. //微信加签
  11. String sMsg_signature = request.getParameter("msg_signature");
  12. //解析url
  13. String sTimestamp = request.getParameter("timestamp");
  14. String SNonce = request.getParameter("nonce");
  15. try {
  16. ServletInputStream inputStream = request.getInputStream();
  17. String sReqData = IoUtils.toString(inputStream, "UTF-8");
  18. String sReplyEchoStr = cryptUtil.getCrypt().DecryptMsg(sMsg_signature, sTimestamp, SNonce, sReqData);
  19. //解析xml数据
  20. DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  21. DocumentBuilder db = dbf.newDocumentBuilder();
  22. StringReader sr = new StringReader(sReplyEchoStr);
  23. InputSource is = new InputSource(sr);
  24. Document document = db.parse(is);
  25. Element root = document.getDocumentElement();
  26. NodeList nodelist1 = root.getElementsByTagName("Content");
  27. String content = nodelist1.item(0).getTextContent();
  28. //获取成员UserID
  29. NodeList nodelist2 = root.getElementsByTagName("FromUserName");
  30. String fromUserName = nodelist2.item(0).getTextContent();
  31. //返回的消息内容
  32. // logger.info("AiManagerController getEntWXMsg Content:{}", content);
  33. String baiduRespMsg = baiduAPIUtil.call_ERNIEBot(content, fromUserName);
  34. // logger.info("AiManagerController call_ERNIE_Bot baiduRespMsg:{}", baiduRespMsg);
  35. //回复的消息
  36. EntWXResp resp = new EntWXResp();
  37. resp.setFromUserName(cryptUtil.getWxProperties().getSCorpID());
  38. resp.setToUserName(fromUserName);
  39. resp.setContent(baiduRespMsg);
  40. resp.setMsgType("text");
  41. resp.setCreateTime(DateUtil.date().toStringDefaultTimeZone());
  42. //拼装被动消息返回体
  43. //生成xml 字符串
  44. String xmlMsg = "<xml>\n" +
  45. " <ToUserName><![CDATA[" + resp.getToUserName() + "]]></ToUserName>\n" +
  46. " <FromUserName><![CDATA[" + resp.getFromUserName() + "]]></FromUserName> \n" +
  47. " <CreateTime>" + resp.getCreateTime() + "</CreateTime>\n" +
  48. " <MsgType><![CDATA[" + resp.getMsgType() + "]]></MsgType>\n" +
  49. " <Content><![CDATA[" + resp.getContent() + "]]></Content>\n" +
  50. "</xml>\n";
  51. // logger.info("AiManagerController call_ERNIE_Bot xmlMsg =:{}", xmlMsg);
  52. //加密返回
  53. respMsg = cryptUtil.getCrypt().EncryptMsg(xmlMsg, sTimestamp, SNonce);
  54. logger.info("AiManagerController cryptUtil.EncryptMsg respMsg ={}", respMsg);
  55. } catch (AesException e) {
  56. logger.error("AiManagerController getEntWXMsg err={}", e);
  57. } catch (ParserConfigurationException e) {
  58. logger.error("AiManagerController getEntWXMsg err={}", e);
  59. } catch (IOException e) {
  60. logger.error("AiManagerController getEntWXMsg err={}", e);
  61. } catch (SAXException e) {
  62. logger.error("AiManagerController getEntWXMsg err={}", e);
  63. }
  64. return respMsg;
  65. }

三、集成百度文心一言应用API

在服务配置文件application.yml配置好该参数:

  1. ##百度文心千帆AI接口配置
  2. baidu:
  3. client_id: j3tpU0KhE3Iwewewew
  4. client_secret: PLSEAb8yXTzGasewewewewnDA7wew
  5. grant_type: client_credentials
  • 按照百度接口文档,开发相应API实现,调用API,zhiqian buxyo huoqu TOKEN
    1. /**
    2. * 获取百度云应用 的access_token
    3. *
    4. * @return
    5. */
    6. public BaiduApiResp getBaiDuAccessToken() {
    7. //设置百度缓存的 key
    8. String reinsCacheToken = String.format(ACCEESS_TOKEN_KEY, CLIENT_ID);
    9. if (redisService.hasKey(reinsCacheToken)) {
    10. BaiduApiResp cacheObject = redisService.getCacheObject(reinsCacheToken);
    11. logger.info("BaiduAPIUtil getBaiDuAccessToken ={}", cacheObject);
    12. return cacheObject;
    13. }
    14. BaiduApiResp resp = new BaiduApiResp();
    15. HashMap<String, Object> paramMap = new HashMap<>();
    16. paramMap.put("client_id", CLIENT_ID);
    17. paramMap.put("client_secret", CLIENT_SECRET);
    18. paramMap.put("grant_type", GRANT_TYPE);
    19. String returnMsg = HttpUtil.post(BAIDU_URL, paramMap);
    20. JSONObject respons = JSONUtil.parseObj(returnMsg);
    21. if (!StrUtil.isEmptyIfStr(respons.getStr("error"))) {
    22. logger.error("BaiduAPIUtil getBaiDuAccessToken err={},error_description={}",
    23. respons.getStr("error"),
    24. respons.getStr("error_description"));
    25. return resp;
    26. }
    27. //获取token
    28. String access_token = respons.getStr("access_token");
    29. resp.setAccess_token(access_token);
    30. //获取有效期
    31. Integer expires_in = respons.getInt("expires_in");
    32. resp.setExpires_in(expires_in);
    33. //当如缓存,过期再取
    34. redisService.setCacheObject(reinsCacheToken, resp, Long.valueOf(expires_in), TimeUnit.SECONDS);
    35. return resp;
    36. }
    1. /**
    2. * ERNIE-Bot是百度自行研发的大语言模型,
    3. * 覆盖海量中文数据,具有更强的对话问答、内容创作生成等能力。
    4. *
    5. * @return
    6. */
    7. public String call_ERNIEBot(String askStr, String userId) {
    8. logger.info("BaiduAPIUtil call_ERNIEBot askStr={},userId={}", askStr, userId);
    9. // 添加请求头信息
    10. Map<String, String> heads = new HashMap<>();
    11. heads.put("Content-Type", "application/json");
    12. Map<String, String> urlParmMap = new HashMap<>();
    13. urlParmMap.put("access_token", getBaiDuAccessToken().getAccess_token());
    14. String realUrl = ERNIE_BOT_URL + URLUtil.buildQuery(urlParmMap, CharsetUtil.CHARSET_UTF_8);
    15. //创建json对象作为requestBody
    16. MessageVo message = new MessageVo();
    17. message.setRole("user");
    18. message.setContent(askStr);
    19. List<MessageVo> messages = new ArrayList<>();
    20. messages.add(message);
    21. JSONObject jsonObject = new JSONObject();
    22. jsonObject.set("messages", messages.toArray());
    23. jsonObject.set("stream", Boolean.TRUE);
    24. //用户id
    25. jsonObject.set("user_id", userId);
    26. System.out.println(JSONUtil.toJsonStr(jsonObject));
    27. HttpResponse returnMsg = HttpRequest.post(realUrl).headerMap(heads, false)
    28. .body(String.valueOf(jsonObject))
    29. .execute();
    30. String result = StrUtil.EMPTY;
    31. JSONObject response = JSONUtil.parseObj(returnMsg);
    32. String status = response.getStr("status");
    33. if ("200".equals(status)) {
    34. byte[] bytes = returnMsg.body().getBytes();
    35. result = new String(bytes);
    36. String[] split = result.split("\n");
    37. StringBuffer buffer = new StringBuffer();
    38. for (String s : split) {
    39. if(s.contains("data")){
    40. String subStr = s.substring(s.indexOf("{")-1);
    41. JSONObject entries = JSONUtil.parseObj(subStr);
    42. buffer.append(entries.getStr("result"));
    43. }
    44. }
    45. logger.info("BaiduAPIUtil call_ERNIEBot result={}", buffer);
    46. return buffer.toString();
    47. }
    48. return result;
    49. }

    四、最终实现效果:

 

 注意点:

  • 企业微信设置API接收必须要是企业申请的域名URL,所以测试成本有点高,适合企业开发。
  • 其次,微信对接口响应有要求,对接百度的接口必须在1s内有响应,否则企业微信后台会丢弃该次请求。这会导致我们向企业微信发送消息不会有回应。之后在5s内,企业微信会幂等性的重试3次,所以我在实际业务中,调用边度文心一言的接口中加了缓存处理,保持5s内企业微信调用我们后台获取消息一定会有内容响应。

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/524785
推荐阅读
相关标签
  

闽ICP备14008679号