C#监听QQ消息自动回复-QQ自动化

news2024/11/20 21:27:12

整理 | 小耕家的喵大仙

出品 | CSDN(ID:lichao19897314)

Q Q | 978124155

关于项目背景和微信自动化学习介绍

   因为前面写了很多关于微信自动化的文章,网上有一位网友说他是做培训行业的,有时候除了微信对接客户还需要通过QQ来做日常的回复工作,因为很多回复是重复性,他想实现监听QQ消息并自动回复文字内容和文件的功能。该篇博客记录了实现QQ自动回复的整体实现逻辑和技术细节

如果有兴趣的朋友可以看下我微信自动化的文章!因为底层实现和微信自动化同根同源,感兴趣的点个赞关注支持下原创。

(1)微信UI自动化-篇章开启(C#)

(2)微信UI自动化-微信窗体管理(C#)

(3)微信UI自动化-热键管理(C#)

(4)微信UI自动化-联系人采集(C#)

(5)微信UI自动化-实现静默鼠标点击(C#)

(6)微信UI自动化-搜索指定联系人(C#)

(7)微信UI自动化-自动发送消息给指定联系人(C#)(.Net)

(8)微信UI自动化-监控微信进程运行状态(C#)

(9)微信UI自动化-监控微信网络状态(C#)

(10)微信UI自动化-跟随微信窗口移动(C#)

(11)微信UI自动化-微信窗口跟随主窗体移动(C#)

(12)PC端微信自动化测试-C#采集微信聊天记录

(13)PC端微信自动化UI-C#监听微信消息自动回复

(14)微信自动化测试-针对微信控件元素截图操作

(15)微信自动化测试-针对微信主窗体的行为控制

(16)微信自动化测试-C#控制微信多开

  • QQ版本以及软件功能效果

采用的QQ版本为当前最新版本QQ👇

QQ监听消息并自动回复的效果视频呈现

QQ监听消息自动回复

 实时监听最新消息并根据消息内容给指定联系人做回复(包括回复文本和文件)

  • 技术实现思路和示例代码 

  1. 找到QQ主窗体句柄和QQ进程ID,通过QQ进程ID构建UIA3Automation的自动化测试实例。
  2. 构建针对QQ自动化测试实例成功后,我们创建一个后台监听任务,监听QQ主窗体的消息面板。监听任务判断消息面板中的UI对象中的内容是否有修改,如果有修改则判断为新消息。
  3. 因为本次程序是针对特定群和特定联系人的自动回复,所以需要将特定群或者联系人的聊天窗口平铺打开。请像如下打开需要监听的联系人聊天窗口
  4. 通过监听任务获取到的新消息内容和消息发送人,通过UI自动化实例对象找到与对应联系人的聊天窗口。
  5. 找到对应的聊天窗口的编辑框和发送按钮的UI对象实例。
  6. 通过监听到的消息内容产生我们自己需要回复的智能化业务内容,并通过剪贴版本的方式复制到聊天窗口的编辑框中,执行发送按钮的点击事件,完成发送,并将新消息内容设为以处理。

核心示例代码 

加载QQ主窗体并构建自动化测试实例

 public bool Load()
 {
     int weChatID = 0;

     IntPtr hwnd = FindWindow(null, "QQ");

     if (hwnd != IntPtr.Zero)
     {
         GetWindowThreadProcessId(hwnd, out weChatID);
     }
     else
     {
         return false;
     }

     application = FlaUI.Core.Application.Attach(weChatID);

     automation = new UIA3Automation();
 
      Window = application.GetMainWindow(automation);
      var windowSource = application.GetAllTopLevelWindows(automation);
 
     if (Window == null)
         return false;

     startPanel = string.Format("/Pane[{0}]", Window.FindAllChildren().Length-1);

     return true;
 }

监控实例对象

using FlaUI.WinForm.UIAuto.Business.WX.Task.Base;
using FlaUI.WinForm.UIAuto.Model;
using OnlineRetailers.Extension.Page.UIAuto;
using OnlineRetailers.Extension.Page.UIAuto.Log;
using OnlineRetailers.Extension.Page.UIAuto.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FlaUI.WinForm.UIAuto.Business.WX.Task
{

    public class UI_Real_Reply_Task : UI_QQ_Element_Base_Task
    {
        private List<QQRealMsgEntity> historyMessageSource { get;   set; }

        /// <summary>
        /// 自动回复内容
        /// </summary>
        public string ReplyMessage { get; set; }

        /// <summary>
        /// 自动回复文件的文件路径
        /// </summary>
        public string FilePath { get; set; }

        /// <summary>
        /// 需要自动回复的用户
        /// </summary>
        public List<string> ReplyUser { get; set; }

        public override void Stop()
        {
            base.Stop();
        }
        public override void Start()
        {
            if (State == TaskState.Stop)
            {
                State = TaskState.Runing;
            }
            else 
            {
                return;
            }
            Thread th = new Thread(new ThreadStart(() =>
            {
                while (State == TaskState.Runing)
                {
                    var currentChatList = UI_QQ_Window.Current.Find("主窗体消息面板UI");
                    if (currentChatList == null || currentChatList.ControlType != FlaUI.Core.Definitions.ControlType.Pane)
                    {
                        Thread.Sleep(1000);
                        continue;
                    }
                    var source = currentChatList.FindAllChildren();
                    var tempMessageSource = new List<QQRealMsgEntity>();
                    source.ToList().ForEach(item =>
                    {
                        if (item.ControlType == FlaUI.Core.Definitions.ControlType.ListItem)
                        {
                            var buttonName = item .Name;
                            var lastMessage = item.Patterns.Value.PatternOrDefault?.Value;
                            var messageitem = new QQRealMsgEntity { UserName = buttonName,  CurrentMessage = lastMessage    };
                            tempMessageSource.Add(messageitem);

                            if (historyMessageSource != null)
                            {
                                var cnt = historyMessageSource.Count(s => s.UserName == messageitem.UserName && messageitem.CurrentMessage == s.CurrentMessage);
                                if (cnt == 0)
                                {
                                    //有新消息
                                    SetMessage(messageitem.UserName + "发送给新消息你:" + messageitem.CurrentMessage);
                                    if (ReplyUser.Count(ss => ss.Contains(messageitem.UserName)) > 0 )
                                    {
                                        if (!string.IsNullOrEmpty(FilePath))
                                        {
                                            if ( 
											!messageitem.CurrentMessage.Contains("对方已成功接收了你发送的离线文件")
											 && !messageitem.CurrentMessage.Contains("[图片文件]")
                                            &&  !messageitem.CurrentMessage.Contains("已成功保存至文件助手"))//正对自己发送的图片文件不采取回复,有可能发送文件
                                            {
                                                if ( SendQQFile(messageitem.UserName, FilePath))
                                                {
                                                    SetMessage("自动回复文本消息给" + messageitem.UserName + ":" + ReplyMessage);
                                                    //var fileName = System.IO.Path.GetFileName(FilePath);
                                                }
                                            }
                                        }
                                        if (!string.IsNullOrEmpty(ReplyMessage))
                                        {
                                            if ( SendQQText(messageitem.UserName, ReplyMessage))
                                            {
                                                SetMessage("自动回复文件消息给" + messageitem.UserName + ":" + ReplyMessage);
                                                messageitem.CurrentMessage = ReplyMessage;
                                            }
                                        }
                                       
                                    }
                                }
                            }
                        }
                    });

                    historyMessageSource = tempMessageSource;
                    Thread.Sleep(500);
                }
            }));
            th.Start();
            base.Start();
        }
        public bool SendQQText(string name, string message)
        {
            return SendQQMessage(name, new QQMessageEntity { Info = message, Type = QQMessageType.Text });
        }

        public bool SendQQFile(string name, string filePath) {
           
            return SendQQMessage(name, new QQMessageEntity { Info = filePath, Type = QQMessageType.File });
        }

        public bool SendQQMessage(string name, QQMessageEntity message) {

            //查找窗体
            var currentChatWindow = UI_QQ_Window.Current.GetCurrentChatWindow(name);
            if (currentChatWindow != null)
            {

                var SendInput = currentChatWindow.FindFirstByXPath("聊天窗体编辑框");// GetSendInput();
                var SendButton = currentChatWindow.FindFirstByXPath("聊天窗体发送按钮");// GetSendInput();

                if (SendInput == null)
                {
                    SystemLog.Error("【" + name + "】窗体下未找到输入框,发送信息失败");
                }
                if (SendButton == null)
                {
                    SystemLog.Error("【" + name + "】窗体下未找到发送按钮,发送信息失败");
                }
                currentChatWindow.Focus();

                SetText(message, SendInput, false);
				
				UI_QQ_Window.Current.ClickElement(SendButton, currentChatWindow);
               
                SystemLog.Info("向【" + name + "】窗体发送信息" + message.Info + "成功");

                return true;
            }
            else
            {
                SystemLog.Error("【" + name + "】窗体未找到,发送信息失败");
            }

            return false;
        }
    }
}

以上是核心组件及代码思路,因为代码关联类比较多,无法在本篇全部博客呈现!如果需要源码请加本人QQ 978124155

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

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

相关文章

在Vue中如何动态绑定class和style属性

在Vue中&#xff0c;动态绑定class和style属性是我们经常遇到的需求。这个功能允许我们根据不同的条件来动态改变元素的样式&#xff0c;让我们的应用更加灵活和富有交互性。在本篇博客文章中&#xff0c;我将带你深入探索在Vue中如何实现这一功能。 首先&#xff0c;让我们了…

C语言内存函数:memcpy、memcat、memmove介绍和模拟实现(实用性高,建议三连收藏)

目录 1.memcpy函数 1.1函数介绍 1.2函数示范使用 1.3函数的模拟实现 1.4补充 2.memmove函数 2.1函数介绍 2.2函数的使用示范 2.3函数的模拟实现 3.memcmp(内存比较函数&#xff09; 3.1函数介绍 3.2函数的示范使用&#xff0c;有趣的例子 4.函数补充memset(内存…

SpringSecurity(18)——OAuth2授权码管理

AuthorizationCodeServices public interface AuthorizationCodeServices {//为指定的身份验证创建授权代码。String createAuthorizationCode(OAuth2Authentication authentication);//使用授权码。OAuth2Authentication consumeAuthorizationCode(String code)throws Invali…

探索设计模式的魅力:外观模式简化术-隐藏复杂性,提供简洁接口的设计秘密

设计模式专栏&#xff1a;http://t.csdnimg.cn/U54zu 目录 引言&#xff1a;探索简化之路 一、起源和演变 二、场景案例分析 2.1 不用模式实现&#xff1a;用一坨坨代码实现 2.2 问题 2.3 外观模式重构代码 定义 界面 接口 利用外观模式解决问题步骤 外观模式结构和说明 重构…

C语言——Q/编译和链接

目录 一、翻译环境和运⾏环境 二、翻译环境 1、预处理&#xff08;预编译&#xff09; 2、编译 2.2.1 词法分析&#xff1a; 2.2.2 语法分析 2.2.3 语义分析 3、汇编 4、链接 三、运行环境 一、翻译环境和运行环境 在ANSI C 的任何⼀种实现中&#xff0c;存在两个不…

哪种安全数据交换系统,可以满足信创环境要求?

安全数据交换系统是一种专门设计用于在不同网络环境之间安全传输数据的技术解决方案。这类系统确保数据在传输过程中的完整性、机密性和可用性&#xff0c;同时遵守相关的数据保护法规和行业标准。 使用安全数据交换系统的原因主要包括以下几点&#xff1a; 1、数据保护&#…

PHP安装后错误处理

一&#xff1a;问题 安装PHP后提示错误如下 二&#xff1a;解决 1&#xff1a;Warning: Module mysqli already loaded in Unknown on line 0解决 原因&#xff1a;通过php.ini配置文件开启mysqli扩展的时候&#xff0c;开启了多次 解决&#xff1a;将php.ini配置文件中多个…

Vue3开发环境搭建和工程结构(一)

一、NVM和Node.js安装 NVM 是 Node Version Manager&#xff08;Node 版本管理工具&#xff09;的缩写&#xff0c;是一个命令行工具&#xff0c;用于管理和切换到不同版本的 Node.js。 1、前往 nvm-windows 仓库&#xff0c;然后单击立即下载 2、下载最新版本 3 、按照安装向…

MMLAB的实例分割算法mmsegmentation

当谈及实例分割时&#xff0c;人们往往只会提到一些早期的经典算法&#xff0c;比如 PSP-Net、DeepLabv3、DeepLabv3 和 U-Net。然而&#xff0c;实例分割领域已经在过去的五六年中蓬勃发展&#xff0c;涌现出许多新的算法。今天&#xff0c;让我们一起探索这个算法库&#xff…

基于单片机的智能寻光小车设计

摘 要&#xff1a;随着物联网技术的飞速发展和逐渐成熟&#xff0c;以单片机为主的智能小车在巡查、仓储、探险及国防等领域得到广泛应用。本文设计了一种基于单片机的智能寻光小车&#xff0c;该小车以STC89C52RC 芯片为设计核心&#xff0c;结合光敏传感器和超声波传感器等多…

jmeter-问题一:关于线程组,线程数,用户数详解

文章目录 jmeter参数介绍1.线程数2.准备时长(Ramp-up)3.循环次数4.same user on each iteratio5.调度器 场景一&#xff1a;当你的线程组中线程数为1,循环为1场景二&#xff1a;当你的线程组中线程数为2&#xff0c;循环为1场景三&#xff1a;当你的线程组中线程数为1&#xff…

springboot158基于springboot的医院资源管理系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

ResizeObserver的使用

这篇说下ResizeObserver API。ResizeObserver接口监视 Element 内容盒或边框盒或者 SVGElement 边界尺寸的变化。 ResizeObserver避免了通过回调函数调整大小时&#xff0c;通常创建的无限回调循环和循环依赖项。它只能通过在后续的帧中处理 DOM 中更深层次的元素来做到这一点…

sqli-labs-master靶场训练笔记(21-38|精英级)

2024.1.30 level-21 (cookie 注入数据加密) 从页面上就可以看出这次的数据被 baes64 加密了 中国有句古话&#xff1a;师夷长技以制夷 &#xff0c;用base64加密后的数据即可爆出数据 加密前&#xff1a; admin and updatexml(1,concat(~,(select database()),~),1) and …

【QT】Graphics View绘图架构

目录 1 场景、视图与图形项 1.1 场景 2.2 视图 3.3 图形项 2 GraphicsView的坐标系统 2.1 图形项坐标 2.2 视图坐标 2.3 场景坐标 2.4 坐标映射 3 GraphicsView相关的类 3.1 QGraphicsView类的主要接口函数 3.2 QGraphicsScene类的主要接口函数 3.3 图形项 4 GraphicsView程序基…

谷粒商城【成神路】-【5】——品牌管理【上】

目录 &#x1f9c8;1.新建品牌分类 &#x1f95e;2.导入前端代码 &#x1f9c2;3.页面优化 &#x1f953;4.阿里云开通oss &#x1f32d;5.文件上传 &#x1f95a;6.表单后端校验 JSR303 1.新建品牌分类 在renren-fast客户端中&#xff0c;创建二级菜单&#xff0c;…

基于CNN+LSTM深度学习网络的时间序列预测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 卷积神经网络&#xff08;CNN&#xff09; 4.2 长短时记忆网络&#xff08;LSTM&#xff09; 4.3 CNNLSTM网络结构 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MA…

微信自动预约小程序开发指南:从小白到专家

在数字化时代&#xff0c;预约小程序已成为各类服务行业的必备工具。本文将指导你从零开始&#xff0c;通过第三方小程序制作平台&#xff0c;顺利开发出一款具有预约功能的实用小程序。 第一步&#xff1a;注册登录第三方小程序制作平台 首先&#xff0c;你需要选择一个适合你…

麻雀搜索算法|Sparrow Search Algorithm(SSA)

在麻雀群体智慧、觅食和反捕食行为的启发下&#xff0c;提出了一种新的群体优化方法&#xff0c;即麻雀搜索算法&#xff08;SSA&#xff09;。 1、简介 在麻雀搜索算法中包含三种类型的麻雀个体&#xff0c;即发现者、跟随者和侦察者&#xff0c;三种类型对应三种行为。发现…

Intellij IDEA各种调试+开发中常见bug

Intellij IDEA中使用好Debug&#xff0c;主要包括如下内容&#xff1a; 一、Debug开篇 ①、以Debug模式启动服务&#xff0c;左边的一个按钮则是以Run模式启动。在开发中&#xff0c;我一般会直接启动Debug模式&#xff0c;方便随时调试代码。 ②、断点&#xff1a;在左边行…