优化底层逻辑和增加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,381 +1,364 @@
package openwechat package openwechat
import ( import (
"errors" "fmt"
"fmt" "os"
"os" "strings"
"strings" "time"
"time"
) )
type Friend struct{ *User } type Friend struct{ *User }
// implement fmt.Stringer // implement fmt.Stringer
func (f Friend) String() string { func (f Friend) String() string {
return fmt.Sprintf("<Friend:%s>", f.NickName) return fmt.Sprintf("<Friend:%s>", f.NickName)
} }
// 重命名当前好友 // 重命名当前好友
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
// 获取好友的数量 // 获取好友的数量
func (f Friends) Count() int { func (f Friends) Count() int {
return len(f) return len(f)
} }
// 获取第一个好友 // 获取第一个好友
func (f Friends) First() *Friend { func (f Friends) First() *Friend {
if f.Count() > 0 { if f.Count() > 0 {
return f[0] return f[0]
} }
return nil return nil
} }
// 获取最后一个好友 // 获取最后一个好友
func (f Friends) Last() *Friend { func (f Friends) Last() *Friend {
if f.Count() > 0 { if f.Count() > 0 {
return f[f.Count()-1] return f[f.Count()-1]
} }
return nil return nil
} }
// 根据用户名查找好友 // 根据用户名查找好友
func (f Friends) SearchByUserName(limit int, username string) (results Friends) { func (f Friends) SearchByUserName(limit int, username string) (results Friends) {
return f.Search(limit, func(friend *Friend) bool { return friend.User.UserName == username }) return f.Search(limit, func(friend *Friend) bool { return friend.User.UserName == username })
} }
// 根据昵称查找好友 // 根据昵称查找好友
func (f Friends) SearchByNickName(limit int, nickName string) (results Friends) { func (f Friends) SearchByNickName(limit int, nickName string) (results Friends) {
return f.Search(limit, func(friend *Friend) bool { return friend.User.NickName == nickName }) return f.Search(limit, func(friend *Friend) bool { return friend.User.NickName == nickName })
} }
// 根据备注查找好友 // 根据备注查找好友
func (f Friends) SearchByRemarkName(limit int, remarkName string) (results Friends) { func (f Friends) SearchByRemarkName(limit int, remarkName string) (results Friends) {
return f.Search(limit, func(friend *Friend) bool { return friend.User.RemarkName == remarkName }) return f.Search(limit, func(friend *Friend) bool { return friend.User.RemarkName == remarkName })
} }
// 根据自定义条件查找好友 // 根据自定义条件查找好友
func (f Friends) Search(limit int, condFuncList ...func(friend *Friend) bool) (results Friends) { func (f Friends) Search(limit int, condFuncList ...func(friend *Friend) bool) (results Friends) {
if condFuncList == nil { if condFuncList == nil {
return f return f
} }
if limit <= 0 { if limit <= 0 {
limit = f.Count() limit = f.Count()
} }
for _, member := range f { for _, member := range f {
if results.Count() == limit { if results.Count() == limit {
break break
} }
var passCount int var passCount int
for _, condFunc := range condFuncList { for _, condFunc := range condFuncList {
if condFunc(member) { if condFunc(member) {
passCount++ passCount++
} }
} }
if passCount == len(condFuncList) { if passCount == len(condFuncList) {
results = append(results, member) results = append(results, member)
} }
} }
return return
} }
// 向slice的好友依次发送消息 // 向slice的好友依次发送消息
func (f Friends) SendMsg(msg *SendMessage, delay ...time.Duration) error { func (f Friends) SendMsg(msg *SendMessage, delay ...time.Duration) error {
for _, friend := range f { for _, friend := range f {
if len(delay) != 0 { if len(delay) != 0 {
time.Sleep(delay[0]) time.Sleep(delay[0])
} }
if err := friend.SendMsg(msg); err != nil { if err := friend.SendMsg(msg); err != nil {
return err return err
} }
} }
return nil return nil
} }
// 向slice的好友依次发送文本消息 // 向slice的好友依次发送文本消息
func (f Friends) SendText(text string, delay ...time.Duration) error { func (f Friends) SendText(text string, delay ...time.Duration) error {
for _, friend := range f { for _, friend := range f {
if len(delay) != 0 { if len(delay) != 0 {
time.Sleep(delay[0]) time.Sleep(delay[0])
} }
if err := friend.SendText(text); err != nil { if err := friend.SendText(text); err != nil {
return err return err
} }
} }
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 {
time.Sleep(delay[0]) time.Sleep(delay[0])
} }
if err := friend.SendImage(file); err != nil { if err := friend.SendImage(file); err != nil {
return err return err
} }
} }
return nil return nil
} }
type Group struct{ *User } type Group struct{ *User }
// implement fmt.Stringer // implement fmt.Stringer
func (g Group) String() string { 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)
} }
// 获取所有的群成员 // 获取所有的群成员
func (g *Group) Members() (Members, error) { func (g *Group) Members() (Members, error) {
group, err := g.Detail() group, err := g.Detail()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return group.MemberList, nil return group.MemberList, nil
} }
// 拉好友入群 // 拉好友入群
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]
} }
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]
} }
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
} }
if err := group.SendMsg(msg); err != nil { for _, group := range g {
return err time.Sleep(total)
} if err := group.SendMsg(msg); err != nil {
} return err
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
} }
if err := group.SendText(text); err != nil { for _, group := range g {
return err time.Sleep(total)
} if err := group.SendText(text); err != nil {
} return err
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
} }
if err := group.SendImage(file); err != nil { for _, group := range g {
return err time.Sleep(total)
} if err := group.SendImage(file); err != nil {
} return err
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
} }
if limit <= 0 { if limit <= 0 {
limit = g.Count() limit = g.Count()
} }
for _, member := range g { for _, member := range g {
if results.Count() == limit { if results.Count() == limit {
break break
} }
var passCount int var passCount int
for _, condFunc := range condFuncList { for _, condFunc := range condFuncList {
if condFunc(member) { if condFunc(member) {
passCount++ passCount++
} }
} }
if passCount == len(condFuncList) { if passCount == len(condFuncList) {
results = append(results, member) results = append(results, member)
} }
} }
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]
} }
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]
} }
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
} }
if limit <= 0 { if limit <= 0 {
limit = m.Count() limit = m.Count()
} }
for _, member := range m { for _, member := range m {
if results.Count() == limit { if results.Count() == limit {
break break
} }
var passCount int var passCount int
for _, condFunc := range condFuncList { for _, condFunc := range condFuncList {
if condFunc(member) { if condFunc(member) {
passCount++ passCount++
} }
} }
if passCount == len(condFuncList) { if passCount == len(condFuncList) {
results = append(results, member) results = append(results, member)
} }
} }
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
} }

