背景

楼主有一台树莓派4B开发板(8G内存版),是目前的顶配机型。这一年来的业余时间,除了写Java、架构方面的文章,也陆续折腾了不少树莓派上的好玩小项目,在此新开一个树莓派实战的文章系列,分享给粉丝和读者。

什么是树莓派?树莓派是一个信用卡大小的单板计算机,ARM架构CPU,可以7×24跑Linux服务器,连接各种扩展硬件,所以发挥想象力,就能做很多有意思的事情。

需求

你有没有想过,拥有一个微信机器人,可以自动回复、AI聊天、定时发送天气预报、控制摄像头等等。使用树莓派+开源库itchat,就能实现上述所有需求。

为什么强调要用树莓派呢?因为它能7×24在线,可以把itchat客户端当作一个不停服的server。

特别说明:本文仅供学习用,请勿用于任何商业和其它用途。

itchat简介

itchat是一个开源的微信个人号接口,使用不到三十行的代码,就可以完成一个能够处理所有信息的微信机器人。

github地址:https://github.com/littlecodersh/ItChat

你一定对原理感到好奇。其实可以概括为一句话:itchat本质上是一个微信网页版客户端,它实现了微信网页版的协议/语义,通过http来通信。具体源码可以看components包里的文件。

下面分点介绍如何实现有趣的功能。

功能实现

1、自动回复

首先得注册消息处理函数,即对不同类型的消息做处理。微信消息分为文本、图片、语音、视频、好友申请等,可通过itchat的Python语法糖来注册不同类型消息的处理函数,有点类似Java里的注解。

如果是文本消息,可以识别其中的关键字,不同的关键字对应不同的逻辑处理。

默认是处理单聊的消息,也可以处理群聊的消息。

下面给出一个demo,并加以注释。

import itchat, time
from itchat.content import * # 注册消息处理函数,回复文本、地图、名片、备注、分享类型的消息
@itchat.msg_register([TEXT, MAP, CARD, NOTE, SHARING])
def text_reply(msg):
# 回复以下消息:消息类型,消息内容文本
itchat.send('%s: %s' % (msg.type, msg.text))
# 根据不同的关键字,回复不同的消息
if '你好' in msg.text:
itchat.send('你好啊')
elif '拜拜' in msg.text:
itchat.send('下次聊') # 注册消息处理函数,当收到图片、语音、附件、视频类型的消息时,下载内容
@itchat.msg_register([PICTURE, RECORDING, ATTACHMENT, VIDEO])
def download_files(msg):
# 下载文件
msg.download(msg.fileName)
typeSymbol = {
PICTURE: 'img',
VIDEO: 'vid', }.get(msg.type, 'fil')
return '@%s@%s' % (typeSymbol, msg.fileName) # 注册消息处理函数,处理好友申请消息
@itchat.msg_register(FRIENDS)
def add_friend(msg):
# 自动通过对方的好友申请
msg.user.verify()
# 然后发送问候语
msg.user.send('Nice to meet you!') # 上面几个都是单聊,加上isGroupChat=True就能处理群聊消息
@itchat.msg_register(TEXT, isGroupChat=True)
def text_reply(msg):
# 当在群聊被at时才回复,一般都会加上此条件,否则可能回复群内所有消息
if msg.isAt:
# 回复时,也at对应的人消息
msg.user.send(u'@%s\u2005I received: %s' % (
msg.actualNickName, msg.text)) # 登录
itchat.auto_login(True)
# 运行itchat客户端,debug=True会打印日志
itchat.run(True)

2、AI聊天

有了第1步的基础,要实现AI聊天,就需要引入另外的AI本地库、或者在线API了,使用在线API更简单,只需要控制传参、解析响应即可。楼主使用了一个叫青云客的API,可免费使用(自己简单试用的前提下,非商用),带关键字命令的AI对话还是不错的,如果是自由对话,那大概率前言不搭后语。

