Golang -- openwechat微信发送消息、自动回复

news2024/11/24 16:59:18

开篇

马上就要到农历新年了,不妨写一段代码准时为好友们送上祝福。
Demo 使用开源项目 openwechat ,实现获取好友列表、为好友发送消息、图片或文件,接收来自好友或群组的消息并设置自动回复等功能。
openwechat Github地址
openwechat 文档地址

代码结构

在这里插入图片描述

项目入口

代码很简单,就是调用一下微信的启动方法即可

启动微信

package bootstrap

import (
	"os"

	wechat "wechatbot/handler"
	"wechatbot/task"

	"github.com/eatmoreapple/openwechat"
	log "github.com/sirupsen/logrus"
)

func StartWebChat() {
	//清除旧的token文件
	os.Remove("token.json")
	//初始化桌面微信
	bot := openwechat.DefaultBot(openwechat.Desktop)
	//设置微信消息处理模块,自动回复
	bot.MessageHandler = wechat.Handler
	//显示登陆二维码
	bot.UUIDCallback = openwechat.PrintlnQrcodeUrl

	reloadStorage := openwechat.NewJsonFileHotReloadStorage("token.json")
	err := bot.HotLogin(reloadStorage)
	if err != nil {
		if err = bot.Login(); err != nil {
			log.Fatal(err)
			return
		}
	}

	// 获取登陆用户信息
	self, err := bot.GetCurrentUser()
	if err != nil {
		log.Fatal(err)
		return
	}
	// 获取好友列表
	friends, err := self.Friends()
	if err != nil {
		log.Fatal(err)
		return
	} else {
		// 初始化定时任务 
		nytask := task.NewYearMessageDomain{
			Content:   "零时的钟声响彻天涯,新年的列车准时出发.它驮去难忘的岁月,迎来了又一轮火红的年华.祝你新年快乐,鹏程万里!",
			Imguris:   []string{"E:\\新年快乐.jpg"},
			Receivers: []string{"xxxxx1","xxxxx2"},
			Blacklist: []string{"xxxxx3"},
			Friends:   friends}
		nytask.InitTask()
	}

	//阻塞进程 等待桌面微信退出
	err = bot.Block()
	if err != nil {
		log.Fatal(err)
		return
	}
}

微信消息处理模块

在启动微信时,我们设置了微信消息处理函数
在这里插入图片描述
我们查看这个 MessageHandler 可以发现其实是一个自定义的 func 类型,接收 Message 指针类型并做处理
在这里插入图片描述
所以 我们需要创建的 wechat.Handler 必须是和 MessageHandler 具有相同参数和返回值的方法。

package wechat

import (
	"strings"

	"github.com/eatmoreapple/openwechat"
	log "github.com/sirupsen/logrus"
)

func Handler(msg *openwechat.Message) {
	err := handle(msg)
	if err != nil {
		log.Errorf("handle error: %s\n", err.Error())
		return
	}
}

func handle(msg *openwechat.Message) error {
	if !msg.IsText() {//只处理回复文本消息
		return nil
	}
	return ReplyText(msg)
}

func ReplyText(msg *openwechat.Message) error {

	sender, err := msg.Sender()
	if err == nil {
		if sender.IsFriend() { //判断如果是好友发来的消息,则处理
			msgContent := msg.Content
			//如果好友发来了新年好 或者 新年快乐,回复新年好
			if strings.Contains(msgContent, "新年") && (strings.Contains(msgContent, "好") || strings.Contains(msgContent, "快乐")) {
				msg.ReplyText("新年好呀")
			}
		}
	} else {
		log.Fatal(err)
	}

	return nil
}

定时任务

定时任务使用的是 robfig/cron 的框架,
robfig/cron 文档地址

创建一个 NewYearMessageDomain 结构体,里面包含以下属性:
1、要发送的文本消息
2、要发送的图片地址
3、设置的接收人列表,可以为空就会发送给所有好友
4、设置的黑名单列表
5、openwechat 好友信息列表

package task

import (
	"fmt"
	"os"
	"time"

	"github.com/eatmoreapple/openwechat"
	"github.com/robfig/cron/v3"
)

type NewYearMessageDomain struct {
	Content   string             //文本消息
	Imguris   []string           //图片地址
	Receivers []string           //接收人
	Blacklist []string           //黑名单
	Friends   openwechat.Friends //好友列表
}