707
user.go
View File

@ -1,391 +1,526 @@
package openwechat package openwechat
import ( import (
"bytes" "bytes"
"fmt" "errors"
"net/http" "fmt"
"os" "net/http"
"os"
) )
type User struct { type User struct {
Uin int Uin int
HideInputBarFlag int HideInputBarFlag int
StarFriend int StarFriend int
Sex int Sex int
AppAccountFlag int AppAccountFlag int
VerifyFlag int VerifyFlag int
ContactFlag int ContactFlag int
WebWxPluginSwitch int WebWxPluginSwitch int
HeadImgFlag int HeadImgFlag int
SnsFlag int SnsFlag int
UserName string IsOwner int
NickName string MemberCount int
HeadImgUrl string ChatRoomId int
RemarkName string UniFriend int
PYInitial string OwnerUin int
PYQuanPin string Statues int
RemarkPYInitial string AttrStatus int
RemarkPYQuanPin string Province string
Signature string City string
MemberCount int Alias string
MemberList Members DisplayName string
OwnerUin int KeyWord string
Statues int EncryChatRoomId string
AttrStatus int UserName string
Province string NickName string
City string HeadImgUrl string
Alias string RemarkName string
UniFriend int PYInitial string
DisplayName string PYQuanPin string
ChatRoomId int RemarkPYInitial string
KeyWord string RemarkPYQuanPin string
EncryChatRoomId string Signature string
IsOwner int
Self *Self MemberList Members
Self *Self
} }
// implement fmt.Stringer // implement fmt.Stringer
func (u *User) String() string { func (u *User) String() string {
return fmt.Sprintf("<User:%s>", u.NickName) return fmt.Sprintf("<User:%s>", u.NickName)
} }
// 获取用户头像 // 获取用户头像
func (u *User) GetAvatarResponse() (*http.Response, error) { func (u *User) GetAvatarResponse() (*http.Response, error) {
return u.Self.Bot.Caller.Client.WebWxGetHeadImg(u.HeadImgUrl) return u.Self.Bot.Caller.Client.WebWxGetHeadImg(u.HeadImgUrl)
} }
// 下载用户头像 // 下载用户头像
func (u *User) SaveAvatar(filename string) error { func (u *User) SaveAvatar(filename string) error {
resp, err := u.GetAvatarResponse() resp, err := u.GetAvatarResponse()
if err != nil { if err != nil {
return err return err
} }
defer resp.Body.Close() defer resp.Body.Close()
buffer := bytes.Buffer{} buffer := bytes.Buffer{}
if _, err := buffer.ReadFrom(resp.Body); err != nil { if _, err := buffer.ReadFrom(resp.Body); err != nil {
return err return err
} }
file, err := os.Create(filename) file, err := os.Create(filename)
if err != nil { if err != nil {
return err return err
} }
defer file.Close() defer file.Close()
_, err = file.Write(buffer.Bytes()) _, err = file.Write(buffer.Bytes())
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
info := u.Self.Bot.storage.LoginInfo info := u.Self.Bot.storage.LoginInfo
request := u.Self.Bot.storage.Request request := u.Self.Bot.storage.Request
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)
} }
// 获取用户的详情 // 获取用户的详情
func (u *User) Detail() (*User, error) { func (u *User) Detail() (*User, error) {
members := Members{u} members := Members{u}
request := u.Self.Bot.storage.Request request := u.Self.Bot.storage.Request
newMembers, err := u.Self.Bot.Caller.WebWxBatchGetContact(members, request) newMembers, err := u.Self.Bot.Caller.WebWxBatchGetContact(members, request)
if err != nil { if err != nil {
return nil, err return nil, err
} }
user := newMembers.First() user := newMembers.First()
user.Self = u.Self user.Self = u.Self
return user, nil return user, nil
} }
// 自己,当前登录用户对象
type Self struct { type Self struct {
*User *User
Bot *Bot Bot *Bot
fileHelper *Friend fileHelper *Friend
members Members members Members
friends Friends friends Friends
groups Groups groups Groups
mps Mps mps Mps
} }
// 获取所有的好友、群组、公众号信息 // 获取所有的好友、群组、公众号信息
func (s *Self) Members(update ...bool) (Members, error) { func (s *Self) Members(update ...bool) (Members, error) {
// 首先判断缓存里有没有,如果没有则去更新缓存 // 首先判断缓存里有没有,如果没有则去更新缓存
if s.members == nil { if s.members == nil {
if err := s.updateMembers(); err != nil { if err := s.updateMembers(); err != nil {
return nil, err return nil, err
} }
return s.members, nil return s.members, nil
} }
// 判断是否需要更新,如果传入的参数不为nil,则取最后一个 // 判断是否需要更新,如果传入的参数不为nil,则取最后一个
var isUpdate bool var isUpdate bool
if len(update) > 0 { if len(update) > 0 {
isUpdate = update[len(update)-1] isUpdate = update[len(update)-1]
} }
// 如果需要更新,则直接更新缓存 // 如果需要更新,则直接更新缓存
if isUpdate { if isUpdate {
if err := s.updateMembers(); err != nil { if err := s.updateMembers(); err != nil {
return nil, err return nil, err
} }
} }
return s.members, nil return s.members, nil
} }
// 更新联系人处理 // 更新联系人处理
func (s *Self) updateMembers() error { func (s *Self) updateMembers() error {
info := s.Bot.storage.LoginInfo info := s.Bot.storage.LoginInfo
members, err := s.Bot.Caller.WebWxGetContact(info) members, err := s.Bot.Caller.WebWxGetContact(info)
if err != nil { if err != nil {
return err return err
} }
members.SetOwner(s) members.SetOwner(s)
s.members = members s.members = members
return nil return nil
} }
// 获取文件传输助手对象封装成Friend返回 // 获取文件传输助手对象封装成Friend返回
func (s *Self) FileHelper() (*Friend, error) { func (s *Self) FileHelper() (*Friend, error) {
// 如果缓存里有,直接返回,否则去联系人里面找 // 如果缓存里有,直接返回,否则去联系人里面找
if s.fileHelper != nil { if s.fileHelper != nil {
return s.fileHelper, nil return s.fileHelper, nil
} }
members, err := s.Members() members, err := s.Members()
if err != nil { if err != nil {
return nil, err return nil, err
} }
users := members.SearchByUserName(1, "filehelper") users := members.SearchByUserName(1, "filehelper")
if users == nil { if users == nil {
return nil, noSuchUserFoundError return nil, noSuchUserFoundError
} }
s.fileHelper = &Friend{users.First()} s.fileHelper = &Friend{users.First()}
return s.fileHelper, nil return s.fileHelper, nil
} }
// 获取所有的好友 // 获取所有的好友
func (s *Self) Friends(update ...bool) (Friends, error) { func (s *Self) Friends(update ...bool) (Friends, error) {
if s.friends == nil { if s.friends == nil {
if err := s.updateFriends(update...); err != nil { if err := s.updateFriends(update...); err != nil {
return nil, err return nil, err
} }
} }
return s.friends, nil return s.friends, nil
} }
// 获取所有的群组 // 获取所有的群组
func (s *Self) Groups(update ...bool) (Groups, error) { func (s *Self) Groups(update ...bool) (Groups, error) {
if s.groups == nil { if s.groups == nil {
if err := s.updateGroups(update...); err != nil { if err := s.updateGroups(update...); err != nil {
return nil, err return nil, err
} }
} }
return s.groups, nil return s.groups, nil
} }
// 获取所有的公众号 // 获取所有的公众号
func (s *Self) Mps(update ...bool) (Mps, error) { func (s *Self) Mps(update ...bool) (Mps, error) {
if s.mps == nil { if s.mps == nil {
if err := s.updateMps(update...); err != nil { if err := s.updateMps(update...); err != nil {
return nil, err return nil, err
} }
} }
return s.mps, nil return s.mps, nil
} }
// 更新好友处理 // 更新好友处理
func (s *Self) updateFriends(update ...bool) error { func (s *Self) updateFriends(update ...bool) error {
var isUpdate bool var isUpdate bool
if len(update) > 0 { if len(update) > 0 {
isUpdate = update[len(update)-1] isUpdate = update[len(update)-1]
} }
if isUpdate || s.members == nil { if isUpdate || s.members == nil {
if err := s.updateMembers(); err != nil { if err := s.updateMembers(); err != nil {
return err return err
} }
} }
var friends Friends var friends Friends
for _, member := range s.members { for _, member := range s.members {
if isFriend(*member) { if isFriend(*member) {
friend := &Friend{member} friend := &Friend{member}
friend.Self = s friend.Self = s
friends = append(friends, friend) friends = append(friends, friend)
} }
} }
s.friends = friends s.friends = friends
return nil return nil
} }
// 更新群组处理 // 更新群组处理
func (s *Self) updateGroups(update ...bool) error { func (s *Self) updateGroups(update ...bool) error {
var isUpdate bool var isUpdate bool
if len(update) > 0 { if len(update) > 0 {
isUpdate = update[len(update)-1] isUpdate = update[len(update)-1]
} }
if isUpdate || s.members == nil { if isUpdate || s.members == nil {
if err := s.updateMembers(); err != nil { if err := s.updateMembers(); err != nil {
return err return err
} }
} }
var groups Groups var groups Groups
for _, member := range s.members { for _, member := range s.members {
if isGroup(*member) { if isGroup(*member) {
group := &Group{member} group := &Group{member}
groups = append(groups, group) groups = append(groups, group)
} }
} }
s.groups = groups s.groups = groups
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 {
isUpdate = update[len(update)-1] isUpdate = update[len(update)-1]
} }
if isUpdate || s.members == nil { if isUpdate || s.members == nil {
if err := s.updateMembers(); err != nil { if err := s.updateMembers(); err != nil {
return err return err
} }
} }
var mps Mps var mps Mps
for _, member := range s.members { for _, member := range s.members {
if isMP(*member) { if isMP(*member) {
mp := &Mp{member} mp := &Mp{member}
mps = append(mps, mp) mps = append(mps, mp)
} }
} }
s.mps = mps s.mps = mps
return nil return nil
} }
// 更新所有的联系人信息 // 更新所有的联系人信息
func (s *Self) UpdateMembersDetail() error { func (s *Self) UpdateMembersDetail() error {
// 先获取所有的联系人 // 先获取所有的联系人
members, err := s.Members() members, err := s.Members()
if err != nil { if err != nil {
return err return err
} }
// 获取他们的数量 // 获取他们的数量
count := members.Count() count := members.Count()
// 一次更新50个,分情况讨论 // 一次更新50个,分情况讨论
// 获取总的需要更新的次数 // 获取总的需要更新的次数
var times int var times int
if count < 50 { if count < 50 {
times = 1 times = 1
} else { } else {
times = count / 50 times = count / 50
} }
var newMembers Members var newMembers Members
request := s.Bot.storage.Request request := s.Bot.storage.Request
var pMembers Members var pMembers Members
// 分情况依次更新 // 分情况依次更新
for i := 1; i <= times; i++ { for i := 1; i <= times; i++ {
if times == 1 { if times == 1 {
pMembers = members pMembers = members
} else { } else {
pMembers = members[(i-1)*50 : i*50] pMembers = members[(i-1)*50 : i*50]
} }
nMembers, err := s.Bot.Caller.WebWxBatchGetContact(pMembers, request) nMembers, err := s.Bot.Caller.WebWxBatchGetContact(pMembers, request)
if err != nil { if err != nil {
return err return err
} }
newMembers = append(newMembers, nMembers...) newMembers = append(newMembers, nMembers...)
} }
// 最后判断是否全部更新完毕 // 最后判断是否全部更新完毕
total := times * 50 total := times * 50
if total < count { if total < count {
// 将全部剩余的更新完毕 // 将全部剩余的更新完毕
left := count - total left := count - total
pMembers = members[total : total+left] pMembers = members[total : total+left]
nMembers, err := s.Bot.Caller.WebWxBatchGetContact(pMembers, request) nMembers, err := s.Bot.Caller.WebWxBatchGetContact(pMembers, request)
if err != nil { if err != nil {
return err return err
} }
newMembers = append(newMembers, nMembers...) newMembers = append(newMembers, nMembers...)
} }
if len(newMembers) != 0 { if len(newMembers) != 0 {
newMembers.SetOwner(s) newMembers.SetOwner(s)
s.members = newMembers s.members = newMembers
} }
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]
return u return u
} }
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]
return u return u
} }
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
} }
if limit <= 0 { if limit <= 0 {
limit = m.Count() limit = m.Count()
} }
for _, member := range m { for _, member := range m {
if count := len(results); count == limit { if count := len(results); count == limit {
break break
} }
var passCount int var passCount int
for _, condFunc := range condFuncList { for _, condFunc := range condFuncList {
if condFunc(member) { if condFunc(member) {
passCount++ passCount++
} else { } else {
break break
} }
} }
if passCount == len(condFuncList) { if passCount == len(condFuncList) {
results = append(results, member) results = append(results, member)
} }
} }
return return
} }