forked from eatmoreapple/openwechat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
relations.go
476 lines (406 loc) · 11.7 KB
/
relations.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
package openwechat
import (
"fmt"
"io"
"time"
)
type Friend struct{ *User }
// implement fmt.Stringer
func (f *Friend) String() string {
display := f.NickName
if f.RemarkName != "" {
display = f.RemarkName
}
return fmt.Sprintf("<Friend:%s>", display)
}
// SetRemarkName 重命名当前好友
func (f *Friend) SetRemarkName(name string) error {
return f.self.SetRemarkNameToFriend(f, name)
}
// SendText 发送文本消息
func (f *Friend) SendText(content string) (*SentMessage, error) {
return f.self.SendTextToFriend(f, content)
}
// SendImage 发送图片消息
func (f *Friend) SendImage(file io.Reader) (*SentMessage, error) {
return f.self.SendImageToFriend(f, file)
}
// SendVideo 发送视频消息
func (f *Friend) SendVideo(file io.Reader) (*SentMessage, error) {
return f.self.SendVideoToFriend(f, file)
}
// SendFile 发送文件消息
func (f *Friend) SendFile(file io.Reader) (*SentMessage, error) {
return f.self.SendFileToFriend(f, file)
}
// AddIntoGroup 拉该好友入群
func (f *Friend) AddIntoGroup(groups ...*Group) error {
return f.self.AddFriendIntoManyGroups(f, groups...)
}
type Friends []*Friend
// Count 获取好友的数量
func (f Friends) Count() int {
return len(f)
}
// First 获取第一个好友
func (f Friends) First() *Friend {
if f.Count() > 0 {
return f.Sort()[0]
}
return nil
}
// Last 获取最后一个好友
func (f Friends) Last() *Friend {
if f.Count() > 0 {
return f.Sort()[f.Count()-1]
}
return nil
}
// SearchByUserName 根据用户名查找好友
func (f Friends) SearchByUserName(limit int, username string) (results Friends) {
return f.Search(limit, func(friend *Friend) bool { return friend.User.UserName == username })
}
// SearchByNickName 根据昵称查找好友
func (f Friends) SearchByNickName(limit int, nickName string) (results Friends) {
return f.Search(limit, func(friend *Friend) bool { return friend.User.NickName == nickName })
}
// SearchByRemarkName 根据备注查找好友
func (f Friends) SearchByRemarkName(limit int, remarkName string) (results Friends) {
return f.Search(limit, func(friend *Friend) bool { return friend.User.RemarkName == remarkName })
}
// Search 根据自定义条件查找好友
func (f Friends) Search(limit int, searchFuncList ...func(friend *Friend) bool) (results Friends) {
return f.AsMembers().Search(limit, func(user *User) bool {
var friend = &Friend{user}
for _, searchFunc := range searchFuncList {
if !searchFunc(friend) {
return false
}
}
return true
}).Friends()
}
// AsMembers 将群组转换为用户列表
func (f Friends) AsMembers() Members {
var members = make(Members, 0, f.Count())
for _, friend := range f {
members = append(members, friend.User)
}
return members
}
// Sort 对好友进行排序
func (f Friends) Sort() Friends {
return f.AsMembers().Sort().Friends()
}
// Uniq 对好友进行去重
func (f Friends) Uniq() Friends {
return f.AsMembers().Uniq().Friends()
}
// SendText 向slice的好友依次发送文本消息
func (f Friends) SendText(text string, delays ...time.Duration) error {
if f.Count() == 0 {
return nil
}
var delay time.Duration
if len(delays) > 0 {
delay = delays[0]
}
self := f.First().self
return self.SendTextToFriends(text, delay, f...)
}
// SendImage 向slice的好友依次发送图片消息
func (f Friends) SendImage(file io.Reader, delays ...time.Duration) error {
if f.Count() == 0 {
return nil
}
var delay time.Duration
if len(delays) > 0 {
delay = delays[0]
}
self := f.First().self
return self.SendImageToFriends(file, delay, f...)
}
// SendFile 群发文件
func (f Friends) SendFile(file io.Reader, delay ...time.Duration) error {
if f.Count() == 0 {
return nil
}
var d time.Duration
if len(delay) > 0 {
d = delay[0]
}
self := f.First().self
return self.SendFileToFriends(file, d, f...)
}
type Group struct{ *User }
// implement fmt.Stringer
func (g *Group) String() string {
return fmt.Sprintf("<Group:%s>", g.NickName)
}
// SendText 发行文本消息给当前的群组
func (g *Group) SendText(content string) (*SentMessage, error) {
return g.self.SendTextToGroup(g, content)
}
// SendImage 发行图片消息给当前的群组
func (g *Group) SendImage(file io.Reader) (*SentMessage, error) {
return g.self.SendImageToGroup(g, file)
}
// SendVideo 发行视频消息给当前的群组
func (g *Group) SendVideo(file io.Reader) (*SentMessage, error) {
return g.self.SendVideoToGroup(g, file)
}
// SendFile 发送文件给当前的群组
func (g *Group) SendFile(file io.Reader) (*SentMessage, error) {
return g.self.SendFileToGroup(g, file)
}
// Members 获取所有的群成员
func (g *Group) Members() (Members, error) {
if err := g.Detail(); err != nil {
return nil, err
}
g.MemberList.init(g.self)
return g.MemberList, nil
}
// AddFriendsIn 拉好友入群
func (g *Group) AddFriendsIn(friends ...*Friend) error {
friends = Friends(friends).Uniq()
return g.self.AddFriendsIntoGroup(g, friends...)
}
// RemoveMembers 从群聊中移除用户
// Deprecated
// 无论是网页版,还是程序上都不起作用
func (g *Group) RemoveMembers(members Members) error {
return g.self.RemoveMemberFromGroup(g, members)
}
// Rename 群组重命名
func (g *Group) Rename(name string) error {
return g.self.RenameGroup(g, name)
}
// SearchMemberByUsername 根据用户名查找群成员
func (g *Group) SearchMemberByUsername(username string) (*User, error) {
if g.MemberList.Count() == 0 {
if _, err := g.Members(); err != nil {
return nil, err
}
}
members := g.MemberList.SearchByUserName(1, username)
// 如果此时本地查不到, 那么该成员可能是新加入的
if members.Count() == 0 {
if _, err := g.Members(); err != nil {
return nil, err
}
}
// 再次尝试获取
members = g.MemberList.SearchByUserName(1, username)
if members.Count() == 0 {
return nil, ErrNoSuchUserFoundError
}
return members.First(), nil
}
type Groups []*Group
// Count 获取群组数量
func (g Groups) Count() int {
return len(g)
}
// First 获取第一个群组
func (g Groups) First() *Group {
if g.Count() > 0 {
return g.Sort()[0]
}
return nil
}
// Last 获取最后一个群组
func (g Groups) Last() *Group {
if g.Count() > 0 {
return g.Sort()[g.Count()-1]
}
return nil
}
// SendText 向群组依次发送文本消息, 支持发送延迟
func (g Groups) SendText(text string, delay ...time.Duration) error {
if g.Count() == 0 {
return nil
}
var d time.Duration
if len(delay) > 0 {
d = delay[0]
}
self := g.First().self
return self.SendTextToGroups(text, d, g...)
}
// SendImage 向群组依次发送图片消息, 支持发送延迟
func (g Groups) SendImage(file io.Reader, delay ...time.Duration) error {
if g.Count() == 0 {
return nil
}
var d time.Duration
if len(delay) > 0 {
d = delay[0]
}
self := g.First().self
return self.SendImageToGroups(file, d, g...)
}
// SendFile 向群组依次发送文件消息, 支持发送延迟
func (g Groups) SendFile(file io.Reader, delay ...time.Duration) error {
if g.Count() == 0 {
return nil
}
var d time.Duration
if len(delay) > 0 {
d = delay[0]
}
self := g.First().self
return self.SendFileToGroups(file, d, g...)
}
// SearchByUserName 根据用户名查找群组
func (g Groups) SearchByUserName(limit int, username string) (results Groups) {
return g.Search(limit, func(group *Group) bool { return group.UserName == username })
}
// SearchByNickName 根据昵称查找群组
func (g Groups) SearchByNickName(limit int, nickName string) (results Groups) {
return g.Search(limit, func(group *Group) bool { return group.NickName == nickName })
}
// Search 根据自定义条件查找群组
func (g Groups) Search(limit int, searchFuncList ...func(group *Group) bool) (results Groups) {
return g.AsMembers().Search(limit, func(user *User) bool {
var group = &Group{user}
for _, searchFunc := range searchFuncList {
if !searchFunc(group) {
return false
}
}
return true
}).Groups()
}
// AsMembers 将群组列表转换为用户列表
func (g Groups) AsMembers() Members {
var members = make(Members, 0, g.Count())
for _, group := range g {
members = append(members, group.User)
}
return members
}
// Sort 对群组进行排序
func (g Groups) Sort() Groups {
return g.AsMembers().Sort().Groups()
}
// Uniq 对群组进行去重
func (g Groups) Uniq() Groups {
return g.AsMembers().Uniq().Groups()
}
// Mp 公众号对象
type Mp struct{ *User }
func (m *Mp) String() string {
return fmt.Sprintf("<Mp:%s>", m.NickName)
}
// Mps 公众号组对象
type Mps []*Mp
// Count 数量统计
func (m Mps) Count() int {
return len(m)
}
// First 获取第一个
func (m Mps) First() *Mp {
if m.Count() > 0 {
return m.Sort()[0]
}
return nil
}
// Last 获取最后一个
func (m Mps) Last() *Mp {
if m.Count() > 0 {
return m.Sort()[m.Count()-1]
}
return nil
}
// Search 根据自定义条件查找
func (m Mps) Search(limit int, searchFuncList ...func(group *Mp) bool) (results Mps) {
return m.AsMembers().Search(limit, func(user *User) bool {
var mp = &Mp{user}
for _, searchFunc := range searchFuncList {
if !searchFunc(mp) {
return false
}
}
return true
}).MPs()
}
// AsMembers 将公众号列表转换为用户列表
func (m Mps) AsMembers() Members {
var members = make(Members, 0, m.Count())
for _, mp := range m {
members = append(members, mp.User)
}
return members
}
// Sort 对公众号进行排序
func (m Mps) Sort() Mps {
return m.AsMembers().Sort().MPs()
}
// Uniq 对公众号进行去重
func (m Mps) Uniq() Mps {
return m.AsMembers().Uniq().MPs()
}
// SearchByUserName 根据用户名查找
func (m Mps) SearchByUserName(limit int, userName string) (results Mps) {
return m.Search(limit, func(group *Mp) bool { return group.UserName == userName })
}
// SearchByNickName 根据昵称查找
func (m Mps) SearchByNickName(limit int, nickName string) (results Mps) {
return m.Search(limit, func(group *Mp) bool { return group.NickName == nickName })
}
// SendText 发送文本消息给公众号
func (m *Mp) SendText(content string) (*SentMessage, error) {
return m.self.SendTextToMp(m, content)
}
// SendImage 发送图片消息给公众号
func (m *Mp) SendImage(file io.Reader) (*SentMessage, error) {
return m.self.SendImageToMp(m, file)
}
// SendFile 发送文件消息给公众号
func (m *Mp) SendFile(file io.Reader) (*SentMessage, error) {
return m.self.SendFileToMp(m, file)
}
// GetByUsername 根据username查询一个Friend
func (f Friends) GetByUsername(username string) *Friend {
return f.SearchByUserName(1, username).First()
}
// GetByRemarkName 根据remarkName查询一个Friend
func (f Friends) GetByRemarkName(remarkName string) *Friend {
return f.SearchByRemarkName(1, remarkName).First()
}
// GetByNickName 根据nickname查询一个Friend
func (f Friends) GetByNickName(nickname string) *Friend {
return f.SearchByNickName(1, nickname).First()
}
// GetByUsername 根据username查询一个Group
func (g Groups) GetByUsername(username string) *Group {
return g.SearchByUserName(1, username).First()
}
// GetByNickName 根据nickname查询一个Group
func (g Groups) GetByNickName(nickname string) *Group {
return g.SearchByNickName(1, nickname).First()
}
// GetByNickName 根据nickname查询一个Mp
func (m Mps) GetByNickName(nickname string) *Mp {
return m.SearchByNickName(1, nickname).First()
}
// GetByUserName 根据username查询一个Mp
func (m Mps) GetByUserName(username string) *Mp {
return m.SearchByUserName(1, username).First()
}
// search 根据自定义条件查找
func search(searchList Members, limit int, searchFunc func(group *User) bool) (results Members) {
if limit <= 0 {
limit = searchList.Count()
}
for _, member := range searchList {
if results.Count() == limit {
break
}
if searchFunc(member) {
results = append(results, member)
}
}
return
}