赞
踩
本文由网友投稿
作者:且听风吟
原文标题:基于FlaUI自动化+chatGPT实现微信自动回复
原文链接:https://blog.csdn.net/ftfmatlab/article/details/132589169
获取微信好友列表
自动问答效果
本次主要介绍如何实现自动回复:
将文件传输助手置顶,模拟鼠标点击文件传输助手;
一直刷新会话列表,有新的消息就需要回复内容;
当刷新到新的消息时,模拟鼠标点击到对应的会话人,此时判断是群聊还是人,如果是群聊则不回复。
获取消息后转发给chatGPT,同时等待chatGPT回复内容。
获取chatGPT的内容后将内容输入到微信聊天框,并模拟鼠标点击发送按钮。
模拟鼠标点击文件传输助手,等待其它消息。。。。
- void GetChatInfo()
- {
- if (!IsInit)
- {
- return;
- }
- if (wxWindow == null)
- {
- return;
- }
-
- //wxWindow.FindAllDescendants(x => x.ByControlType(FlaUI.Core.Definitions.ControlType.Button)).AsParallel().FirstOrDefault(s =>s!=null && s.Name == "聊天")?.Click(false);
- wxWindow.FindFirstDescendant(cf => cf.ByName("聊天"))?.Click(false);
- Task.Run(() =>
- {
- AutomationElement? assFirst = null;
- object obj = new object();
- while (true)
- {
- if (ChatListCancellationToken.IsCancellationRequested)
- {
- break;
- }
-
- try
- {
- DateTime dateTime3 = DateTime.Now;
- var searchTextBox = wxWindow.FindFirstDescendant(cf => cf.ByName("会话")).AsListBoxItem();
-
- if (searchTextBox != null)
- {
- var list = searchTextBox.FindAllChildren();
- if (assFirst == null)
- {
- assFirst = list.AsParallel().FirstOrDefault(t => t != null && "文件传输助手".Equals(t.Name));// 并行查询---需要将文件传输助手置顶
- assFirst?.Click();
- continue;
- }
-
- Parallel.ForEach(list, item =>
- {
- if (item != null && !string.IsNullOrEmpty(item.Name) && !"折叠置顶聊天".Equals(item.Name)
- && !"腾讯新闻".Equals(item.Name) && !"群聊".Contains(item.Name))
- {
- DateTime t1= DateTime.Now;
- var allText = item.FindAllByXPath(".//Text");// 定位元素的局部搜索: .//Text; 全局搜索: //*/Text
- DateTime t2 = DateTime.Now;
- Trace.WriteLine($"allText用时:{(t2 - t1).TotalMilliseconds}ms");
- // 回复消息列表还未回复的
- if (allText != null && allText.Length >= 4)
- {
- if (int.TryParse(allText[3].Name, out var count) && count > 0)
- {
- lock (obj)
- {
- var name = allText[0].Name;
- var time = allText[1].Name;
- var content = allText[2].Name;
- if (wxWindow.Patterns.Window.PatternOrDefault != null)
- {
- //将微信窗体设置为默认焦点状态
- wxWindow.Patterns.Window.Pattern.SetWindowVisualState(FlaUI.Core.Definitions.WindowVisualState.Normal);
- }
-
- item.Click();
- DateTime t7= DateTime.Now;
- var itemFirst = wxWindow.FindAllDescendants(x => x.ByControlType(FlaUI.Core.Definitions.ControlType.Text)).AsParallel()
- .FirstOrDefault(t =>t!=null && t.Parent.ControlType == ControlType.Pane && !t.IsOffscreen && t.Name.Trim().IsSpecificNumbers());
- DateTime t8= DateTime.Now;
- Trace.WriteLine($"itemFirst:{(t8 - t7).TotalMilliseconds}ms");
- // 判断是否为群聊
- if (itemFirst == null)
- {
- AutoGetMesg(content);
- }
- assFirst?.Click();
- }
- }
- }
- }
- });
-
- DateTime dateTime4 = DateTime.Now;
- Trace.WriteLine($"任务888耗时:{(dateTime4 - dateTime3).TotalMilliseconds}ms");
- }
- else
- {
- Thread.Sleep(10);
- continue;
- }
-
- //ScrollEvent(-700);
-
- }
- catch (Exception ex)
- {
- continue;
- }
- finally
- {
- //await Task.Delay(1);
- }
- }
- }, ChatListCancellationToken);
- }