// 判断切片中是否存在某个元素
func (nymd *NewYearMessageDomain) find(slice []string, val string) bool {
	for i := range slice {
		if slice[i] == val {
			return true
		}
	}
	return false
}

//初始化定时任务的方法
func (nymd *NewYearMessageDomain) InitTask() {

	//设置定时任务
	crontab := cron.New(cron.WithSeconds()) //精确到秒
	//定义定时器调用的任务函数
	task := func() {
		for i := range nymd.Friends {
			friend := nymd.Friends[i]
 			//好友在黑名单里 不发送消息
			if nymd.find(nymd.Blacklist, friend.NickName) {
				continue
			}

			//如果设置了发送好友列表 则判断是否在列表中,否则直接发送
			if (len(nymd.Receivers) > 0 && nymd.find(nymd.Receivers, friend.NickName)) || len(nymd.Receivers) == 0 {
				if len(nymd.Content) > 0 {
					//发送祝福语
					friend.SendText(nymd.Content)
				}
				if len(nymd.Imguris) > 0 {
					//设置了图片路径 发送图片
					for i := range nymd.Imguris {
						fileInfos, err := os.Open(nymd.Imguris[i])
						defer fileInfos.Close()
						if err == nil {
							time.Sleep(time.Millisecond * 50) //频繁发送可能会被微信限制
							friend.SendImage(fileInfos)
						} else {
							fmt.Println(err)
						}
					}
				}
			}

		}
	}
	//设置cron表达式  指定时间
	spec := "0 0 0 21 1 2023"
	// 添加定时任务
	crontab.AddFunc(spec, task)
	// 启动定时器
	crontab.Start()
}

效果

启动程序后会弹出二维码,手机微信扫描之后登录桌面微信。
在这里插入图片描述
自动发送消息。
在这里插入图片描述
自动回复的功能。
在这里插入图片描述

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

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

相关文章

管道(匿名,有名)

文章目录Linux 进程间通信的方式管道匿名管道有名管道Linux 进程间通信的方式 管道 管道特点 管道其实是一个在内核内存中维护的缓冲器,这个缓冲器的存储能力是有限的,不同的操作系统大小不一定相同管道拥有文件的特质:读操作、写操作 匿名管…

线扫相机DALSA-变行高拍照

CamExpert在线阵模式中默认的Buffer设置是Fixed Length。在这种设置下,在一帧采集结束前所接收到的新的帧触发信号都会被忽略。在有的应用中,需要新一帧的外触发信号能够中断当前帧的采集,开始新的一帧。这需要将Buffer设为Variable Length。…

【云原生】k8s之HPA,命名空间资源限制

内容预知 1.HPA的相关知识 2.HPA的部署运用 2.1 进行HPA的部署设置 2.2 HPA伸缩的测试演示 (1)创建一个用于测试的pod资源 (2)创建HPA控制器,进行资源的限制,伸缩管理 (3)进入其中一个pod容器仲&#xf…

Redhat OpenStack使用命令行发放云主机

OpenStack中各大组件的作用Glance:负责管理镜像(镜像的上传、删除、下载)Swift:提供镜像存储的空间Nova:负责配额的修改、启动云主机(实例)、创建密钥对、绑定弹性IP等Keystone:提供…

jQuery(二):属性、元素、尺寸位置操作、事件

