优化底层逻辑和增加self的行为

This commit is contained in:
eatMoreApple 2021-04-27 11:02:20 +08:00
parent 7d93aa7b3a
commit 7ddcde9ab6
2 changed files with 634 additions and 516 deletions

View File

@ -1,7 +1,6 @@
package openwechat package openwechat
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
"strings" "strings"
@ -17,32 +16,27 @@ func (f Friend) String() string {
// 重命名当前好友 // 重命名当前好友
func (f *Friend) SetRemarkName(name string) error { func (f *Friend) SetRemarkName(name string) error {
return f.setRemarkName(name) return f.Self.SetRemarkNameToFriend(f, name)
} }
// 发送自定义消息 // 发送自定义消息
func (f *Friend) SendMsg(msg *SendMessage) error { func (f *Friend) SendMsg(msg *SendMessage) error {
return f.sendMsg(msg) return f.Self.SendMessageToFriend(f, msg)
} }
// 发送文本消息 // 发送文本消息
func (f *Friend) SendText(content string) error { func (f *Friend) SendText(content string) error {
return f.sendText(content) return f.Self.SendTextToFriend(f, content)
} }
// 发送图片消息 // 发送图片消息
func (f *Friend) SendImage(file *os.File) error { func (f *Friend) SendImage(file *os.File) error {
return f.sendImage(file) return f.Self.SendImageToFriend(f, file)
} }
// 拉该好友入群 // 拉该好友入群
func (f *Friend) AddIntoGroup(groups ...*Group) error { func (f *Friend) AddIntoGroup(groups ...*Group) error {
for _, group := range groups { return f.Self.AddFriendIntoManyGroups(f, groups...)
if err := group.AddFriendsIn(f); err != nil {
return err
}
}
return nil
} }
type Friends []*Friend type Friends []*Friend
@ -134,6 +128,7 @@ func (f Friends) SendText(text string, delay ...time.Duration) error {
return nil return nil
} }
// 向slice的好友依次发送图片消息
func (f Friends) SendImage(file *os.File, delay ...time.Duration) error { func (f Friends) SendImage(file *os.File, delay ...time.Duration) error {
for _, friend := range f { for _, friend := range f {
if len(delay) != 0 { if len(delay) != 0 {
@ -153,16 +148,19 @@ func (g Group) String() string {
return fmt.Sprintf("<Group:%s>", g.NickName) return fmt.Sprintf("<Group:%s>", g.NickName)
} }
// 发行消息给当前的群组
func (g *Group) SendMsg(msg *SendMessage) error { func (g *Group) SendMsg(msg *SendMessage) error {
return g.sendMsg(msg) return g.Self.SendMessageToGroup(g, msg)
} }
// 发行文本消息给当前的群组
func (g *Group) SendText(content string) error { func (g *Group) SendText(content string) error {
return g.sendText(content) return g.Self.SendTextToGroup(g, content)
} }
// 发行图片消息给当前的群组
func (g *Group) SendImage(file *os.File) error { func (g *Group) SendImage(file *os.File) error {
return g.sendImage(file) return g.Self.SendImageToGroup(g, file)
} }
// 获取所有的群成员 // 获取所有的群成员
@ -176,62 +174,24 @@ func (g *Group) Members() (Members, error) {
// 拉好友入群 // 拉好友入群
func (g *Group) AddFriendsIn(friends ...*Friend) error { func (g *Group) AddFriendsIn(friends ...*Friend) error {
if len(friends) == 0 { return g.Self.AddFriendsIntoGroup(g, friends...)
return nil
}
groupMembers, err := g.Members()
if err != nil {
return err
}
for _, friend := range friends {
for _, member := range groupMembers {
if member.UserName == friend.UserName {
return fmt.Errorf("user %s has alreay in this group", friend.String())
}
}
}
req := g.Self.Bot.storage.Request
info := g.Self.Bot.storage.LoginInfo
return g.Self.Bot.Caller.AddFriendIntoChatRoom(req, info, g, friends...)
} }
// 从群聊中移除用户 // 从群聊中移除用户
// Deprecated // Deprecated
// 无论是网页版,还是程序上都不起作用 // 无论是网页版,还是程序上都不起作用
func (g *Group) RemoveMembers(members Members) error { func (g *Group) RemoveMembers(members Members) error {
if len(members) == 0 { return g.Self.RemoveMemberFromGroup(g, members)
return nil
}
if g.IsOwner == 0 {
return errors.New("group owner required")
}
groupMembers, err := g.Members()
if err != nil {
return err
}
// 判断用户是否在群聊中
var count int
for _, member := range members {
for _, gm := range groupMembers {
if gm.UserName == member.UserName {
count++
}
}
}
if count != len(members) {
return errors.New("invalid members")
}
req := g.Self.Bot.storage.Request
info := g.Self.Bot.storage.LoginInfo
return g.Self.Bot.Caller.RemoveFriendFromChatRoom(req, info, g, members...)
} }
type Groups []*Group type Groups []*Group
// 获取群组数量
func (g Groups) Count() int { func (g Groups) Count() int {
return len(g) return len(g)
} }
// 获取第一个群组
func (g Groups) First() *Group { func (g Groups) First() *Group {
if g.Count() > 0 { if g.Count() > 0 {
return g[0] return g[0]
@ -239,6 +199,7 @@ func (g Groups) First() *Group {
return nil return nil
} }
// 获取最后一个群组
func (g Groups) Last() *Group { func (g Groups) Last() *Group {
if g.Count() > 0 { if g.Count() > 0 {
return g[g.Count()-1] return g[g.Count()-1]
@ -246,11 +207,14 @@ func (g Groups) Last() *Group {
return nil return nil
} }
// 向群组依次发送消息, 支持发送延迟
func (g Groups) SendMsg(msg *SendMessage, delay ...time.Duration) error { func (g Groups) SendMsg(msg *SendMessage, delay ...time.Duration) error {
for _, group := range g { var total time.Duration
if len(delay) != 0 { for _, d := range delay {
time.Sleep(delay[0]) total += d
} }
for _, group := range g {
time.Sleep(total)
if err := group.SendMsg(msg); err != nil { if err := group.SendMsg(msg); err != nil {
return err return err
} }
@ -258,11 +222,14 @@ func (g Groups) SendMsg(msg *SendMessage, delay ...time.Duration) error {
return nil return nil
} }
// 向群组依次发送文本消息, 支持发送延迟
func (g Groups) SendText(text string, delay ...time.Duration) error { func (g Groups) SendText(text string, delay ...time.Duration) error {
for _, group := range g { var total time.Duration
if len(delay) != 0 { for _, d := range delay {
time.Sleep(delay[0]) total += d
} }
for _, group := range g {
time.Sleep(total)
if err := group.SendText(text); err != nil { if err := group.SendText(text); err != nil {
return err return err
} }
@ -270,11 +237,14 @@ func (g Groups) SendText(text string, delay ...time.Duration) error {
return nil return nil
} }
// 向群组依次发送图片消息, 支持发送延迟
func (g Groups) SendImage(file *os.File, delay ...time.Duration) error { func (g Groups) SendImage(file *os.File, delay ...time.Duration) error {
for _, group := range g { var total time.Duration
if len(delay) != 0 { for _, d := range delay {
time.Sleep(delay[0]) total += d
} }
for _, group := range g {
time.Sleep(total)
if err := group.SendImage(file); err != nil { if err := group.SendImage(file); err != nil {
return err return err
} }
@ -282,18 +252,22 @@ func (g Groups) SendImage(file *os.File, delay ...time.Duration) error {
return nil return nil
} }
// 根据用户名查找群组
func (g Groups) SearchByUserName(limit int, username string) (results Groups) { func (g Groups) SearchByUserName(limit int, username string) (results Groups) {
return g.Search(limit, func(group *Group) bool { return group.UserName == username }) return g.Search(limit, func(group *Group) bool { return group.UserName == username })
} }
// 根据昵称查找群组
func (g Groups) SearchByNickName(limit int, nickName string) (results Groups) { func (g Groups) SearchByNickName(limit int, nickName string) (results Groups) {
return g.Search(limit, func(group *Group) bool { return group.NickName == nickName }) return g.Search(limit, func(group *Group) bool { return group.NickName == nickName })
} }
// 根据备注查找群组
func (g Groups) SearchByRemarkName(limit int, remarkName string) (results Groups) { func (g Groups) SearchByRemarkName(limit int, remarkName string) (results Groups) {
return g.Search(limit, func(group *Group) bool { return group.RemarkName == remarkName }) return g.Search(limit, func(group *Group) bool { return group.RemarkName == remarkName })
} }
// 根据自定义条件查找群组
func (g Groups) Search(limit int, condFuncList ...func(group *Group) bool) (results Groups) { func (g Groups) Search(limit int, condFuncList ...func(group *Group) bool) (results Groups) {
if condFuncList == nil { if condFuncList == nil {
return g return g
@ -318,30 +292,22 @@ func (g Groups) Search(limit int, condFuncList ...func(group *Group) bool) (resu
return return
} }
func isFriend(user User) bool { // 公众号对象
return !isGroup(user) && strings.HasPrefix(user.UserName, "@") && user.VerifyFlag == 0
}
func isGroup(user User) bool {
return strings.HasPrefix(user.UserName, "@@") && user.VerifyFlag == 0
}
func isMP(user User) bool {
return user.VerifyFlag == 8 || user.VerifyFlag == 24 || user.VerifyFlag == 136
}
type Mp struct{ *User } type Mp struct{ *User }
func (m Mp) String() string { func (m Mp) String() string {
return fmt.Sprintf("<Mp:%s>", m.NickName) return fmt.Sprintf("<Mp:%s>", m.NickName)
} }
// 公众号组对象
type Mps []*Mp type Mps []*Mp
// 数量统计
func (m Mps) Count() int { func (m Mps) Count() int {
return len(m) return len(m)
} }
// 获取第一个
func (m Mps) First() *Mp { func (m Mps) First() *Mp {
if m.Count() > 0 { if m.Count() > 0 {
return m[0] return m[0]
@ -349,6 +315,7 @@ func (m Mps) First() *Mp {
return nil return nil
} }
// 获取最后一个
func (m Mps) Last() *Mp { func (m Mps) Last() *Mp {
if m.Count() > 0 { if m.Count() > 0 {
return m[m.Count()-1] return m[m.Count()-1]
@ -356,6 +323,7 @@ func (m Mps) Last() *Mp {
return nil return nil
} }
// 根据自定义条件查找
func (m Mps) Search(limit int, condFuncList ...func(group *Mp) bool) (results Mps) { func (m Mps) Search(limit int, condFuncList ...func(group *Mp) bool) (results Mps) {
if condFuncList == nil { if condFuncList == nil {
return m return m
@ -379,3 +347,18 @@ func (m Mps) Search(limit int, condFuncList ...func(group *Mp) bool) (results Mp
} }
return return
} }
// 判断是否为好友
func isFriend(user User) bool {
return !isGroup(user) && strings.HasPrefix(user.UserName, "@") && user.VerifyFlag == 0
}
// 判断是否为群组
func isGroup(user User) bool {
return strings.HasPrefix(user.UserName, "@@") && user.VerifyFlag == 0
}
// 判断是否为公众号
func isMP(user User) bool {
return user.VerifyFlag == 8 || user.VerifyFlag == 24 || user.VerifyFlag == 136
}

161
user.go
View File

@ -2,6 +2,7 @@ package openwechat
import ( import (
"bytes" "bytes"
"errors"
"fmt" "fmt"
"net/http" "net/http"
"os" "os"
@ -18,6 +19,19 @@ type User struct {
WebWxPluginSwitch int WebWxPluginSwitch int
HeadImgFlag int HeadImgFlag int
SnsFlag int SnsFlag int
IsOwner int
MemberCount int
ChatRoomId int
UniFriend int
OwnerUin int
Statues int
AttrStatus int
Province string
City string
Alias string
DisplayName string
KeyWord string
EncryChatRoomId string
UserName string UserName string
NickName string NickName string
HeadImgUrl string HeadImgUrl string
@ -27,20 +41,8 @@ type User struct {
RemarkPYInitial string RemarkPYInitial string
RemarkPYQuanPin string RemarkPYQuanPin string
Signature string Signature string
MemberCount int
MemberList Members MemberList Members
OwnerUin int
Statues int
AttrStatus int
Province string
City string
Alias string
UniFriend int
DisplayName string
ChatRoomId int
KeyWord string
EncryChatRoomId string
IsOwner int
Self *Self Self *Self
} }
@ -75,6 +77,7 @@ func (u *User) SaveAvatar(filename string) error {
return err return err
} }
// Deprecated
func (u *User) sendMsg(msg *SendMessage) error { func (u *User) sendMsg(msg *SendMessage) error {
msg.FromUserName = u.Self.UserName msg.FromUserName = u.Self.UserName
msg.ToUserName = u.UserName msg.ToUserName = u.UserName
@ -83,17 +86,20 @@ func (u *User) sendMsg(msg *SendMessage) error {
return u.Self.Bot.Caller.WebWxSendMsg(msg, info, request) return u.Self.Bot.Caller.WebWxSendMsg(msg, info, request)
} }
// Deprecated
func (u *User) sendText(content string) error { func (u *User) sendText(content string) error {
msg := NewTextSendMessage(content, u.Self.UserName, u.UserName) msg := NewTextSendMessage(content, u.Self.UserName, u.UserName)
return u.sendMsg(msg) return u.sendMsg(msg)
} }
// Deprecated
func (u *User) sendImage(file *os.File) error { func (u *User) sendImage(file *os.File) error {
request := u.Self.Bot.storage.Request request := u.Self.Bot.storage.Request
info := u.Self.Bot.storage.LoginInfo info := u.Self.Bot.storage.LoginInfo
return u.Self.Bot.Caller.WebWxSendImageMsg(file, request, info, u.Self.UserName, u.UserName) return u.Self.Bot.Caller.WebWxSendImageMsg(file, request, info, u.Self.UserName, u.UserName)
} }
// Deprecated
func (u *User) setRemarkName(remarkName string) error { func (u *User) setRemarkName(remarkName string) error {
request := u.Self.Bot.storage.Request request := u.Self.Bot.storage.Request
return u.Self.Bot.Caller.WebWxOplog(request, remarkName, u.UserName) return u.Self.Bot.Caller.WebWxOplog(request, remarkName, u.UserName)
@ -112,6 +118,7 @@ func (u *User) Detail() (*User, error) {
return user, nil return user, nil
} }
// 自己,当前登录用户对象
type Self struct { type Self struct {
*User *User
Bot *Bot Bot *Bot
@ -250,6 +257,7 @@ func (s *Self) updateGroups(update ...bool) error {
return nil return nil
} }
// 更新公众号处理
func (s *Self) updateMps(update ...bool) error { func (s *Self) updateMps(update ...bool) error {
var isUpdate bool var isUpdate bool
if len(update) > 0 { if len(update) > 0 {
@ -324,12 +332,132 @@ func (s *Self) UpdateMembersDetail() error {
return nil return nil
} }
// 抽象发送消息接口
func (s *Self) sendMessageToUser(user *User, msg *SendMessage) error {
msg.FromUserName = s.UserName
msg.ToUserName = user.UserName
info := s.Bot.storage.LoginInfo
request := s.Bot.storage.Request
return s.Bot.Caller.WebWxSendMsg(msg, info, request)
}
// 发送消息给好友
func (s *Self) SendMessageToFriend(friend *Friend, msg *SendMessage) error {
return s.sendMessageToUser(friend.User, msg)
}
// 发送文本消息给好友
func (s *Self) SendTextToFriend(friend *Friend, text string) error {
msg := NewTextSendMessage(text, s.UserName, friend.UserName)
return s.SendMessageToFriend(friend, msg)
}
// 发送图片消息给好友
func (s *Self) SendImageToFriend(friend *Friend, file *os.File) error {
req := s.Bot.storage.Request
info := s.Bot.storage.LoginInfo
return s.Bot.Caller.WebWxSendImageMsg(file, req, info, s.UserName, friend.UserName)
}
// 设置好友备注
func (s *Self) SetRemarkNameToFriend(friend *Friend, remarkName string) error {
req := s.Bot.storage.Request
return s.Bot.Caller.WebWxOplog(req, remarkName, friend.UserName)
}
// 拉多名好友进群
// 最好自己是群主,成功率高一点,因为有的群允许非群组拉人,而有的群不允许
func (s *Self) AddFriendsIntoGroup(group *Group, friends ...*Friend) error {
if len(friends) == 0 {
return nil
}
// 获取群的所有的群员
groupMembers, err := group.Members()
if err != nil {
return err
}
// 判断当前的成员在不在群里面
for _, friend := range friends {
for _, member := range groupMembers {
if member.UserName == friend.UserName {
return fmt.Errorf("user %s has alreay in this group", friend.String())
}
}
}
req := s.Bot.storage.Request
info := s.Bot.storage.LoginInfo
return s.Bot.Caller.AddFriendIntoChatRoom(req, info, group, friends...)
}
// 从群聊中移除用户
// Deprecated
// 无论是网页版,还是程序上都不起作用
func (s *Self) RemoveMemberFromGroup(group *Group, members Members) error {
if len(members) == 0 {
return nil
}
if group.IsOwner == 0 {
return errors.New("group owner required")
}
groupMembers, err := group.Members()
if err != nil {
return err
}
// 判断用户是否在群聊中
var count int
for _, member := range members {
for _, gm := range groupMembers {
if gm.UserName == member.UserName {
count++
}
}
}
if count != len(members) {
return errors.New("invalid members")
}
req := s.Bot.storage.Request
info := s.Bot.storage.LoginInfo
return s.Bot.Caller.RemoveFriendFromChatRoom(req, info, group, members...)
}
// 拉好友进多个群聊
// AddFriendIntoGroups, 名字和上面的有点像
func (s *Self) AddFriendIntoManyGroups(friend *Friend, groups ...*Group) error {
for _, group := range groups {
if err := s.AddFriendsIntoGroup(group, friend); err != nil {
return err
}
}
return nil
}
// 发送消息给群组
func (s *Self) SendMessageToGroup(group *Group, msg *SendMessage) error {
return s.sendMessageToUser(group.User, msg)
}
// 发送文本消息给群组
func (s *Self) SendTextToGroup(group *Group, text string) error {
msg := NewTextSendMessage(text, s.UserName, group.UserName)
return s.SendMessageToGroup(group, msg)
}
// 发送图片消息给群组
func (s *Self) SendImageToGroup(group *Group, file *os.File) error {
req := s.Bot.storage.Request
info := s.Bot.storage.LoginInfo
return s.Bot.Caller.WebWxSendImageMsg(file, req, info, s.UserName, group.UserName)
}
// 抽象的用户组
type Members []*User type Members []*User
// 统计数量
func (m Members) Count() int { func (m Members) Count() int {
return len(m) return len(m)
} }
// 获取第一个
func (m Members) First() *User { func (m Members) First() *User {
if m.Count() > 0 { if m.Count() > 0 {
u := m[0] u := m[0]
@ -338,6 +466,7 @@ func (m Members) First() *User {
return nil return nil
} }
// 获取最后一个
func (m Members) Last() *User { func (m Members) Last() *User {
if m.Count() > 0 { if m.Count() > 0 {
u := m[m.Count()-1] u := m[m.Count()-1]
@ -346,24 +475,30 @@ func (m Members) Last() *User {
return nil return nil
} }
// 设置owner
// 请不要随意设置
func (m Members) SetOwner(s *Self) { func (m Members) SetOwner(s *Self) {
for _, member := range m { for _, member := range m {
member.Self = s member.Self = s
} }
} }
// 根据用户名查找
func (m Members) SearchByUserName(limit int, username string) (results Members) { func (m Members) SearchByUserName(limit int, username string) (results Members) {
return m.Search(limit, func(user *User) bool { return user.UserName == username }) return m.Search(limit, func(user *User) bool { return user.UserName == username })
} }
// 根据昵称查找
func (m Members) SearchByNickName(limit int, nickName string) (results Members) { func (m Members) SearchByNickName(limit int, nickName string) (results Members) {
return m.Search(limit, func(user *User) bool { return user.NickName == nickName }) return m.Search(limit, func(user *User) bool { return user.NickName == nickName })
} }
// 根据备注查找
func (m Members) SearchByRemarkName(limit int, remarkName string) (results Members) { func (m Members) SearchByRemarkName(limit int, remarkName string) (results Members) {
return m.Search(limit, func(user *User) bool { return user.RemarkName == remarkName }) return m.Search(limit, func(user *User) bool { return user.RemarkName == remarkName })
} }
// 根据自定义条件查找
func (m Members) Search(limit int, condFuncList ...func(user *User) bool) (results Members) { func (m Members) Search(limit int, condFuncList ...func(user *User) bool) (results Members) {
if condFuncList == nil { if condFuncList == nil {
return m return m