- IChat _chat;
- private void AutoGetMesg(string txt)
- {
- if (_chat == null)
- {
- _chat = new ChatAchieve();
- _chat.RequestContent = GetMessage;
- }
- Trace.WriteLine($"发送消息:{txt}");
- _chat.RequestGPT(txt);
- }
-
- private FlaUI.Core.AutomationElements.TextBox _mesText;
- public FlaUI.Core.AutomationElements.TextBox MesText
- {
- get
- {
- if (_mesText == null)
- _mesText = wxWindow.FindFirstDescendant(x => x.ByControlType(FlaUI.Core.Definitions.ControlType.Text)).AsTextBox();
-
- return _mesText;
- }
- }
- private AutomationElement? _btnSend;
- public AutomationElement? btnSend
- {
- get
- {
- if (_btnSend == null)
- {
- _btnSend = wxWindow.FindFirstDescendant(cf => cf.ByName("sendBtn"));
- //_btnSend = wxWindow.FindAllDescendants(x => x.ByControlType(FlaUI.Core.Definitions.ControlType.Button)).FirstOrDefault(s => s.Name == "发送(S)");
- }
-
- return _btnSend;
- }
- }
- const int _offSize = 300;
- private void GetMessage(string mes)
- {
- SendMes(mes);
- Trace.WriteLine($"回复:{mes}");
- }
- private void SendMes(string mes)
- {
- if (wxWindow.Patterns.Window.PatternOrDefault != null)
- {
- //将微信窗体设置为默认焦点状态
- wxWindow.Patterns.Window.Pattern.SetWindowVisualState(FlaUI.Core.Definitions.WindowVisualState.Normal);
- }
- int tempLen = 0;
- string txt = string.Empty;
- try
- {
- if (!string.IsNullOrWhiteSpace(mes))
- {
- string[] lines = mes.Split(Environment.NewLine);
-
- foreach (string line in lines)
- {
- tempLen += line.Length;
- txt += line + Environment.NewLine;
- if (tempLen > _offSize)
- {
- MesText.Text = txt;
- btnSend?.Click();
- tempLen = 0;
- txt = string.Empty;
- }
- }
- if (!string.IsNullOrWhiteSpace(txt))
- {
- MesText.Text = txt;
- Thread.Sleep(3);
- btnSend?.Click();
- }
- }
- }
- catch (Exception ex)
- {
- Trace.WriteLine(ex.Message);
- MesText.Text = txt;
- btnSend?.Click();
- }
- }

