使用wechaty与Flask搭建消息通知服务

本文介绍了如何使用wechaty和Flask搭建一个消息通知服务。作者通过部署Wechaty Puppet Hostie并避免消息监听循环,创建了一个可主动发送消息的微信机器人。此外,还利用aioflask和asyncio实现多服务并发请求,确保消息的高效发送。
摘要由CSDN通过智能技术生成

作者: Houruirui,代码爱好者。

Wechaty-Flask-Service

目前,市面上有各种各样的接口提供了消息推送,比如钉钉,spark, IFTTT, telegram等等. 但是,每个人手机里各种各样的消息推送常常让人应接不暇。而微信,作为最广泛使用的聊天工具,鲜有人错过阅读微信消息。 所以,最方便的还是通过微信机器人来进行消息推送。

通过搜索,了解到目前市场的消息机器人有itchat, wxpy,wechaty等等。可是随着腾讯施加压力,基于web微信的itchat和wxpy无法使用。而wechaty支持多种协议,比web协议更加安全,于是决定采用wechaty基于ipad协议 ( padLocal ) 来搭建机器人。但是,在实际的应用当中,而且wechaty是通过消息回调的形式实现的,这样的情况下,就没有办法让机器人主动发消息,还有一个问题是可能你有很多个应用都需要使用微信通知,但是一个Token只能供一个微信账号使用,那怎么样才能让多个服务都通过这一个微信来发通知呢?对于这两个问题,我想到的办法首先自己实现初始化机器人,在完成初始化后直接返回机器人而不让机器人进入消息监听循环,从而主动控制机器人收发消息;在多服务的场景下,用flask建立后端服务,维护初始化好的机器人,这样不同的业务可以直接向后端发起请求而实现消息通知。

让我们进入正题!

环境和依赖

python aioflask asyncio

Wechaty Puppet Hostie部署:

因为原生的wechaty是基于JavaScript和TypeScript写的,所以需要通过docker搭建Wechaty Puppet Hostie 服务作为中转, 从而可以通过python调用。

  • 部署前置准备:

一个满足以下三点要求的服务器:

Public IP Public Port Docker

  • 部署Wechaty Puppet Hostie

具体代码如下(本人服务器为 Ununtu 18.04)

#! /usr/bin/bash

export WECHATY_LOG="verbose"
export WECHATY_PUPPET="wechaty-puppet-padlocal"
export WECHATY_PUPPET_PADLOCAL_TOKEN="puppet_padlocal__TOKEN__"

export WECHATY_PUPPET_SERVER_PORT="9001"
export WECHATY_TOKEN=$(curl -s https://www.uuidgenerator.net/api/version4)
  --name wechaty_puppet_service_token_gateway \
  --rm \
  -e WECHATY_LOG \
  -e WECHATY_PUPPET \
  -e WECHATY_PUPPET_PADLOCAL_TOKEN \
  -e WECHATY_PUPPET_SERVER_PORT \
  -e WECHATY_TOKEN \
  -p "$WECHATY_PUPPET_SERVER_PORT:$WECHATY_PUPPET_SERVER_PORT" \
  wechaty/wechaty

代码中的WECHATY_PUPPET_PADLOCAL_TOKEN是需要向官方申请,可以得到的一个可以试用7天的token,后续通过社区的激励计划,还可以免费获得时效更长的token。详情参见这里

  • 验证Wechaty Puppet Hostie

访问 https://api.chatie.io/v0/hosties/WECHATY_TOKEN, 其中WECHATY_TOKEN是指你刚刚自行设定的Token,当返回结果为服务器的Public IP时则说明部署成功,为0.0.0.0时则说明部署失败~

项目思路

关于机器人方面,我读了官方examples里面的代码发现机器人都是继承Wechaty基类来通过自定义回调函数来实现各种功能。利用事件驱动的回调函数这样是很被动的,而我想得到一个可直接调用的Wechaty对象,不通过start()函数进入事件循环监听, 而可以主动的发送信息。经过一天的阅读代码和自我摸索,终于实现了创建一个可以直接调用的机器人对象,稍后请参考详细代码,其中最重要的还是需要进入事件监听,然后在监听到成功登录的事件以后,中断监听,返回已经登录好的机器人对象, 从而实现直接调用。

首先我们初始化机器人对象,我是想把消息通知发送到群聊当中,在使用过程中发现,在初始化好机器人后并没有加载好微信群,所以我们需要先用官方提供的examples来获取到微信群的id,然后手动加载微信群。同时,我还发现如果同步的发送消息,flask需要5-10s才能处理完请求,所以在这里我使用了用线程处理不同的请求,实现了消息的并发。

from aioflask import Flask
from aioflask import request
from Config import WECHAT_SEVER_CONFIG
import concurrent.futures
from threading import Thread
import threading
import itertools

from wechaty import Wechaty, Message, WechatyPlugin, Room, WechatyOptions
from wechaty_puppet import *
import os
import asyncio
import json
import traceback

app = Flask(__name__)

WECHATY_PUPPET_SERVICE_TOKEN = ''
WECHATY_PUPPET = 'wechaty-puppet-service'

os.environ['WECHATY_PUPPET_SERVICE_TOKEN'] = WECHATY_PUPPET_SERVICE_TOKEN
os.environ['WECHATY_PUPPET'] = WECHATY_PUPPET
os.environ['WECHATY_PUPPET_SERVICE_ENDPOINT'] = "0.0.0.0:9001"

class WechatBot():

    def __init__(self):
        print("need to Init wechat bot!")
        self.bot: Wechaty = None
        asyncio.get_event_loop().run_until_complete(self.init_wechat_bot())

    async def init_wechat_bot(self):
        puppet_options = PuppetOptions()
        puppet_options.token = WECHATY_PUPPET_SERVICE_TOKEN

        options = WechatyOptions()
        # options.name = self.my_wechat_id
        options.puppet = WECHATY_PUPPET
        options.puppet_options = puppet_options

        self.bot = Wechaty(options)
        await self.bot.init_puppet()
        await self.bot.init_puppet_event_bridge(self.bot.puppet)
        self.bot.puppet._init_puppet()
        # await self.bot.puppet.logout()
        # print(self.bot.puppet.login_user_id)
        async for response in self.bot.puppet
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值