PC端从零搭建微信自动回复机器人(一)基础框架搭建及源码

由于工作需要,最近一年一直在研究和使用C#,加上最近工作上有做微信机器人的需要,在已经对接、调试稳定之后,将项目的源码分享给大家,传递开源精神。

一、环境依赖

1、开发工具:Vistual Studio 2022
2、NetFramework版本:6.0及以上
3、微信版本:WeChatSetup_3.7.0.30.exe (找不到可以私信我)

二、支持功能

目前该组件自身支持很多功能,如下所示:

  • 获取通讯录
  • 获取所有群成员基础信息(含wxid,群昵称,微信昵称)
  • 发送文本、图片、文件、xml文章、名片、群艾特消息
  • 根据wxid查询好友信息
  • 根据群ID获取所有群成员WXID / 同时获取一个微信群内所有成员的群昵称
  • 检测好友状态(是否好友、被删除、被拉黑)
  • 接收各类消息,可写回调函数进行处理
  • 群管理
  • 微信多开
  • 自动合并短的文本、艾特信息(可设定单条信息最大长度)
  • 自动分割过长的单条信息

在这些功能的基础上我们可以结合自身的使用场景进行定制化开发和调用。目前我主要根据群聊中@和私聊这两个场景进行一些封装,我将代码进行了删减,仅保留基础部分。

三、项目结构及如何运行

1、项目结构

项目整体有三个部分构成。如下图所示:
在这里插入图片描述
ConsoleApp1用于自定义逻辑和启动类都写在中。–自行创建
RS.Snail.JJJ.Wechat是底层依赖组件。–可参考我上传的附件
Segments是自带中文分词器的一个组件,用于对用户问题与问题列表进行分词匹配。–下篇文章详解

2、自定义逻辑实现

启动类实现代码 Program.cs 代码如下

