基于FlaUI自动化+chatGPT实现微信自动回复

news2024/12/26 23:51:43

先看效果图

本次主要介绍如何实现自动回复:

1.将文件传输助手置顶,模拟鼠标点击文件传输助手;

2.一直刷新会话列表,有新的消息就需要回复内容;

3.当刷新到新的消息时,模拟鼠标点击到对应的会话人,此时判断是群聊还是人,如果是群聊则不回复。

4.获取消息后转发给chatGPT,同时等待chatGPT回复内容。

5.获取chatGPT的内容后将内容输入到微信聊天框,并模拟鼠标点击发送按钮。

6.模拟鼠标点击文件传输助手,等待其它消息。。。。

获取聊天消息并发送

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);
    }

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

擦除信道(erasure channel)

定义 二进制擦除通道&#xff08;BEC&#xff09;是一种信道模型。发送端发送一个比特&#xff08;0或1&#xff09;&#xff0c;接收端要么正确接收该比特&#xff08;0或1&#xff09;&#xff0c;要么以概率 P e P_{e} Pe​接收到该比特没有被接收的信息&#xff08;即“擦除…

公司电脑文件数据透明加密、防泄密系统

一套利用驱动层透明加密技术实现电子文件安全加密的防护产品&#xff0c;从源头上保障数据安全和使用安全的加密系统。该系统遵循基于文件生命周期安全防护的思想&#xff0c;集成了密码学、访问控制和审计跟踪等技术手段&#xff0c;对企事业单位电子文件的存储、访问、传播和…

【UE 材质】实现角度渐变材质、棋盘纹理材质

目标 步骤 一、角度渐变材质 1. 首先通过“Mask”节点将"Texture Coordinate" 节点的R、G通道分离 2. 通过“RemapValueRange”节点将0~1范围映射到-1~1 可以看到此时R通道效果&#xff1a; G通道效果&#xff1a; 继续补充如下节点 二、棋盘纹理材质 原视频链接&…

Docker(三) 创建Docker镜像

一、在Docker中拉取最基本的Ubuntu系统镜像 搜索Ubuntu镜像 Explore Dockers Container Image Repository | Docker Hub 下载镜像 docker pull ubuntu:22.04 二、在镜像中添加自己的内容 使用ubuntu镜像创建容器 docker run -it ubuntu:20.04 /bin/bash 在容器中创建了一个文…

成集云 | 多维表格自动化管理jira Server项目 | 解决方案

源系统成集云目标系统 方案介绍 基于成集云集成平台&#xff0c;在多维表格中的需求任务信息自动创建、更新同步至 Jira Server 的指定项目中&#xff0c;实现多维表格中一表管理 Jira Server 中的项目进度。 维格表是一种新一代的团队数据协作和项目管理工具&…

day-01 Docker

一、docker简介 Docker 是一种开源的容器化平台&#xff0c;它可以帮助开发人员将应用程序及其依赖项打包成一个独立的、可移植的容器&#xff0c;而无需担心环境差异和依赖问题。通过使用 Docker&#xff0c;您可以更轻松地创建、分发和运行应用程序&#xff0c;无论是在开发、…

Apipost: 开发者们的瑞士军刀

在当今的数字化时代&#xff0c;数据流通是推动社会进步的关键因素之一。其中&#xff0c;API&#xff08;应用编程接口&#xff09;已经成为跨平台数据交互的标准。然而&#xff0c;API开发和管理并非易事&#xff0c;Apipost一体化研发协作赋能平台&#xff0c;支持从API设计…

并发编程(四)---死锁 synchronized、volatile详解

一.关键字 1.synchronized关键字&#xff1a; a.重量级锁&#xff0c;功能完整的锁 b.修饰类、方法、静态方法、代码块&#xff0c;但不可以在声明的时候修饰 c.synchronized是实现同步的基础&#xff0c;Java中不管是对象还是方法&#xff0c;都可加上锁。synchronized分为三…

音频应用编程

目录 ALSA 概述alsa-lib 简介sound 设备节点alsa-lib 移植编写一个简单地alsa-lib 应用程序一些基本概念打开PCM 设备设置硬件参数 ALPHA I.MX6U 开发板支持音频&#xff0c;板上搭载了音频编解码芯片WM8960&#xff0c;支持播放以及录音功能&#xff01; 本章我们来学习Linux …

探索散列表和哈希表:高效存储与快速检索的魔法

文章目录 散列函数的原理散列表和哈希表的概念与操作解决冲突的方法案例分析&#xff1a;电话簿的实现拓展&#xff1a;性能与碰撞结论 &#x1f389;欢迎来到数据结构学习专栏~探索散列表和哈希表&#xff1a;高效存储与快速检索的魔法 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒&#…

【模拟集成电路】反馈系统加载效应——基础到进阶(三)

【模拟集成电路】反馈系统加载效应——基础到进阶&#xff08;三&#xff09; -----------------------文末附往期文章链接-------------------- 1.概述2.二端口网络方法2.1二端口网络模型2.2电压-电压反馈的加载2.2电流-电压反馈的加载2.3电压-电流反馈的加载2.4电流-电流反馈…

一文速学-让神经网络不再神秘,一天速学神经网络基础-输出层(四)

前言 思索了很久到底要不要出深度学习内容&#xff0c;毕竟在数学建模专栏里边的机器学习内容还有一大半算法没有更新&#xff0c;很多坑都没有填满&#xff0c;而且现在深度学习的文章和学习课程都十分的多&#xff0c;我考虑了很久决定还是得出神经网络系列文章&#xff0c;不…

Flutter 混合开发调试

针对Flutter开发的同学来说&#xff0c;大部分的应用还是Native Flutter的混合开发&#xff0c;所以每次改完Flutter代码&#xff0c;运行整个项目无疑是很费时间的。所以Flutter官方也给我们提供了混合调试的方案【在混合开发模式下进行调试】&#xff0c;这里以Android Stud…

Python基础学习第四天:Python注释

创建注释 注释以 &#xff03; 开头&#xff0c;Python 将忽略它们&#xff1a; 实例 #This is a comment print("Hello, World!")运行实例 注释可以放在一行的末尾&#xff0c;Python 将忽略该行的其余部分&#xff1a; 实例 print("Hello, World!")…

1-8 隐语小课|私有信息检索(PIR)及其应用场景

“隐语”是开源的可信隐私计算框架&#xff0c;内置 MPC、TEE、同态等多种密态计算虚拟设备供灵活选择&#xff0c;提供丰富的联邦学习算法和差分隐私机制 开源项目 github.com/secretflow gitee.com/secretflow 前言 欢迎来到小剧场全新系列节目「隐语小课」&#xff01;本…

Run the Docker daemon as a non-root user (Rootless mode)

rootless 简介 rootless模式是指以非root用户身份运行Docker守护程序和容器。那么为什么要有rootless mode呢&#xff1f;因为在root用户下安装启动的容器存在安全问题。存在的安全问题具体来说是容器内的root用户就是宿主机的root用户&#xff0c;容器内uid1000的用户就是宿主…

csp认证真题——重复局面——Java题解

目录 题目背景 问题描述 输入格式 输出格式 样例输入 样例输出 样例说明 子任务 提示 【思路解析】 【代码实现】 题目背景 国际象棋在对局时&#xff0c;同一局面连续或间断出现3次或3次以上&#xff0c;可由任意一方提出和棋。 问题描述 国际象棋每一个局面可以…

vscode 清除全部的console.log

在放页面的大文件夹view上面右键点击在文件夹中查找 console.log.*$ 注意&#xff1a;要选择使用正则匹配 替换为 " " (空字符串)