修复当bot在线的情况下执行热登录,会开启多次事件监听 🐛

This commit is contained in:
eatmoreapple 2021-08-01 00:51:52 +08:00
parent 825dc51bf9
commit 67b71542c8
3 changed files with 65 additions and 362 deletions

13
bot.go
View File

@ -5,6 +5,7 @@ import (
"errors"
"log"
"net/url"
"sync"
)
type Bot struct {
@ -14,7 +15,8 @@ type Bot struct {
UUIDCallback func(uuid string) // 获取UUID的回调函数
MessageHandler MessageHandler // 获取消息成功的handle
GetMessageErrorHandler func(err error) // 获取消息发生错误的handle
isHot bool
isHot bool // 是否为热登录模式
once sync.Once
err error
context context.Context
cancel context.CancelFunc
@ -56,6 +58,9 @@ func (b *Bot) GetCurrentUser() (*Self, error) {
// err := bot.HotLogin(storage, true)
// fmt.Println(err)
func (b *Bot) HotLogin(storage HotReloadStorage, retry ...bool) error {
if b.Alive() {
b.cancel()
}
b.isHot = true
b.hotReloadStorage = storage
@ -201,14 +206,16 @@ func (b *Bot) webInit() error {
return err
}
// 开启协程,轮询获取是否有新的消息返回
go func() {
// FIX: 当bot在线的情况下执行热登录,会开启多次事件监听
go b.once.Do(func() {
if b.GetMessageErrorHandler == nil {
b.GetMessageErrorHandler = b.stopAsyncCALL
}
if err = b.asyncCall(); err != nil {
b.GetMessageErrorHandler(err)
}
}()
})
return nil
}

View File

@ -1,218 +1,29 @@
package openwechat
import (
"os"
"testing"
"time"
)
func defaultBot(modes ...mode) *Bot {
bot := DefaultBot(modes...)
bot.UUIDCallback = PrintlnQrcodeUrl
return bot
}
func getSelf(modes ...mode) (*Self, error) {
bot := defaultBot(modes...)
if err := bot.Login(); err != nil {
return nil, err
}
return bot.GetCurrentUser()
}
func TestBotLogin(t *testing.T) {
bot := defaultBot()
if err := bot.Login(); err != nil {
t.Error(err)
return
}
self, err := bot.GetCurrentUser()
if err != nil {
t.Error(err)
return
}
t.Log(self.NickName)
}
func TestMessage(t *testing.T) {
bot := defaultBot()
bot.MessageHandler = func(msg *Message) {
t.Log(msg.MsgType)
t.Log(msg.Content)
if msg.IsMedia() {
t.Log(msg.Content)
t.Log(msg.FileName)
}
if msg.IsCard() {
c, _ := msg.Card()
t.Log(c.Alias)
}
if msg.IsSystem() {
t.Log(msg.Content)
}
if msg.IsRecalled() {
t.Log(msg.Content)
}
func TestLogin(t *testing.T) {
bot := DefaultBot(Desktop)
bot.LoginCallBack = func(body []byte) {
t.Log("login success")
}
if err := bot.Login(); err != nil {
t.Error(err)
return
}
bot.Block()
}
func TestFriend(t *testing.T) {
self, err := getSelf()
if err != nil {
t.Error(err)
return
}
friends, err := self.Friends()
if err != nil {
t.Error(err)
return
}
t.Log(friends)
}
func TestGroup(t *testing.T) {
self, err := getSelf()
if err != nil {
t.Error(err)
return
}
group, err := self.Groups()
if err != nil {
t.Error(err)
return
}
t.Log(group)
g := group.SearchByNickName(1, "杭州Gopher群组")
if g.First() != nil {
members, err := g.First().Members()
if err != nil {
t.Error(err)
return
}
t.Log(members.Count())
}
}
func TestMps(t *testing.T) {
self, err := getSelf()
if err != nil {
t.Error(err)
return
}
mps, err := self.Mps()
if err != nil {
t.Error(err)
return
}
t.Log(mps)
}
func TestAddFriendIntoChatRoom(t *testing.T) {
self, err := getSelf(Desktop)
if err != nil {
t.Error(err)
return
}
groups, err := self.Groups()
if err != nil {
t.Error(err)
return
}
friends, err := self.Friends()
if err != nil {
t.Error(err)
return
}
searchGroups := groups.SearchByNickName(1, "厉害了")
if g := searchGroups.First(); g != nil {
addFriends := friends.SearchByRemarkName(1, "1")
if err := g.AddFriendsIn(addFriends...); err != nil {
t.Error(err)
}
}
}
func TestRemoveFriendIntoChatRoom(t *testing.T) {
self, err := getSelf()
if err != nil {
t.Error(err)
return
}
groups, err := self.Groups()
if err != nil {
t.Error(err)
return
}
friends, err := self.Friends()
if err != nil {
t.Error(err)
return
}
searchGroups := groups.SearchByNickName(1, "厉害了")
if g := searchGroups.First(); g != nil {
addFriends := friends.SearchByRemarkName(1, "大爷")
if f := addFriends.First(); f != nil {
if err := g.RemoveMembers(Members{f.User}); err != nil {
t.Error(err)
}
}
}
}
func TestLogout(t *testing.T) {
bot := defaultBot(Desktop)
bot := DefaultBot(Desktop)
bot.LoginCallBack = func(body []byte) {
t.Log("login success")
}
bot.LogoutCallBack = func(bot *Bot) {
t.Log("logout")
}
bot.MessageHandler = func(msg *Message) {
if msg.Content == "logout" {
msg.Bot.Logout()
}
}
if err := bot.Login(); err != nil {
t.Error(err)
return
}
bot.Block()
}
func TestSendMessage(t *testing.T) {
bot := defaultBot(Desktop)
if err := bot.Login(); err != nil {
t.Error(err)
return
}
self, err := bot.GetCurrentUser()
if err != nil {
t.Error(err)
return
}
helper, err := self.FileHelper()
if err != nil {
t.Error(err)
return
}
if _, err = helper.SendText("test message! received ?"); err != nil {
t.Error(err)
return
}
time.Sleep(time.Second)
if _, err = self.SendTextToFriend(helper, "send test message twice ! received?"); err != nil {
t.Error(err)
return
}
}
func TestAgreeFriendsAdd(t *testing.T) {
bot := defaultBot()
bot.MessageHandler = func(msg *Message) {
msg.Sender()
if msg.IsFriendAdd() {
if err := msg.Agree(); err != nil {
t.Error(err)
}
if msg.IsText() && msg.Content == "logout" {
bot.Logout()
}
}
@ -223,155 +34,54 @@ func TestAgreeFriendsAdd(t *testing.T) {
bot.Block()
}
func TestHotLogin(t *testing.T) {
filename := "test.json"
bot := defaultBot()
s := NewJsonFileHotReloadStorage(filename)
if err := bot.HotLogin(s); err != nil {
t.Error(err)
return
}
self, err := bot.GetCurrentUser()
if err != nil {
t.Error(err)
return
}
t.Log(self.NickName)
}
func TestFriendHelper(t *testing.T) {
bot := defaultBot(Desktop)
if err := bot.HotLogin(NewJsonFileHotReloadStorage("2.json"), true); err != nil {
t.Error(err)
return
}
self, err := bot.GetCurrentUser()
if err != nil {
t.Error(err)
return
}
fh, err := self.FileHelper()
if err != nil {
t.Error(err)
return
}
f, _ := os.Open("run")
defer f.Close()
msg, err := fh.SendFile(f)
if err != nil {
t.Error(err)
return
}
t.Log(msg.MsgId)
}
func TestRevokeMessage(t *testing.T) {
bot := defaultBot(Desktop)
if err := bot.HotLogin(NewJsonFileHotReloadStorage("2.json")); err != nil {
t.Error(err)
return
}
self, err := bot.GetCurrentUser()
if err != nil {
t.Error(err)
return
}
friends, err := self.Friends()
if err != nil {
t.Error(err)
return
}
fs := friends.SearchByRemarkName(1, "1")
ms, err := fs.First().SendText("test")
if err != nil {
t.Error(err)
return
}
time.Sleep(time.Second)
if err := ms.Revoke(); err != nil {
t.Error(err)
}
}
func TestSendFile(t *testing.T) {
bot := defaultBot(Desktop)
if err := bot.HotLogin(NewJsonFileHotReloadStorage("2.json"), true); err != nil {
t.Error(err)
return
}
self, err := bot.GetCurrentUser()
if err != nil {
t.Error(err)
return
}
fh, err := self.FileHelper()
if err != nil {
t.Error(err)
return
}
f, _ := os.Open("README.md")
defer f.Close()
msg, err := fh.SendFile(f)
if err != nil {
t.Error(err)
return
}
t.Log(msg.MsgId)
}
func TestForwardMessage(t *testing.T) {
bot := defaultBot(Desktop)
if err := bot.HotLogin(NewJsonFileHotReloadStorage("2.json"), true); err != nil {
t.Error(err)
return
}
self, err := bot.GetCurrentUser()
if err != nil {
t.Error(err)
return
}
groups, err := self.Groups()
if err != nil {
t.Error(err)
return
}
f, _ := os.Open("README.md")
defer f.Close()
sentM, err := self.SendFileToGroup(groups.First(), f)
if err != nil {
t.Log(err)
return
}
self.ForwardMessageToGroups(sentM, groups...)
}
func TestMessageMatchDispatcher(t *testing.T) {
dispatcher := NewMessageMatchDispatcher()
m1 := func(ctx *MessageContext) {
if ctx.Content == "ping" {
ctx.ReplyText("pong")
}
ctx.Next()
t.Log("处理完毕~")
}
m2 := func(ctx *MessageContext) {
if ctx.Content == "hello" {
ctx.ReplyText("world")
func TestMessageHandle(t *testing.T) {
bot := DefaultBot(Desktop)
bot.MessageHandler = func(msg *Message) {
if msg.IsText() && msg.Content == "ping" {
msg.ReplyText("pong")
}
}
dispatcher.OnText(m1, m2)
dispatcher.OnFriendByRemarkName("1", func(ctx *MessageContext) { ctx.ReplyText("我收到了你的信息了") })
bot := defaultBot(Desktop)
bot.MessageHandler = DispatchMessage(dispatcher)
if err := bot.Login(); err != nil {
t.Error(err)
return
}
bot.Block()
}
func TestFriends(t *testing.T) {
bot := DefaultBot(Desktop)
if err := bot.Login(); err != nil {
t.Error(err)
return
}
user, err := bot.GetCurrentUser()
if err != nil {
t.Error(err)
return
}
friends, err := user.Friends()
if err != nil {
t.Error(err)
return
}
t.Log(friends)
}
func TestGroups(t *testing.T) {
bot := DefaultBot(Desktop)
if err := bot.Login(); err != nil {
t.Error(err)
return
}
user, err := bot.GetCurrentUser()
if err != nil {
t.Error(err)
return
}
groups, err := user.Groups()
if err != nil {
t.Error(err)
return
}
t.Log(groups)
}

View File

@ -9,20 +9,6 @@ func TestFormatEmoji(t *testing.T) {
t.Log(FormatEmoji(`多吃点苹果<span class="emoji emoji1f34f"></span>高兴<span class="emoji emoji1f604"></span><span class="emoji emoji1f604"></span><span class="emoji emoji1f604"></span> 生气<span class="emoji emoji1f64e"></span> 点赞<span class="emoji emoji1f44d"></span>`))
}
func TestSendEmoji(t *testing.T) {
self, err := getSelf()
if err != nil {
t.Error(err)
return
}
f, err := self.FileHelper()
if err != nil {
t.Error(err)
return
}
_, _ = f.SendText(Emoji.Dagger)
}
func BenchmarkFormatEmojiString(b *testing.B) {
str := `多吃点苹果<span class="emoji emoji1f34f"></span>高兴<span class="emoji emoji1f604"></span><span class="emoji emoji1f604"></span><span class="emoji emoji1f604"></span> 生气<span class="emoji emoji1f64e"></span> 点赞<span class="emoji emoji1f44d"></span>`
b.SetBytes(int64(len(str)))