diff --git a/bot.go b/bot.go index 422590b..958aefb 100644 --- a/bot.go +++ b/bot.go @@ -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 } diff --git a/bot_test.go b/bot_test.go index 1a58127..8a69621 100644 --- a/bot_test.go +++ b/bot_test.go @@ -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) +} diff --git a/emoji_test.go b/emoji_test.go index cfad054..9c2029e 100644 --- a/emoji_test.go +++ b/emoji_test.go @@ -9,20 +9,6 @@ func TestFormatEmoji(t *testing.T) { t.Log(FormatEmoji(`多吃点苹果高兴 生气 点赞`)) } -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 := `多吃点苹果高兴 生气 点赞` b.SetBytes(int64(len(str)))