# 调API来进行AI聊天,只有一个文本参数
def ai_chat(msg):
url = 'http://api.qingyunke.com/api.php?key=free&appid=0&msg=%s' % msg
response = requests.get(url)
return response.json()["content"].replace('{br}', '\n') # 响应里的换行是{br},替换为微信可识别的\n换行

3、定时发送天气预报

有了第2步的基础,要获取天气预报信息,只需要在AI聊天的请求里传某地天气即可,比如:上海天气、北京天气。当然,你也可以通过爬天气预报网页的字段,得到更详尽的天气预报信息,此处就不多讨论了。

定时发天气预报,要解决2个关键问题。

  • 一是如何执行定时任务。此处选用Python库apscheduler。当然,也可以写一个Python脚本,然后通过操作系统的crontab在指定的时间执行该脚本,不过还有更优雅的方式,在Python主程序内启动定时任务。可以使用Python库apscheduler来实现定时任务的调度,类似于Java的ScheduledThreadPool。
  • 二是如何发送消息到指定的群。itchat已经提供了便捷的API来根据群名搜索具体的群。
from apscheduler.schedulers.blocking import BlockingScheduler

# 发送天气预报信息到群里
def weather_report():
msg = ai_chat('上海天气')
# 获取所有群聊
itchat.get_chatrooms(update=True)
# 根据群名,搜索具体的群
chatrooms = itchat.search_chatrooms(name='<此处改为实际的群名>')
chatroom = itchat.update_chatroom(chatrooms[0]['UserName'])
# 发送消息,到指定的群
itchat.send_msg(msg=msg,toUserName=chatroom['UserName']) if __name__ == '__main__':
itchat.auto_login(hotReload=True)
# itchat启动后是否阻塞,此处改为否(默认为是),相当于itchat在新启动的线程中运行,不阻塞主程序
itchat.run(blockThread=False) # 定时任务
scheduler = BlockingScheduler()
# 指定在每天早上9点调用weather_report函数
scheduler.add_job(weather_report, 'cron', day_of_week='*', hour=9, minute=0, second=0)
scheduler.start()

4、控制摄像头,拍照、视频看看家里

树莓派4B有2个USB 3.0高速接口、2个USB 2.0接口,只需要其中一个连接上USB摄像头即可,一般2.0接口即可,3.0接口留给外接硬盘。

想要通过摄像头看到家里,要解决的关键问题是,使用什么拍照软件?使用什么视频聊天软件?

拍照

可以使用fswebcam来拍照,可以指定图像分辨率,也可以不指定,默认的分辨率较低。

安装:sudo apt install fswebcam

    img_file = '%d.jpg' % timestamp
# 调用fswebcam拍照
os.system('fswebcam %s' % img_file)
# 发送照片至自己的文件传输助手,因为通常发给自己会失败
itchat.send_image(img_file, toUserName='filehelper')

发起视频

楼主尝试了几个常见的免费视频聊天软件,都无法支持,主要原因是树莓派是ARM CPU架构,主流软件基本上只在amd64、x86 CPU架构下发行。比如QQ、Skype、网页版Jitsi Meet等都无法发起视频聊天。

最终,楼主发现了一个较为完美的解决方案,就是使用linphone:

  • 发起视频:在树莓派上安装并打开linphone程序,也在手机上安装并打开linphone app。这样通过微信就可以让树莓派上的linphone发起视频通话,手机端就能接到电话了。
  • 挂断视频:需要通过微信机器人,在树莓派上主动退出linphone,否则后续不能继续发起视频。

    下载最新的linphone可能无法正常工作,得使用sudo apt install linphone来安装旧的稳定版。
    # 先退出linphone(如当前有在运行),再启动linphone
os.system('linphonecsh exit; linphonecsh init -V -c .linphonerc')
time.sleep(1)
# 使用linphone命令行拨打视频通话
os.system('linphonecsh generic "call <替换成实际的linphone账号,需注册>"')

完整代码

以下是楼主写的几个实用例子,并加以注释。

完整代码已上传至github:https://github.com/topcoding/wechat_robot