- /// <summary>
- /// 启动
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnStart_Click(object sender, EventArgs e)
- {
- InitWechat();
- }
-
- private void FrmMain_Load(object sender, EventArgs e)
- {
-
- }
-
- private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
- {
- this.Dispose();
- GC.Collect();
- }
- private CancellationToken FriendCancellationToken { get; set; }
- private CancellationTokenSource FriendTokenSource { get; set; }
- private CancellationToken ChatListCancellationToken { get; set; }
- private CancellationTokenSource ChatListTokenSource { get; set; }
- private CancellationToken GetFriendCancellationToken { get; set; }
- private CancellationTokenSource GetFriendTokenSource { get; set; }
- /// <summary>
- /// 微信的进程ID
- /// </summary>
- private int ProcessId { get; set; }
- /// <summary>
- /// 微信窗体
- /// </summary>
- private Window wxWindow { get; set; }
- private bool IsInit { get; set; }
- /// <summary>
- /// 获取
- /// </summary>
- void GetWxHandle()
- {
- var process = Process.GetProcessesByName("Wechat").FirstOrDefault();
- if (process != null)
- {
- ProcessId = process.Id;
- }
- }
- /// <summary>
- /// 加载微信
- /// </summary>
- void InitWechat()
- {
- IsInit = true;
- GetWxHandle();
- GetFriendTokenSource = new CancellationTokenSource();
- GetFriendCancellationToken = GetFriendTokenSource.Token;
- ChatListTokenSource = new CancellationTokenSource();
- ChatListCancellationToken = ChatListTokenSource.Token;
- FriendTokenSource = new CancellationTokenSource();
- FriendCancellationToken = FriendTokenSource.Token;
- //根据微信进程ID绑定FLAUI
- try
- {
- var application = FlaUI.Core.Application.Attach(ProcessId);
- var automation = new UIA3Automation();
- //获取微信window自动化操作对象
- wxWindow = application.GetMainWindow(automation);
- }
- catch (Exception ex)
- {
- if (MessageBox.Show(ex.Message, "异常", MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK)
- this.Close();
- }
-
-
- // 加载好友
- IsListenCronyList = true;
- // 加载聊天信息
- GetChatInfo();
- }
- /// <summary>
- /// 获取好友列表
- /// </summary>
- void GetFriends()
- {
- if (!IsInit)
- {
- return;
- }
- if (wxWindow == null)
- {
- return;
- }
-
- if (wxWindow.Patterns.Window.PatternOrDefault != null)
- {
- //将微信窗体设置为默认焦点状态
- wxWindow.Patterns.Window.Pattern.SetWindowVisualState(FlaUI.Core.Definitions.WindowVisualState.Normal);
- }
-
- wxWindow.FindAllDescendants(x => x.ByControlType(FlaUI.Core.Definitions.ControlType.Button)).AsParallel()
- .FirstOrDefault(item => item != null && item.Name == "通讯录")?.Click(false);
-
- string lastName = string.Empty;
- var list = new List<AutomationElement>();
- var sync = SynchronizationContext.Current;
- Task.Run(async () =>
- {
- while (true)
- {
- if (GetFriendCancellationToken.IsCancellationRequested)
- break;
- var all = wxWindow.FindAllDescendants(x => x.ByControlType(FlaUI.Core.Definitions.ControlType.ListItem));
- var allItem = all.AsParallel().Where(s => s != null && s.Parent != null && "联系人".Equals(s.Parent?.Name)).ToList();
- foreach (var item in allItem)
- {
- if (!string.IsNullOrWhiteSpace(item.Name) && !listBox1.Items.Contains(item.Name.ToString()))
- {
- sync.Post(s =>
- {
- listBox1.Items.Add(s);
- }, item.Name.ToString());
- }
-
- }
- //ScrollEvent(-700);
-
- await Task.Delay(1);
- }
- }, GetFriendCancellationToken);
- }
- /// <summary>
- /// 监听好友列表
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- private void btnListenCronyList_Click(object sender, EventArgs e)
- {
- IsListenCronyList = !IsListenCronyList;
- }
- private bool _isListenCronyList = false;
- public bool IsListenCronyList
- {
- set
- {
- if (_isListenCronyList == value)
- return;
-
- _isListenCronyList = value;
- string txt = string.Empty;
- if (value)
- {
- txt = "关闭监听好友列表";
- GetFriends();
- }
- else
- {
- txt = "开启监听好友列表";
- GetFriendTokenSource.Cancel();
- }
- btnListenCronyList.ExecBeginInvoke(() =>
- {
- btnListenCronyList.Text = txt;
- });
- }
- get => this._isListenCronyList;
- }

- internal static class SystemEx
- {
- /// <summary>
- /// 跨线程操作控件
- /// </summary>
- /// <param name="con"></param>
- /// <param name="action"></param>
- public static void ExecBeginInvoke(this Control con, Action action)
- {
- if (action == null) return;
- if (con.InvokeRequired)
- {
- con.BeginInvoke(new Action(action));
- }
- else
- {
- action();
- }
- }
- public static void ExecInvoke(this Control con, Action action)
- {
- if (action == null) return;
- if (con.InvokeRequired)
- {
- con.Invoke(new Action(action));
- }
- else
- {
- action();
- }
- }
- const string PARRERN = @"^\(\d+\)$";
- public static bool IsSpecificNumbers(this string txt)
- {
- return Regex.IsMatch(txt, PARRERN);
- }
- }

注:ChatAchieve是 IChat的实现,是对chatGPT的实现
- public interface IChat
- {
- Action<string> RequestContent { get; set; }
- void RequestGPT(string content);
- }
作者懒,不愿意将代码放仓库,源码直接丢站长了,大家需要直接点击下载:https://img1.dotnet9.com/2023/08/WeChat.Automation.zip
技术交流添加QQ群:771992300
或扫站长微信加入微信技术交流群:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。