Awesome: Use C#to combine FlaUI and chatGPT to achieve WeChat AI Q & A

Awesome: Use C#to combine FlaUI and chatGPT to achieve WeChat AI Q & A

Automatic WeChat reply based on FlaUI Automation +chatGPT

最后更新 8/30/2023 7:57 PM
且听风吟
预计阅读 8 分钟
分类
.NET
标签
.NET C# AI

This article was submitted by netizens

Author: Listen to the wind

Original title: Automatic WeChat reply based on FlaUI automation + chatGPT

Original link: https://www.example.com

1. Look at the renderings first

    • Get WeChat friends list **

    • Automatic question and answer effect **

2. This article implements functions

This time we mainly introduce how to achieve automatic reply:

  1. Place the File Transfer Assistant at the top and simulate the mouse clicking on the File Transfer Assistant;

  2. Keep refreshing the session list, and you need to reply to new messages;

  3. When a new message is refreshed, the mouse is simulated to click on the corresponding conversation person. At this time, it is determined whether it is Group chats or people. If it is Group chats, no reply will be given.

  4. Get the message and forward it to chatGPT, while waiting for chatGPT to reply.

  5. After obtaining the content of chatGPT, enter the content into the WeChat chat box and simulate the mouse clicking on the send button.

  6. Simulate the mouse clicking on the File Transfer Assistant, waiting for other messages...

3. function code

3.1. Get chat messages and send them

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

3.2. automatic reply

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

3.3. other code

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

3.4. extension method

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);
     }
}
    • Note: ChatAchieve is an implementation of IChat, an implementation of chatGPT **
public interface IChat
{
     Action<string> RequestContent { get; set; }
     void RequestGPT(string content);
}

The author is lazy and unwilling to put the code in the warehouse. The source code is directly lost to the webmaster. You need to directly click to download it: https://www.example.com

Add QQ group for technical exchanges: 771992300

Or scan the webmaster's WeChat (codewf, note "add group ") to join the WeChat technical exchange group:

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 1/5/2026

A 2025 summary for all. NET developers

I believe you have seen many articles like "Sorry, C#has fallen out of the top echelon" this year. What is the. NET ecosystem? This article will systematically sort out the technology trends and important events that. NET developers should pay attention to most in 2025, covering the latest developments and trends in AI development,. NET evolution and the integration of the two, in order to help everyone find the right position and meet future challenges and opportunities.

继续阅读
同分类 / 同标签 11/17/2023

NET8 officially released, new changes in C #12

Although 8 has brought many enhancements, such as artificial intelligence, cloud native, performance, native AOT, etc., I am still most concerned about the C#language and some framework-level changes. Here are some new features in C#12 and the framework that I think are more practical.

继续阅读