除了上面提到的几个功能实现,还增加了健身打卡、睡觉打卡的功能。现在,微信机器人的功能已经越来越丰富了。

# -*- coding: utf-8 -*-

import itchat
import sqlite3
import os
import time
import requests
from apscheduler.schedulers.blocking import BlockingScheduler PUNCH_TYPE_WORKOUT = 1
PUNCH_TYPE_SLEEP = 2 ai_chat_switch = True AI_CHATROOM_WHITELIST = ['<替换成实际的群名>'] def save_db(punch_type, owner, timestamp = None):
conn = sqlite3.connect('punch-card.db')
cursor = conn.cursor()
if timestamp is None:
punch_time = (int) (time.time())
else:
punch_time = timestamp
cursor.execute("insert into punch_card(punch_type, owner, updated_at) values(%d, '%s', %d)"
% (punch_type, owner, punch_time))
conn.commit()
conn.close() @itchat.msg_register(itchat.content.TEXT)
def text_reply(msg):
print(msg)
timestamp = (int) (time.time())
global ai_chat_switch
if msg.text == '健身打卡':
save_db(PUNCH_TYPE_WORKOUT, msg.User.NickName, timestamp)
itchat.send('%s,您好,您于%s健身打卡成功' % (msg.User.NickName, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())), toUserName='filehelper')
elif msg.text == '睡觉打卡':
save_db(PUNCH_TYPE_SLEEP, msg.User.NickName, timestamp)
itchat.send('%s,您好,您于%s睡觉打卡成功' % (msg.User.NickName, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())), toUserName='filehelper')
elif msg.text == '拍照':
img_file = '%d.jpg' % timestamp
os.system('fswebcam %s' % img_file)
itchat.send_image(img_file, toUserName='filehelper')
elif msg.text == '看看家里':
os.system('linphonecsh exit; linphonecsh init -V -c .linphonerc')
time.sleep(1)
os.system('linphonecsh generic "call <替换成实际的linphone账号,需注册>"')
elif msg.text == '挂断视频':
os.system('linphonecsh exit')
elif msg.text == '群聊':
ai_chat_switch = True
elif msg.text == '群聊取消':
ai_chat_switch = False
else:
# do nothing
pass @itchat.msg_register('Text', isGroupChat = True)
def group_reply(msg):
if ai_chat_switch and msg['isAt'] and msg['User']['NickName'] in AI_CHATROOM_WHITELIST:
print(msg)
return u'@%s\u2005%s' % (msg['ActualNickName'], ai_chat(msg)) def ai_chat(msg):
url = 'http://api.qingyunke.com/api.php?key=free&appid=0&msg=%s' % msg
response = requests.get(url)
return response.json()["content"].replace('{br}', '\n') def weather_report():
msg = ai_chat('上海天气')
itchat.get_chatrooms(update=True)
chatrooms = itchat.search_chatrooms(name='<替换成实际的群名>')
chatroom = itchat.update_chatroom(chatrooms[0]['UserName'])
itchat.send_msg(msg=msg,toUserName=chatroom['UserName']) if __name__ == '__main__':
itchat.auto_login(hotReload=True)
itchat.run(blockThread=False) scheduler = BlockingScheduler()
scheduler.add_job(weather_report, 'cron', day_of_week='*', hour=9, minute=0, second=0)
scheduler.start()