jQuery属性操作内容文本值元素操作尺寸、位置操作事件注册事件处理事件对象拷贝对象属性操作 1.获取固有属性语法 prop(‘‘属性’’) 固有属性就是html自带的,例如a元素里面的 href ,input 元素里面的 type。 2.设置固有属性语法 prop(‘‘属性’’, …

Python NumPy 搜索 数组

前言NumPy(Numerical Python的缩写)是一个开源的Python科学计算库。使用NumPy,就可以很自然地使用数组和矩阵。NumPy包含很多实用的数学函数,涵盖线性代数运算、傅里叶变换和随机数生成等功能。本文主要介绍Python NumPy 搜索 数组…

Linux小黑板(8)管道

"让我们,笑吧"一、什么是通信?管道是属于进程间通信的一个实现方式。再讲管道之前呢,我们先来说说什么叫做进程间通信。我们日常生活中,给自己的家人、朋友给一个call,或者弹一条微信、QQ等等,从而让人家能够知道我们想…

Databend 开源周报第 76 期

英文版移步:https://databend.rs/blog/2023-01-11-databend-weekly Databend 是一款强大的云数仓。专为弹性和高效设计。自由且开源。即刻体验云服务:https://app.databend.com 。 What’s New 探索 Databend 本周新进展,遇到更贴近你心意的…

vue 中由浅拷贝引发问题的一些场景

在工作的过程中踩了很多的由浅拷贝导致的坑,今天总结在这里,希望对大家有所帮助 1. 组件中直接抛出一个引用类型变量 🌰举个例子 (ps: 以下代码为伪代码,主要展示逻辑用) 子组件(uploadImg&a…

线 程 同 步、线程的死锁问题

线程同步: 模拟售票程序出现问题:当多个线程同时访问共享数据时,产生无序、重复、超额售票等多线程安全问题 解决:将多个线程需要访问的共享数据,包装起来视为一个整体,确保一次只有一个线程执行流访问共享…

春节福利丨神策数据 2022 年数字化营销资料打包全送

2022 年,神策数据出品多份行业研究报告,覆盖银行、证券、零售、教育、电商、融合媒体等多个行业,帮助更多企业通过多视角洞见紧握数字化营销的方向和趋势,用方法论结合落地实践驱动企业数字化经营。01B2B 电商数字化运营聚焦四类 …

【自学Python】Python查找字符串位置

Python查找字符串位置 大纲 Python查找字符串位置教程 在开发过程中,很多时候我们有在一个 字符串 中查找另一个字符串位置的需求,在 Python 中,在一个字符串中查找另一个字符串的位置我们使用 index() 函数。 index() 函数的功能与 find(…

力扣(78.90)补9.22

78.子集 感觉不太难&#xff0c;但是就是不会写。感觉回溯里有很多细节问题。 class Solution { private: vector<vector<int>> res; vector<int> num; void back(vector<int>& nums,int index,int end){ res.push_back(num); …

【JavaEE初阶】第三节.多线程基础篇

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 文章目录 前言 一、认识线程 二、多线程程序 2.1 第一个Java多线程程序 2.2 怎么样观察线程的详细情况 2.3 sleep方法 2.4 run 和 start 方法的区别是什么 三、创…

在springboot中配置热部署

今天什么节日也不是&#xff0c;那就祝大家今天快乐。 热部署 所谓热部署&#xff0c;就是在应用正在运行的时候升级软件&#xff0c;却不需要重新启动应用。对于Java应用程序来说&#xff0c;热部署就是在运行时更新Java类文件。在以往&#xff0c;我们对java代码进行修改之后…

【HBU】大一下期末重点

物理简答题一、牛顿第二定律&#xff08;Fdp/dt &#xff09;&#xff1a;1. 飞机怕小鸟:Fdp/dt 力与作用时间的乘积等于物体动量的变化。由于小鸟与飞机相对速度很大&#xff0c;作用时间很短,产生的作用力很大&#xff0c;当小鸟与飞机向撞&#xff0c;效果与同质量炮弹撞飞机…

正则表达式入门及常用正则表达式

常用正则表达式 1 正则表达式的基础概念 1.1 预定义字符 . 表示任何字符&#xff08;与行结束符可能匹配也可能不匹配&#xff09; \d 数字&#xff1a;[0-9] \D 非数字字符&#xff1a;[^0-9] \s 空白字符&#xff1a;[\t\n\xoB\f\r] \S 非空白字符&#xff1a;[^\s] \w 单…

k8s的YAML部署rocketmq记录

说明 测试环境是k8s集群&#xff0c;在上边部署一套单节点的rocketmq nameserver部署 Service和StatefulSet脚本如下 apiVersion: v1 kind: Service metadata:labels:app: rocketmqnamesrvname: rocketmqnamesrv spec:type: ClusterIPports:- port: 9876targetPort: 9876na…

Pytorch深度学习【十四】

批量归一化 归一化 损失出现在最后&#xff0c;后面的层(高级语义层)训练较快数据输入在最底部 底部的层训练慢底部层一变化&#xff0c;所有高级语义层都得跟着变最后的那些层需要重新学习多次—收敛速度变慢 问题—是否可以在学习底部层的时候避免变化顶部层 批量归一化 固定…

8 个精彩的免费 G​​IS 软件资源分享

有人说&#xff1a;一个人从1岁活到80岁很平凡&#xff0c;但如果从80岁倒着活&#xff0c;那么一半以上的人都可能不凡。 生活没有捷径&#xff0c;我们踩过的坑都成为了生活的经验&#xff0c;这些经验越早知道&#xff0c;你要走的弯路就会越少。 GIS 软件有两种通用格式&a…