Bot对象
Bot
对象负责处理网络请求和消息回调以及登录登出的用户行为,一个Bot
对应一个登录的微信号。
创建Bot对象
在登录微信之前需要创建一个Bot
对象。
bot := openwechat.DefaultBot()
使用默认的构造方法DefaultBot
来创建一个Bot
对象。
登陆二维码回调
但仅仅是这样我们依然无法登录, 我们平常登录微信都需要用手机扫描二维码登录,所以我们得知道需要扫描哪张二维码,最后还需要为它绑定一个登录二维码的回调函数。
// 注册登陆二维码回调
bot.UUIDCallback = openwechat.PrintlnQrcodeUrl
PrintlnQrcodeUrl
这个函数做的事情很简单,就是将我们需要扫码登录的二维码链接打印打控制台上,这样我们就知道去扫描哪张二维码登录了。
可以自定义UUIDCallback
来实现自己的逻辑。
如:将登录的二维码打印到控制台。
package main
import (
"fmt"
"github.com/skip2/go-qrcode"
"github.com/eatMoreApple/openwechat"
)
func ConsoleQrCode(uuid string) {
q, _ := qrcode.New("https://login.weixin.qq.com/l/"+uuid, qrcode.Low)
fmt.Println(q.ToString(true))
}
func main() {
bot := openwechat.DefaultBot()
bot.UUIDCallback = ConsoleQrCode
bot.Login()
}
虽然最终打印的结果肉眼看上去有点不尽人意,但手机也还能够识别...
登录
扫码登录
上面的准备工作做完了,下面就可以登录,直接调用Bot.Login
即可。
bot.Login()
Login
方法会阻塞当前 goroutine,直到登录成功或者失败。
登录会返回一个error
,即登录失败的原因。
热登录
每次执行普通登录都需要扫码,在调试一些功能的时候需要反复编译,这样会很麻烦。
热登录可以只用扫码一次,后面在单位时间内重启程序也不会再要求扫码
// 创建热存储容器对象
reloadStorage := openwechat.NewFileHotReloadStorage("storage.json")
defer reloadStorage.Close()
// 执行热登录
bot.HotLogin(reloadStorage)
HotLogin
需要接受一个热存储容器对象
来调用。热存储容器
用来保存登录的会话信息,本质是一个接口类型
我们第一次进行热登录的时候,因为我们的热存储容器
是空的,所以这时候会发生错误。
我们只需要在HotLogin
增加一个参数,让它在失败后执行扫码登录即可
bot.HotLogin(reloadStorage, openwechat.NewRetryLoginOption())
当扫码登录成功后,会将会话信息写入到热存储容器
中,下次再执行热登录的时候就会从热存储容器
中读取会话信息,直接登录成功。
// 热登陆存储接口
type HotReloadStorage io.ReadWriter
NewFileHotReloadStorage
简单实现了该接口,它采用文件的方式存储会话信息。
实现这个接口,来定义你自己的存储方式。
免扫码登录
目前热登录有一点缺点就是它的有效期很短(具体多久我也不知道)。
我们平常在pc上登录微信的时候,通常只需要登录一次,第二次就会在微信上有一个确认登录的按钮,点击确认就会往手机上发送一个确认登录的请求,这样就可以免扫码登录了。
openwechat也提供了这样的功能。
bot.PushLogin(storage HotReloadStorage, opts ...openwechat.BotLoginOption) error
PushLogin
需要传入一个热存储容器
,和一些可选参数。
HotReloadStorage
跟上面一样,用来保存会话信息,必要参数。
openwechat.BotLoginOption
是一个可选参数,用来设置一些额外的行为。
目前有下面几个可选参数:
// NewRetryLoginOption 登录失败后进行扫码登录
func NewRetryLoginOption() BotLoginOption
注意:如果是第一次登录,PushLogin
一定会失败的,因为我们的HotReloadStorage
里面没有会话信息,你需要设置失败会进行扫码登录。
bot := openwechat.DefaultBot()
reloadStorage := openwechat.NewFileHotReloadStorage("storage.json")
defer reloadStorage.Close()
err = bot.PushLogin(reloadStorage, openwechat.NewRetryLoginOption())
这样当第一次登录失败的时候,会自动执行扫码登录。
扫码登录成功后,会自动保存会话信息到HotReloadStorage
,下次登录就可以直接使用PushLogin
了,就会往手机上发送确认登录的请求。
扫码回调
在pc端微信上我们打开手机扫码进行登录的时候,只扫描二维码,但不点击确认,微信上也能够显示当前扫码用户的头像,并提示用户登录确认。
通过对bot
对象绑定扫码回调即可实现对应的功能。
bot.ScanCallBack = func(body openwechat.CheckLoginResponse) { fmt.Println(string(body)) }
用户扫码后,body里面会携带用户的头像信息。
注:绑定扫码回调须在登录前执行。
CheckLoginResponse
是一个[]byte
包装类型, 扫码成功后可以通过该类型获取用户的头像信息。
type CheckLoginResponse []byte
func (c CheckLoginResponse) Avatar() (string, error)
登录回调
对bot
对象绑定登录
bot.LoginCallBack = func(body openwechat.CheckLoginResponse) {
fmt.Println(string(body))
// to do your business
}
登录回调的参数就是当前客户端需要跳转的链接,用户可以不用关心它。(其实可以拿来做一些骚操作😈)
登录回调函数可以当做一个信号处理,表示当前扫码登录的用户已经确认登录。
桌面模式
DefaultBot
默认是与网页版微信进行交互,部分用户的网页版wx可能已经被限制登录了。
这时候可以尝试使用桌面模式
进行登录。
bot := openwechat.DefaultBot(openwechat.Desktop)
别的逻辑不用改,直接在创建bot的时候加一个参数就行了。
如果桌面模式还登录不上,请检查你的微信号是不是刚刚申请。
消息处理
在用户登录后需要实时接受微信发送过来的消息。
很简单,给BOT
对象绑定一个消息回调函数就行了。
// 注册消息处理函数
bot.MessageHandler = func(msg *openwechat.Message) {
if msg.IsText() && msg.Content == "ping" {
msg.ReplyText("pong")
}
}
所有接受的消息都通过Bot.MessageHandler
来处理。
基于这个回调函数,可以对消息进行多样化处理
dispatcher := openwechat.NewMessageMatchDispatcher()
// 只处理消息类型为文本类型的消息
dispatcher.OnText(func(ctx *openwechat.MessageContext){
msg := ctx.Message
fmt.Println("Text: ", msg.Content)
msg.ReplyText("hello")
})
// 注册消息回调函数
bot.MessageHandler = dispatcher.AsMessageHandler()
openwechat.DispatchMessage
会将消息转发给dispatcher
对象处理
MessageMatchDispatcher
构造方法
openwechat.NewMessageMatchDispatcher()
注册消息处理函数
// 注册消息处理函数
func (m *MessageMatchDispatcher) RegisterHandler(matchFunc matchFunc, handlers ...MessageContextHandler)
// 消息匹配函数
type matchFunc func(*Message) bool
// 消息处理函数
type MessageContextHandler func(ctx *MessageContext)
matchFunc
:接受当前收到的消息对象,并返回bool
值,返回true
则表示处理当前的消息
RegisterHandler
:接受一个matchFunc
和不定长的消息处理函数,如果matchFunc
返回为true
,则表示运行对应的处理函数组。
OnText
注册处理消息类型为文本类型的消息
func (m *MessageMatchDispatcher) OnText(handlers ...MessageContextHandler)
OnImage
注册处理消息类型为图片类型的消息
func (m *MessageMatchDispatcher) OnImage(handlers ...MessageContextHandler)
OnVoice
注册处理消息类型为语言类型的消息
func (m *MessageMatchDispatcher) OnVoice(handlers ...MessageContextHandler)
更多请点击查看源码
获取登录后的用户
self, err := bot.GetCurrentUser()
注:该方法在登录成功后调用
阻塞主程序
bot.Block()
该方法会一直阻塞,直到用户主动退出或者网络请求发生错误。
控制Bot存活
判断当前的Bot
是否存活。
func (b *Bot) Alive() bool
当返回为true
则表示Bot
存活。
如何控制Bot
存活呢?
ctx, cancel := context.WithCancel(context.Background())
bot := openwechat.DefaultBot(openwechat.WithContext(ctx))
WithContext
接受一个context.Context
对象,当context
对象被取消时,Bot
也会被取消。
当前我们也可以调用bot.Logout
来主动退出当前的Bot
,当Bot
退出后,bot.Alive()
会返回false
。