树莓派实战:微信机器人(itchat实现)的更多相关文章

  1. python+爬虫+微信机器人 打造属于你的网购价格监督利器

    写在最前 程序是为人类服务的,最近正好身边小伙伴们在做球衣生意,当然是去nikenba专区购买了,可是有些热门球衣发布几分钟就被抢完,有些折扣球衣也是很快就被抢售一空,那么我们只能靠自己的眼睛一直盯着 ...

  2. 你的网购价格监督利器——python+爬虫+微信机器人

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:风,又奈何 PS:如有需要Python学习资料的小伙伴可以加点击下方链 ...

  3. python使用itchat库实现微信机器人

    itchat是一个开源的微信个人号接口,可以使用该库进行微信网页版中的所有操作,比如:所有好友.添加好友.拉好友群聊.微信机器人等等.详细用户请看文档介绍,在这里. 本文主要使用该库完成一个能够处理微 ...

  4. Golang 微信机器人包

    一. 最近用在学习golang,写了个小工具练练手.通过golang模拟微信网页端,接收微信服务器的消息并定制.可接入图灵机器人的api实现一个微信机器人的小玩具,当然了,可以有更多更好玩的玩法. 二 ...

  5. python实现微信接口(itchat)

    python实现微信接口(itchat) 安装 sudo pip install itchat 登录 itchat.auto_login() 这种方法将会通过微信扫描二维码登录,但是这种登录的方式确实 ...

  6. 登录以及发送微信消息itchat 库

    项目地址点这里 itchat   itchat是一个开源的微信个人号接口,使用python调用微信从未如此简单. 使用不到三十行的代码,你就可以完成一个能够处理所有信息的微信机器人. 当然,该api的 ...

  7. Python创建微信机器人

    微信,一个日活10亿的超级app,不仅在国内社交独领风骚,在国外社交也同样占有一席之地,今天我们要将便是如何用Python来生成一个微信机器人,突然想起鲁迅先生曾经说过的一句话:因为是微信机器人系列的 ...

  8. Python+ITchart实现微信机器人对指定的朋友和群自动回复

    这里我主要用了3个机器人,可以切换. 1.图灵机器人  (傻的不行,一直在问别人问题,没有限制) http://www.tuling123.com 2.showApi上的图灵机器人 (感觉最聪明,可以 ...

  9. phantomjs + python 打造一个微信机器人

    phantomjs + python 打造一个微信机器人 1.前奏   媳妇公司不能上网,但经常需要在公众号上找一些文章做一些参考,需要的时候就把文章链接分享给我,然后我在浏览器打开网页,一点点复制过 ...

随机推荐

  1. STS快捷键

    在类或者方法上方加注释:shift+alt+J

  2. 攻防世界-MISC:Aesop_secret

    这是攻防世界高手进阶区的的第九题,题目如下: 点击下载附件一,得到一个压缩包,解压后得到一张GIF动图,找个网站给他分解一下,得到如下图片 不知道是什么意思,所以就跑去看WP了,用010editor打 ...

  3. [洛谷] P2241 统计方形(数据加强版)

    点击查看代码 #include<bits/stdc++.h> using namespace std; long long n, m, total, sum1, sum2; int mai ...

  4. 从零开始,开发一个 Web Office 套件(16):拖动控制点,调整编辑器大小

    这是一个系列博客,最终目的是要做一个基于 HTML Canvas 的.类似于微软 Office 的 Web Office 套件(包括:文档.表格.幻灯片--等等). 博客园:<从零开始, 开发一 ...

  5. shell脚本实现MySQL全量备份+异地备份

    一.知识储备工作: Mysql导出数据库语法: mysqldump -u用户名 -p密码 数据库名 > 数据库名.sql shell脚本for循环及if条件判断基本语法 gzip压缩文件用法 r ...

  6. css自定义省略实例2

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. MySQL8新增降序索引

    MySQL8新增降序索引 桃花坞里桃花庵,桃花庵里桃花仙.桃花仙人种桃树,又摘桃花卖酒钱. 一.MySQL5.7 降序索引 MySQL在语法上很早就已经支持降序索引,但实际上创建的却仍然是升序索引,如 ...

  8. 不要使用Java Executors 提供的默认线程池

    线程池构造方法 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUni ...

  9. 理解 Angular 服务

    理解 Angular 服务 本文写于 2021 年 3 月 29 日 理解 Angular 服务 什么是服务 服务写法 原理简述 提供服务 1. 在服务中注册 2. 在 module 中注册 3. 在 ...

  10. Vulnhub-napping

    1.信息收集 先用arp-scan探测出靶机地址 arps-scan -l 显然靶机地址 10.1.1.106,然后利用nmap进行详细信息收集 nmap -A 10.1.1.106 可以看到,目标的 ...