分享本周所学——使用Python将微信转发至Windows通知中心并支持快捷回复

大家好,欢迎来到《分享本周所学》第十一期。本人是一名人工智能初学者(虽然我最近写的东西都跟人工智能没什么关系),刚刚上完大一。最近在公司实习摸鱼的时候突然觉得微信没法把消息发进Windows通知中心,特别不好用。于是就决定写一个基于wxpywin11toast的自己的微信。

这是我第一次用优快云的MD编辑器,所以可能格式和往期不太一样。

9月8日更新

我在GitHub仓库上的项目更新了,更新后的内容和这篇教程没法匹配上,所以我新建了一个叫tutorial分支,把项目的最初版本(也就是这篇文章对应的版本)放了进去。大家在阅读或学习的时候可以参考tutorial分支,如果想实际体验的话,可以用main分支上的最新版本,体验会更好。

上期文章连接

分享本周所学——在Windows上搭建自己的Git服务器并支持互联网远程访问

本期封面

text

项目安装与运行

我已经把整个项目上传到GitHub了。大家可以到我的GitHub仓库上把整个项目打包下载到本地。千万别忘先Star一下我的项目!求你了! 项目还在不断更新,以后可能会推出更多美观而且实用的功能。

安装

  1. 项目必须在Windows 11系统上运行。如果你还没有更新到Windows 11,请务必先进行更新。我使用的Windows版本是25330.1000,在其他版本的系统上也大概率能成功运行,但不能保证一定成功,毕竟我没有做过测试。
  2. 安装Python。我使用的版本是Python 3.8,其他版本上也大概率能成功运行,但不能保证一定成功,毕竟我没有做过测试。
  3. 使用以下命令来安装所依赖的包(win11toastwxpy):
pip install wxpy win11toast -i https://pypi.tuna.tsinghua.edu.cn/simple

运行

下载并解压项目文件之后,里面应该有一个叫run.bat的文件。直接双击run.bat即可运行。

使用方法

开始运行后,程序会先下载一个微信网页版的二维码。你需要先扫描二维码进行登录。登录之后,程序就会不断地将收到的微信转发到系统的通知中心。具体效果是这样的:

  • 文字信息:

在这里插入图片描述

  • 图片:

在这里插入图片描述

  • 文件:

在这里插入图片描述

是不是还挺好看的?而且和Windows的通知中心集成得非常好。你可以在“Reply to this message”那个文本框里直接输入你想回复的内容,然后点击“Send”回复。非常方便。除此之外,你也可以在run.bat开启的那个终端窗口里发送信息,下面是一个示例:

In [1]: switch_context('RFdragon') # 开始与RFdragon的聊天。

In [2]: show_context() # 显示当前聊天对象。
Current context: [RFdragon].

In [3]: send('Hello world!') # 发送文字信息“Hello world!”。

In [4]: send(r'D:\Downloads\download.zip', msg_type='file') # 发送文件。

至于这些命令具体的功能和使用方法,我会在下面代码讲解的部分提到。

代码讲解

首先我们导入需要的包:

import os # 处理文件路径。
from typing import Union # 这个是专门写注释用的,没啥实际作用。

import win11toast # 发送Windows通知。
import wxpy # 收发微信。

这个wxpy里有一个非常重要的Bot类。我们需要创建一个Bot类的变量,用于收发微信:

bot = wxpy.Bot(cache_path=True)

其中,这个cache_path表示微信登录信息的缓存路径。如果设置为True,它就会在程序的同级目录下创建一个叫wxpy.pkl的文件,这样就不用每次运行的时候都扫一次码了,只有当缓存的登录信息过期时,才需要重新扫码。但是使用这个参数也有一个缺点,就是每次重新运行程序的时候都会收到一些重复的信息。初始化Bot的时候还可以使用一些其他参数,具体可以参考wxpy的官方文档

接下来,就是要处理bot接收到的所有微信消息。我们可以用Bot.register装饰器来处理这些消息:

@bot.register(except_self=False)
def echo(msg: wxpy.Message) -> None:

装饰器中,except_self参数表示是否处理自己发送的消息。如果为True,将只处理别人发送的消息。而装饰器下方函数的参数是一个wxpy.Message类的变量。关于这个变量的具体信息也可以参考wxpy的官方文档

现在,我们要分别处理收到的文字、图片和文件信息。首先是文字信息:

if msg.type == wxpy.TEXT: # 判断信息类型为文字信息。
    display = f'{msg.chat.name}({msg.sender.name if msg.member is None else msg.member.name}): {msg.text}'
    res = win11toast.toast('WeChat',
                           display,
                           input='Reply to this message...',
                           button={
                               'activationType': 'protocol',
                               'arguments': 'http:',
                               'content': 'Send',
                               'hint-inputId': 'Reply to this message...'
                           },
                           duration='long')

这里主要要说一下这个win11toast.toast函数。这个函数是用来发送通知的,函数的前两个参数分别是通知的标题和内容,之后有一些关键字参数。button参数表示这个通知上有一个按钮,duration参数可以延长通知显示的时间。这个函数会返回一个字典,其中包含了用户想要回复的信息。

图片和文件信息的处理其实大同小异,这里就不赘述了。接下来是处理用户的回复:

try:
    reply = res['user_input']['Reply to this message...'] # 获取用户的回复。
    if reply:
        msg.chat.send_msg(reply) # 发送回复。
except Exception:
    pass

这样就完成了整个信息处理的步骤,说实话还挺简单的,主要是wxpywin11toast这两个库封装得太好了。我在编写这段代码的时候其实也没遇到什么问题,唯一的问题就是感觉win11toast的文档写得有点不清不楚。

但现在的问题是,我们只能被动地回复收到的信息,不能主动向别人发送信息。为了解决这个问题,我写了三个函数用于在Windows终端中主动发送信息。它们分别是:

  • switch_context,用于选择聊天对象。
def switch_context(chat: Union[str, None] = None) -> None:
	# 参数chat表示想要选择的聊天对象,可以为对象的昵称、备注、群名等信息。如果为None,则会切换到上一个向你发送消息的聊天对象。
    global context # 全局变量context记录着当前的聊天对象。
    if chat is None:
        if last is None:
            print('Warning: No existing chat found.') # 聊天对象为None,并且当前没有收到任何消息时报错。
        else:
            context = last
    else:
        chat = bot.search(chat) # 搜索聊天对象。
        try:
            context = wxpy.ensure_one(chat) # 确保搜索结果唯一。
        except ValueError:
            print(
                'Warning: Zero or more than one chat with the given keyword found. Skipping these chats.'
            ) # 当搜索结果不唯一时报错。
            return
  • show_context,用于显示当前聊天对象。
def show_context() -> None:
    if context is None: # 当前无聊天对象。
        print('No chat context is available.')
        return
    print(f'Current context: [{context.name}].')
  • send,用于发送消息。
def send(msg: str,
         chat: Union[str, None] = None,
         msg_type: str = 'msg') -> None:
    # msg为待发送的信息,可以为文字信息或文件名。
    # chat为发往的聊天对象。可以为对象的昵称、备注、群名等信息。如果为None,则会使用当前context中的聊天对象。
    # msg_type为消息类型,可以为“msg”(文字消息)、“image”(图片)、“file”(文件)或“video”(视频)。
    if chat is None:
        if context is None:
        	# 当chat为None并且当前无聊天对象时报错。
            print('Warning: No chat context is available.')
            return
        else:
            chat = context
    else:
    	# 搜索聊天对象。
        chat = bot.search(chat)
        try:
            chat = wxpy.ensure_one(chat)
        except ValueError:
            print(
                'Warning: Zero or more than one chat with the given keyword found. Skipping these chats.'
            )
            return
    if msg_type == 'msg':
        chat.send_msg(msg)
    elif msg_type == 'image':
        chat.send_image(msg)
    elif msg_type == 'file':
        chat.send_file(msg)
    elif msg_type == 'video':
        chat.send_video(msg)
    else:
        print('Warning: Invalid message type.')
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值