// See https://aka.ms/new-console-template for more information
using ConsoleApp1;
using Newtonsoft.Json.Linq;
using RS.Snail.JJJ.Wechat;
using static ConsoleApp1.MessageHandler;Console.WriteLine("Hello, World!");
var wechat = new RS.Snail.JJJ.Wechat.Service();
String mSelf_WXID = "wxid_m2khoia398xh22";//登录
bool v = wechat.Init(// new List<string> { "wxid_1234_" },new List<string> { mSelf_WXID },new Func<dynamic, Task>((msg) => {Console.Write(msg);;//CDATA[,wxid_8qfg0x0do56t22MessageParam mMessageParam = new MessageParam(mSelf_WXID,wechat, (JObject)msg);         if (mMessageParam.isAtSelf())//判断是否是群聊@微信机器人{List<String> atPersons = mMessageParam.getAtList();String mTemp = ((JObject)msg).GetValue("message").ToString();foreach (String mItem in atPersons) {String mOld = "@" + wechat.ChatroomGetMemberNick(mSelf_WXID, ((JObject)msg).GetValue("sender").ToString(), mItem);mTemp = mTemp.Replace("@微信客服", "").Trim();//注意,这里需要与自身微信昵称保持一致}ThreadParam mThreadParam = new ThreadParam() {ObjParam = wechat,Msg=msg, MTemp=mTemp, Self_WXID=mSelf_WXID};new Thread(new ParameterizedThreadStart((Obj) =>{new MessageHandler().sendAnswer((ThreadParam)Obj);})).Start(mThreadParam);}else {String mTemp = ((JObject)msg).GetValue("message").ToString();List<String> atPersons = mMessageParam.getAtList();ThreadParam mThreadParam = new ThreadParam(){ObjParam = wechat,Msg = msg,MTemp = mTemp,Self_WXID = mSelf_WXID};new Thread(new ParameterizedThreadStart((Obj) =>{new MessageHandler().transferAnser((ThreadParam)Obj);})).Start(mThreadParam);}return new Task(new Action(() => {}));})//msg =>  Console.Write(msg)) ;
//图片保存钩子
//wechat.MsgStartImageHook(mSelf_WXID, "D:\\image");wechat.StartReceive();
Console.ReadKey();
Console.ReadKey();
Console.ReadKey();
Console.ReadKey();
Console.ReadKey();
Console.ReadKey();
Console.ReadKey();
Console.ReadKey();
Console.ReadKey();

自定义问答逻辑类MessageParam.cs 代码如下:


using JiebaNet.Segmenter.PosSeg;
using Newtonsoft.Json.Linq;
using RS.Snail.JJJ.Wechat;
using System.Diagnostics;
using System.Text;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Segments;namespace ConsoleApp1
{public class MessageParam{private RS.Snail.JJJ.Wechat.Service wechat;private JObject msg;private String self_WXID;public Service Wechat { get => wechat; set => wechat = value; }public JObject Msg { get => msg; set => msg = value; }public string Self_WXID { get => self_WXID; set => self_WXID = value; }public MessageParam(String self_WXID, RS.Snail.JJJ.Wechat.Service wechat, JObject msg) {this.self_WXID = self_WXID;this.wechat= wechat;this.msg = msg;}public bool isAtSelf() {String mextrainfo = ((JObject)msg).GetValue("message").ToString();if (mextrainfo.Contains("@微信客服"))//注意,这里需要与自身微信昵称保持一致{return true;}else {return false;}}public List<String> getAtList() {String mextrainfo = ((JObject)msg).GetValue("extrainfo").ToString();List<String> mStrs = new List<String>();try{mStrs = mextrainfo.Split(new String[] { "<atuserlist><![CDATA[", "]]></atuserlist>" }, StringSplitOptions.None)[1].Split(",").ToList();}catch (Exception ex) {mStrs = new List<String>();}try{if (mStrs.Count == 0) {mStrs = mextrainfo.Split(new String[] { "<atuserlist>", "</atuserlist>" }, StringSplitOptions.None)[1].Split(",").ToList();}}catch (Exception ex){mStrs = new List<String>();}return mStrs;}}public  class MessageHandler{public void sendAnswer(ThreadParam mThreadParam){Object Obj = mThreadParam.ObjParam;String mSelf_WXID = mThreadParam.Self_WXID;Object msg = mThreadParam.Msg;String mTemp = mThreadParam.MTemp.Replace("@智能客服", "").Trim();//注意,这里需要与自身微信昵称保持一致String roomName = getChatRoomName(mSelf_WXID, Obj, msg);String roomId = ((JObject)msg).GetValue("sender").ToString();Service wechat = (Service)Obj;String sendStr = "";String similarity = "1";if (mTemp.Equals("智能客服")|| mTemp.Trim().Equals("")){sendStr = "@" + wechat.ChatroomGetMemberNick(mSelf_WXID, ((JObject)msg).GetValue("sender").ToString(),((JObject)msg).GetValue("wxid").ToString()) + "您好,我是微信客服。有什么问题可以直接向我提问哦~ 提问方式请参考下方模板\r\n【常见问题搜索】请输入报错码/错误关键字,例如:96000322/系统异常,请您稍后再试\r\n";((Service)Obj).MsgSendAt(mSelf_WXID,((JObject)msg).GetValue("sender").ToString(),new List<string> { ((JObject)msg).GetValue("wxid").ToString() },sendStr, false);}else{//调用分词匹配进行初筛List<JObject> resList = Segments.Segments.selectQuestion(mTemp,CommonUtils.parseErrorList());similarity = resList.Count.ToString();//调用搜索接口//List<JObject> resList = CommonUtils.QueryMsg(mTemp);if (resList.Count == 0)//未查询到答案信息{sendStr = "@" + wechat.ChatroomGetMemberNick(mSelf_WXID, ((JObject)msg).GetValue("sender").ToString(),((JObject)msg).GetValue("wxid").ToString()) + " 您发送了:" + mTemp + ",未找到相应答案,请用报错码/报错信息直接进行提问。或者@群内技术推广老师进行咨询";((Service)Obj).MsgSendAt(mSelf_WXID,((JObject)msg).GetValue("sender").ToString(),new List<string> { ((JObject)msg).GetValue("wxid").ToString() },sendStr, false);}else{StringBuilder sb = new StringBuilder();sb.AppendLine( " 您发送了:" + mTemp + ",为您匹配到了:" + resList.Count + "条解答,详情如下:");List<JObject> imgList = new List<JObject>();for (int i = 0; i < resList.Count; i++){String errorDetail = resList[i]["errorDetail"].ToString();String isImg = resList[i]["isImg"].ToString();String errorType = CommonUtils.getErrorType(resList[i]["errorType"].ToString());//如果isImg为1,则下载并发送图片if (isImg.Equals("1")){imgList.Add(resList[i]);}else{String solution = resList[i]["errorSolution"].ToString();String errorCode = resList[i]["errorCode"].ToString();sb.AppendLine("错误码:"+errorCode);sb.AppendLine("错误类型:"+ errorType);sb.AppendLine("错误描述:"+ errorDetail);sb.AppendLine("解决方案:"+ solution);sb.AppendLine("=====================");}}sendStr = "@" + wechat.ChatroomGetMemberNick(mSelf_WXID, ((JObject)msg).GetValue("sender").ToString(),((JObject)msg).GetValue("wxid").ToString()) + sb.ToString();((Service)Obj).MsgSendAt(mSelf_WXID,((JObject)msg).GetValue("sender").ToString(),new List<string> { ((JObject)msg).GetValue("wxid").ToString() },sendStr, false);}}}//   查询群名称public String getChatRoomName(String mSelf_WXID,Object Obj,Object msg){//获取数据库句柄JArray obj = ((Service)Obj).DatabaseGetHandles(mSelf_WXID);//查询群名称String sql = "select NickName from Contact where UserName = '" + ((JObject)msg).GetValue("sender").ToString() + "'";JObject first = obj.First() as JObject;obj = ((Service)Obj).DatabaseQuery(mSelf_WXID, (uint)first["handle"], sql);return obj[1][0].ToString();}public void transferAnser(ThreadParam mThreadParam){//自定义逻辑            }}public class ThreadParam {Object mObj; String self_WXID;Object msg;String mTemp;public object ObjParam { get => mObj; set => mObj = value; }public string Self_WXID { get => self_WXID; set => self_WXID = value; }public object Msg { get => msg; set => msg = value; }public string MTemp { get => mTemp; set => mTemp = value; }}}

CommonUtils.cs由于都是一些发送http请求的方法,就不放源码了,大家自行实现。

3、项目启动演示

首先需要配置启动项,我们需要将ConsoleApp1配置为启动项。
在这里插入图片描述
启动项目后会自动打开一个控制台,同时唤醒微信客户端。在这里插入图片描述
需要扫码登录后,在控制台中输入大写的Y,即可完成登录。
这里由于我的微信自动升级了版本,就不演示了。
当你在群聊中@微信机器人时,就会按照代码中的实现逻辑自动回复你了。这其中的语料库可以自己通过查库,本地读取,或者直接接入目前主流的各类大语言模型(chatGPT,文心一言,通义千问,科大星火等等),发挥自己的想象力,尽情的尝试吧。
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是自动化测试po模式,po分层如何实现?

一、什么是PO模式 全称&#xff1a;page object model 简称&#xff1a;POM/PO PO模式最核心的思想是分层&#xff0c;实现松耦合&#xff01;实现脚本重复使用&#xff0c;实现脚本易维护性&#xff01; 主要分三层&#xff1a; 1.基础层BasePage&#xff1a;封装一些最基…

SpectralGPT: Spectral Foundation Model 论文翻译1

遥感领域的通用大模型 2023.11.13在CVPR发表 原文地址&#xff1a;[2311.07113] SpectralGPT: Spectral Foundation Model (arxiv.org) 摘要 ​ 基础模型最近引起了人们的极大关注&#xff0c;因为它有可能以一种自我监督的方式彻底改变视觉表征学习领域。虽然大多数基础模型…

云端导览,数字互动 | 拓世法宝AI数字人一体机助力全新旅游时代

《中国旅行消费趋势洞察白皮书&#xff08;2023版&#xff09;》显示&#xff0c;消费者旅行习惯已从“到此一游”变为“深度在地”&#xff0c;更强调在旅游中充实自我、学习新知识。 &#xff08;《中国旅行消费趋势洞察白皮书&#xff08;2023版》截图&#xff09; 从这些资…

【腾讯云 TDSQL-C Serverless 产品测评】深度实测TDSQL-C Serverless 弹性伸缩策略及稳定性

文章目录 前言一、什么是 TDSQL-C Serverless二、TDSQL-C Serverless 的弹性伸缩方案三、弹性伸缩策略及稳定性实测1.测试设计2.测试流程&#xff1a;3.测试准备工作4.开始测试5.测试结果分析5.1.整体过程分析5.2.扩容过程分析5.3.缩容过程分析 四、总结 前言 Serverless 数据…

小白也能看得懂的Jmeter性能测试中服务端资源监控技术

操作步骤&#xff1a; 1、安装插件管理器 插件管理器的作用&#xff1a;可以提供扩展插件的在线安装升级和卸载。因为我们需要在线安装监控插件&#xff0c;首先我们就要先安装插件管理器。 插件管理器的下载地址&#xff1a;https://jmeter-plugins.org/install/Install/ 如…

关于鸿蒙网络请求的问题

https://developer.huawei.com/consumer/cn/forum/topic/0204136145853212268?fid0102683795438680754 鸿蒙OS 代码 import http from ohos.net.http;export const httpUtils (url: string, data: any) > {return new Promise((resolve, reject) > {let httpRequest …

【黑马甄选离线数仓day05_核销主题域开发】

1. 指标分类 ​ 通过沟通调研&#xff0c;把需求进行分析、抽象和总结&#xff0c;整理成指标列表。指标有原子指标、派生指标、 衍生指标三种类型。 ​ 原子指标基于某一业务过程的度量值&#xff0c;是业务定义中不可再拆解的指标&#xff0c;原子指标的核心功能就是对指标…

03:2440--UART

目录 一:UART 1:概念 2:工作模式 3:逻辑电平 4:串口结构图 5:时间的计算 二:寄存器 1:简单的UART传输数据 A:GPHCON--配置引脚 B:GPHUP----使能内部上拉​编辑 C: UCON0---设置频率115200 D: ULCON0----数据格式8n1 E:发送数据 A:UTRSTAT0 B:UTXHO--发送数据输…

VCenter连接主机提示:未验证主机SSL证书的真实性

问题&#xff1a;VCenter主机断开连接了&#xff0c;重新连接主机报错SSL证书问题 移除重新加入ESXI6.0节点报错常规系统错误&#xff08;如下图&#xff09; 解决方案&#xff1a;需更改一下验证方式 VCenter Serevr设置→高级设置 将项cpxd.certmgmt.mode 值 vmca 改为&…

linux嵌入式时区问题

目录 操作说明实验参考 最近有个针对时区的需求&#xff0c;研究了下。 查询网上的一些设置&#xff0c;发现基本都是系统中自带的一些文件&#xff0c;然后开机时解析&#xff0c;或者是有个修改的命令。 操作 但针对嵌入式常用到的 busybox 制作的最小系统&#xff0c;并没…

N-134基于java实现捕鱼达人游戏

开发工具eclipse,jdk1.8 文档截图&#xff1a; package com.qd.fish;import java.awt.Graphics; import java.io.File; import java.util.ArrayList; import java.util.List;import javax.imageio.ImageIO;public class Fishes {//定义一个集合来管理鱼List<Fish> fish…

76. 最小覆盖子串 (滑动窗口)

Problem: 76. 最小覆盖子串 文章目录 思路相似滑动窗口题目 :Code 题目 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串 “” 。 注意&#xff1a; 对于 t 中重复字符&#xff0c;我…