@juzi/wechaty 1.0.19 → 1.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/cjs/src/package-json.js +4 -4
  2. package/dist/cjs/src/package-json.js.map +1 -1
  3. package/dist/cjs/src/pure-functions/update.d.ts +1 -1
  4. package/dist/cjs/src/pure-functions/update.d.ts.map +1 -1
  5. package/dist/cjs/src/pure-functions/update.js +6 -5
  6. package/dist/cjs/src/pure-functions/update.js.map +1 -1
  7. package/dist/cjs/src/schemas/contact-events.d.ts +14 -2
  8. package/dist/cjs/src/schemas/contact-events.d.ts.map +1 -1
  9. package/dist/cjs/src/schemas/contact-events.js.map +1 -1
  10. package/dist/cjs/src/schemas/room-events.d.ts +4 -1
  11. package/dist/cjs/src/schemas/room-events.d.ts.map +1 -1
  12. package/dist/cjs/src/schemas/room-events.js +1 -0
  13. package/dist/cjs/src/schemas/room-events.js.map +1 -1
  14. package/dist/cjs/src/schemas/update.d.ts +30 -11
  15. package/dist/cjs/src/schemas/update.d.ts.map +1 -1
  16. package/dist/cjs/src/schemas/update.js +32 -0
  17. package/dist/cjs/src/schemas/update.js.map +1 -1
  18. package/dist/cjs/src/schemas/wechaty-events.d.ts +23 -2
  19. package/dist/cjs/src/schemas/wechaty-events.d.ts.map +1 -1
  20. package/dist/cjs/src/schemas/wechaty-events.js +7 -0
  21. package/dist/cjs/src/schemas/wechaty-events.js.map +1 -1
  22. package/dist/cjs/src/user-modules/contact.d.ts +2 -11
  23. package/dist/cjs/src/user-modules/contact.d.ts.map +1 -1
  24. package/dist/cjs/src/user-modules/contact.js +30 -29
  25. package/dist/cjs/src/user-modules/contact.js.map +1 -1
  26. package/dist/cjs/src/user-modules/room.d.ts +2 -2
  27. package/dist/cjs/src/user-modules/room.d.ts.map +1 -1
  28. package/dist/cjs/src/user-modules/room.js +10 -3
  29. package/dist/cjs/src/user-modules/room.js.map +1 -1
  30. package/dist/cjs/src/user-modules/tag-group.d.ts +7 -1
  31. package/dist/cjs/src/user-modules/tag-group.d.ts.map +1 -1
  32. package/dist/cjs/src/user-modules/tag-group.js +40 -13
  33. package/dist/cjs/src/user-modules/tag-group.js.map +1 -1
  34. package/dist/cjs/src/user-modules/tag.d.ts +11 -4
  35. package/dist/cjs/src/user-modules/tag.d.ts.map +1 -1
  36. package/dist/cjs/src/user-modules/tag.js +53 -17
  37. package/dist/cjs/src/user-modules/tag.js.map +1 -1
  38. package/dist/cjs/src/wechaty/wechaty-base.d.ts +7 -7
  39. package/dist/cjs/src/wechaty-mixins/gerror-mixin.d.ts +1 -1
  40. package/dist/cjs/src/wechaty-mixins/io-mixin.d.ts +2 -2
  41. package/dist/cjs/src/wechaty-mixins/login-mixin.d.ts +5 -5
  42. package/dist/cjs/src/wechaty-mixins/misc-mixin.d.ts +5 -5
  43. package/dist/cjs/src/wechaty-mixins/plugin-mixin.d.ts +6 -6
  44. package/dist/cjs/src/wechaty-mixins/puppet-mixin.d.ts +4 -4
  45. package/dist/cjs/src/wechaty-mixins/puppet-mixin.d.ts.map +1 -1
  46. package/dist/cjs/src/wechaty-mixins/puppet-mixin.js +72 -13
  47. package/dist/cjs/src/wechaty-mixins/puppet-mixin.js.map +1 -1
  48. package/dist/cjs/src/wechaty-mixins/wechatify-user-module-mixin.d.ts +1 -1
  49. package/dist/esm/src/package-json.js +4 -4
  50. package/dist/esm/src/package-json.js.map +1 -1
  51. package/dist/esm/src/pure-functions/update.d.ts +1 -1
  52. package/dist/esm/src/pure-functions/update.d.ts.map +1 -1
  53. package/dist/esm/src/pure-functions/update.js +6 -5
  54. package/dist/esm/src/pure-functions/update.js.map +1 -1
  55. package/dist/esm/src/schemas/contact-events.d.ts +14 -2
  56. package/dist/esm/src/schemas/contact-events.d.ts.map +1 -1
  57. package/dist/esm/src/schemas/contact-events.js.map +1 -1
  58. package/dist/esm/src/schemas/room-events.d.ts +4 -1
  59. package/dist/esm/src/schemas/room-events.d.ts.map +1 -1
  60. package/dist/esm/src/schemas/room-events.js +1 -0
  61. package/dist/esm/src/schemas/room-events.js.map +1 -1
  62. package/dist/esm/src/schemas/update.d.ts +30 -11
  63. package/dist/esm/src/schemas/update.d.ts.map +1 -1
  64. package/dist/esm/src/schemas/update.js +8 -1
  65. package/dist/esm/src/schemas/update.js.map +1 -1
  66. package/dist/esm/src/schemas/wechaty-events.d.ts +23 -2
  67. package/dist/esm/src/schemas/wechaty-events.d.ts.map +1 -1
  68. package/dist/esm/src/schemas/wechaty-events.js +7 -0
  69. package/dist/esm/src/schemas/wechaty-events.js.map +1 -1
  70. package/dist/esm/src/user-modules/contact.d.ts +2 -11
  71. package/dist/esm/src/user-modules/contact.d.ts.map +1 -1
  72. package/dist/esm/src/user-modules/contact.js +30 -29
  73. package/dist/esm/src/user-modules/contact.js.map +1 -1
  74. package/dist/esm/src/user-modules/room.d.ts +2 -2
  75. package/dist/esm/src/user-modules/room.d.ts.map +1 -1
  76. package/dist/esm/src/user-modules/room.js +10 -3
  77. package/dist/esm/src/user-modules/room.js.map +1 -1
  78. package/dist/esm/src/user-modules/tag-group.d.ts +7 -1
  79. package/dist/esm/src/user-modules/tag-group.d.ts.map +1 -1
  80. package/dist/esm/src/user-modules/tag-group.js +40 -13
  81. package/dist/esm/src/user-modules/tag-group.js.map +1 -1
  82. package/dist/esm/src/user-modules/tag.d.ts +11 -4
  83. package/dist/esm/src/user-modules/tag.d.ts.map +1 -1
  84. package/dist/esm/src/user-modules/tag.js +53 -17
  85. package/dist/esm/src/user-modules/tag.js.map +1 -1
  86. package/dist/esm/src/wechaty/wechaty-base.d.ts +7 -7
  87. package/dist/esm/src/wechaty-mixins/gerror-mixin.d.ts +1 -1
  88. package/dist/esm/src/wechaty-mixins/io-mixin.d.ts +2 -2
  89. package/dist/esm/src/wechaty-mixins/login-mixin.d.ts +5 -5
  90. package/dist/esm/src/wechaty-mixins/misc-mixin.d.ts +5 -5
  91. package/dist/esm/src/wechaty-mixins/plugin-mixin.d.ts +6 -6
  92. package/dist/esm/src/wechaty-mixins/puppet-mixin.d.ts +4 -4
  93. package/dist/esm/src/wechaty-mixins/puppet-mixin.d.ts.map +1 -1
  94. package/dist/esm/src/wechaty-mixins/puppet-mixin.js +72 -13
  95. package/dist/esm/src/wechaty-mixins/puppet-mixin.js.map +1 -1
  96. package/dist/esm/src/wechaty-mixins/wechatify-user-module-mixin.d.ts +1 -1
  97. package/package.json +3 -3
  98. package/src/package-json.ts +4 -4
  99. package/src/pure-functions/update.ts +9 -8
  100. package/src/schemas/contact-events.ts +22 -3
  101. package/src/schemas/room-events.ts +4 -0
  102. package/src/schemas/update.ts +42 -13
  103. package/src/schemas/wechaty-events.ts +73 -43
  104. package/src/user-modules/contact.ts +34 -30
  105. package/src/user-modules/room.ts +11 -4
  106. package/src/user-modules/tag-group.ts +48 -12
  107. package/src/user-modules/tag.ts +63 -17
  108. package/src/wechaty-mixins/puppet-mixin.ts +74 -14
@@ -207,28 +207,6 @@ class ContactMixin extends MixinBase implements SayableSayer {
207
207
  log.verbose('Contact', 'static delete(%s)', contact.id)
208
208
  }
209
209
 
210
- /**
211
- * Get tags for all contact
212
- *
213
- * @static
214
- * @returns {Promise<TagInterface[]>}
215
- * @example
216
- * const tags = await wechaty.Contact.tags()
217
- */
218
- static async tags (): Promise<TagInterface[]> {
219
- log.verbose('Contact', 'static tags() for %s', this)
220
-
221
- try {
222
- const tagIdList = await this.wechaty.puppet.tagTagList()
223
- const tagList = tagIdList.map(id => this.wechaty.Tag.create(id))
224
- return tagList
225
- } catch (e) {
226
- this.wechaty.emitError(e)
227
- log.error('Contact', 'static tags() exception: %s', (e as Error).message)
228
- return []
229
- }
230
- }
231
-
232
210
  /**
233
211
  *
234
212
  * Instance properties
@@ -674,8 +652,13 @@ class ContactMixin extends MixinBase implements SayableSayer {
674
652
 
675
653
  try {
676
654
  const tagPayloadList = await this.wechaty.puppet.tagContactTagList(this.id)
677
- const tagList = tagPayloadList.map(tag => this.wechaty.Tag.create(tag))
678
- return tagList
655
+
656
+ let tagList = tagPayloadList.map(tag => this.wechaty.Tag.load(tag))
657
+ if (tagList.some(tag => typeof tag === 'undefined')) {
658
+ await this.wechaty.Tag.sync()
659
+ tagList = tagPayloadList.map(tag => this.wechaty.Tag.load(tag))
660
+ }
661
+ return tagList.filter(tag => !!tag) as TagInterface[]
679
662
  } catch (e) {
680
663
  this.wechaty.emitError(e)
681
664
  log.error('Contact', 'tags() exception: %s', (e as Error).message)
@@ -687,10 +670,20 @@ class ContactMixin extends MixinBase implements SayableSayer {
687
670
  * Add a Tag
688
671
  */
689
672
 
690
- async tag (tag: TagInterface): Promise<void> {
691
- log.verbose('Contact', 'tag(%s) for %s', tag, this)
673
+ async tag (tags: TagInterface | TagInterface[]): Promise<void> {
674
+ log.verbose('Contact', 'tag(%s) for %s', JSON.stringify(tags), this)
692
675
 
693
- await this.wechaty.puppet.tagContactTagAdd(tag.groupId(), tag.id(), this.id)
676
+ if (!Array.isArray(tags)) {
677
+ tags = [tags]
678
+ }
679
+
680
+ const tagIdentifiers = tags.map(tag => {
681
+ return {
682
+ id: tag.id(),
683
+ groupId: tag.groupId(),
684
+ }
685
+ })
686
+ await this.wechaty.puppet.tagContactTagAdd(tagIdentifiers, [this.id])
694
687
 
695
688
  }
696
689
 
@@ -698,10 +691,21 @@ class ContactMixin extends MixinBase implements SayableSayer {
698
691
  * Remove a Tag
699
692
  */
700
693
 
701
- async tagRemove (tag: TagInterface): Promise<void> {
702
- log.verbose('Contact', 'tagRemove(%s) for %s', tag, this)
694
+ async tagRemove (tags: TagInterface | TagInterface[]): Promise<void> {
695
+ log.verbose('Contact', 'tagRemove(%s) for %s', JSON.stringify(tags), this)
696
+
697
+ if (!Array.isArray(tags)) {
698
+ tags = [tags]
699
+ }
700
+
701
+ const tagIdentifiers = tags.map(tag => {
702
+ return {
703
+ id: tag.id(),
704
+ groupId: tag.groupId(),
705
+ }
706
+ })
703
707
 
704
- await this.wechaty.puppet.tagContactTagRemove(tag.groupId(), tag.id(), this.id)
708
+ await this.wechaty.puppet.tagContactTagRemove(tagIdentifiers, [this.id])
705
709
 
706
710
  }
707
711
 
@@ -728,9 +728,16 @@ class RoomMixin extends MixinBase implements SayableSayer {
728
728
  * }
729
729
  * }
730
730
  */
731
- async remove (contact: ContactInterface): Promise<void> {
732
- log.verbose('Room', 'del(%s)', contact)
733
- await this.wechaty.puppet.roomDel(this.id, contact.id)
731
+ async remove (contacts: ContactInterface | ContactInterface[]): Promise<void> {
732
+ log.verbose('Room', 'del(%s)', contacts)
733
+
734
+ let contactIds: string[]
735
+ if (Array.isArray(contacts)) {
736
+ contactIds = contacts.map(c => c.id)
737
+ } else {
738
+ contactIds = [contacts.id]
739
+ }
740
+ await this.wechaty.puppet.roomDel(this.id, contactIds)
734
741
  // this.delLocal(contact)
735
742
  }
736
743
 
@@ -738,7 +745,7 @@ class RoomMixin extends MixinBase implements SayableSayer {
738
745
  * Huan(202106): will be removed after Dec 31, 2023
739
746
  * @deprecated use remove(contact) instead.
740
747
  */
741
- async del (contact: ContactImpl): Promise<void> {
748
+ async del (contact: ContactImpl | ContactImpl[]): Promise<void> {
742
749
  log.warn('Room', 'del() is DEPRECATED, use remove() instead.\n%s', new Error().stack)
743
750
  return this.remove(contact)
744
751
  }
@@ -26,6 +26,7 @@ import { validationMixin } from '../user-mixins/validation.js'
26
26
  import {
27
27
  wechatifyMixinBase,
28
28
  } from '../user-mixins/wechatify.js'
29
+ import type { TagInterface } from './tag.js'
29
30
 
30
31
  class TagGroupMixin extends wechatifyMixinBase() {
31
32
 
@@ -58,13 +59,52 @@ class TagGroupMixin extends wechatifyMixinBase() {
58
59
  return this.payload.name
59
60
  }
60
61
 
62
+ private static pool: TagGroupInterface[] = []
63
+
64
+ static async list (forceSync = false): Promise<TagGroupInterface[]> {
65
+ log.verbose('TagGroup', 'list(%s)', forceSync)
66
+
67
+ if (this.pool.length > 0 && !forceSync) {
68
+ return this.pool
69
+ }
70
+
71
+ try {
72
+ const payloads = await this.wechaty.puppet.tagGroupList()
73
+ this.pool = payloads.map(payload => new this(payload))
74
+ return this.pool
75
+ } catch (e) {
76
+ this.wechaty.emitError(e)
77
+ log.error('TagGroup', 'list() exception: %s', (e as Error).message)
78
+ return []
79
+ }
80
+ }
81
+
82
+ static async sync (): Promise<void> {
83
+ log.verbose('TagGroup', 'sync()')
84
+
85
+ await this.list(true)
86
+ }
87
+
88
+ static load (tagGroupId: string): TagGroupInterface | undefined {
89
+ log.verbose('TagGroup', 'load(%s)', tagGroupId)
90
+
91
+ for (const item of this.pool) {
92
+ if (item.id() === tagGroupId) {
93
+ return item
94
+ }
95
+ }
96
+ return undefined
97
+ }
98
+
61
99
  static async createTagGroup (name: string): Promise<TagGroupInterface | void> {
62
100
  log.verbose('TagGroup', 'createTagGroup(%s, %s)', name)
63
101
 
64
102
  try {
65
103
  const payload = await this.wechaty.puppet.tagGroupAdd(name)
66
104
  if (payload) {
67
- return new this(payload)
105
+ const newTagGroup = new this(payload)
106
+ this.pool.push(newTagGroup)
107
+ return newTagGroup
68
108
  }
69
109
  } catch (e) {
70
110
  this.wechaty.emitError(e)
@@ -77,23 +117,19 @@ class TagGroupMixin extends wechatifyMixinBase() {
77
117
 
78
118
  try {
79
119
  await this.wechaty.puppet.tagGroupDelete(tagGroup.id())
120
+ this.pool.splice(this.pool.indexOf(tagGroup), 1)
80
121
  } catch (e) {
81
122
  this.wechaty.emitError(e)
82
- log.error('Contact', 'createTag() exception: %s', (e as Error).message)
123
+ log.error('TagGroup', 'deleteTagGroup() exception: %s', (e as Error).message)
83
124
  }
84
125
  }
85
126
 
86
- static async list (): Promise<TagGroupInterface[]> {
87
- log.verbose('TagGroup', 'list()')
127
+ async tags (): Promise<TagInterface[]> {
128
+ return (await this.wechaty.Tag.list()).filter(tag => tag.groupId() === this.id())
129
+ }
88
130
 
89
- try {
90
- const payloads = await this.wechaty.puppet.tagGroupList()
91
- return payloads.map(payload => new this(payload))
92
- } catch (e) {
93
- this.wechaty.emitError(e)
94
- log.error('TagGroup', 'list() exception: %s', (e as Error).message)
95
- return []
96
- }
131
+ override toString () {
132
+ return `<TagGroup#${this.name() || this.id()}>`
97
133
  }
98
134
 
99
135
  }
@@ -18,6 +18,7 @@
18
18
  *
19
19
  */
20
20
  import type * as PUPPET from '@juzi/wechaty-puppet'
21
+ import type { TagIdentifier } from '@juzi/wechaty-puppet/filters'
21
22
 
22
23
  import type { Constructor } from 'clone-class'
23
24
  import { log } from '../config.js'
@@ -27,6 +28,7 @@ import {
27
28
  wechatifyMixinBase,
28
29
  } from '../user-mixins/wechatify.js'
29
30
  import type { ContactInterface } from './contact.js'
31
+ import type { TagGroupInterface } from './tag-group.js'
30
32
 
31
33
  class TagMixin extends wechatifyMixinBase() {
32
34
 
@@ -67,12 +69,23 @@ class TagMixin extends wechatifyMixinBase() {
67
69
  return this.payload.name
68
70
  }
69
71
 
70
- static async list (): Promise<TagInterface[]> {
71
- log.verbose('Tag', 'list()')
72
+ group (): TagGroupInterface | undefined {
73
+ return this.wechaty.TagGroup.load(this.groupId())
74
+ }
75
+
76
+ private static pool: TagInterface[] = []
77
+
78
+ static async list (forceSync = false): Promise<TagInterface[]> {
79
+ log.verbose('Tag', 'list(%s)', forceSync)
80
+
81
+ if (this.pool.length > 0 && !forceSync) {
82
+ return this.pool
83
+ }
72
84
 
73
85
  try {
74
86
  const payloads = await this.wechaty.puppet.tagTagList()
75
- return payloads.map(payload => new this(payload))
87
+ this.pool = payloads.map(payload => new this(payload))
88
+ return this.pool
76
89
  } catch (e) {
77
90
  this.wechaty.emitError(e)
78
91
  log.error('Tag', 'list() exception: %s', (e as Error).message)
@@ -80,28 +93,54 @@ class TagMixin extends wechatifyMixinBase() {
80
93
  }
81
94
  }
82
95
 
96
+ static async sync (): Promise<void> {
97
+ log.verbose('Tag', 'sync()')
98
+
99
+ await this.list(true)
100
+ }
101
+
102
+ static load (tag: TagIdentifier): TagInterface | undefined {
103
+ log.verbose('TagGroup', 'load(%s)', tag)
104
+
105
+ for (const item of this.pool) {
106
+ if (item.id() === tag.id && (item.groupId() === tag.groupId || (!item.groupId() && !tag.groupId))) {
107
+ return item
108
+ }
109
+ }
110
+ return undefined
111
+ }
112
+
83
113
  async contactList (): Promise<ContactInterface[]> {
84
- log.verbose('Tag', 'contactList() for tag id: %s', this.id())
114
+ log.verbose('Tag', 'contactList() for tag : %s', this)
85
115
 
86
- const contactIds = await this.wechaty.puppet.tagTagContactList(this.groupId(), this.id())
116
+ const tag = { id: this.id(), groupId: this.groupId() } as TagIdentifier
117
+ const contactIds = await this.wechaty.puppet.tagTagContactList(tag)
87
118
  const contactPromises = contactIds.map(id => this.wechaty.Contact.find({ id })) as Promise<ContactInterface>[]
88
119
  return Promise.all(contactPromises)
89
120
  }
90
121
 
91
- async tag (contact: ContactInterface): Promise<void> {
92
- log.verbose('Tag', 'tag(%s) for tag id: %s', contact, this.id())
122
+ async tag (contacts: ContactInterface | ContactInterface[]): Promise<void> {
123
+ log.verbose('Tag', 'tag(%s) for tag : %s', contacts, this)
93
124
 
94
- const contactId = contact.id
95
- await this.wechaty.puppet.tagContactTagAdd(this.groupId(), this.id(), contactId)
125
+ const tag = { id: this.id(), groupId: this.groupId() } as TagIdentifier
126
+ let contactIds: string[]
127
+ if (Array.isArray(contacts)) {
128
+ contactIds = contacts.map(c => c.id)
129
+ } else {
130
+ contactIds = [contacts.id]
131
+ }
132
+ await this.wechaty.puppet.tagContactTagAdd([tag], contactIds)
96
133
  }
97
134
 
98
- static async createTag (tagGroupId: string | undefined, name: string): Promise<TagInterface | void> {
99
- log.verbose('Tag', 'createTag(%s, %s)', tagGroupId, name)
135
+ static async createTag (name: string, tagGroup?: TagGroupInterface): Promise<TagInterface | void> {
136
+ log.verbose('Tag', 'createTag(%s, %s)', tagGroup, name)
100
137
 
101
138
  try {
102
- const payload = await this.wechaty.puppet.tagTagAdd(tagGroupId, name)
139
+ const payload = await this.wechaty.puppet.tagTagAdd(name, tagGroup?.name())
103
140
  if (payload) {
104
- return new this(payload)
141
+ const newTag = new this(payload)
142
+ this.pool.push(newTag)
143
+ return newTag
105
144
  }
106
145
  } catch (e) {
107
146
  this.wechaty.emitError(e)
@@ -109,17 +148,24 @@ class TagMixin extends wechatifyMixinBase() {
109
148
  }
110
149
  }
111
150
 
112
- static async deleteTag (tag: TagInterface): Promise<void> {
113
- log.verbose('Tag', 'deleteTag(%s, %s)', tag)
151
+ static async deleteTag (tagInstance: TagInterface): Promise<void> {
152
+ log.verbose('Tag', 'deleteTag(%s, %s)', tagInstance)
153
+
154
+ const tag = { id: tagInstance.id(), groupId: tagInstance.groupId() } as TagIdentifier
114
155
 
115
156
  try {
116
- await this.wechaty.puppet.tagTagDelete(tag.groupId(), tag.id())
157
+ await this.wechaty.puppet.tagTagDelete(tag)
158
+ this.pool.splice(this.pool.indexOf(tagInstance), 1)
117
159
  } catch (e) {
118
160
  this.wechaty.emitError(e)
119
- log.error('Contact', 'deleteTag() exception: %s', (e as Error).message)
161
+ log.error('Tag', 'deleteTag() exception: %s', (e as Error).message)
120
162
  }
121
163
  }
122
164
 
165
+ override toString () {
166
+ return `<Tag#${this.name() || this.id()}>`
167
+ }
168
+
123
169
  }
124
170
 
125
171
  class TagImpl extends validationMixin(TagMixin)<TagInterface>() {}
@@ -11,7 +11,7 @@ import type {
11
11
  StateSwitchInterface,
12
12
  } from 'state-switch'
13
13
 
14
- import { config } from '../config.js'
14
+ import { config, FOUR_PER_EM_SPACE } from '../config.js'
15
15
  import { timestampToDate } from '../pure-functions/timestamp-to-date.js'
16
16
  import type {
17
17
  ContactImpl,
@@ -25,7 +25,7 @@ import type {
25
25
 
26
26
  import type { GErrorMixin } from './gerror-mixin.js'
27
27
  import type { IoMixin } from './io-mixin.js'
28
- import type { InfoUpdateInterface } from '../schemas/update.js'
28
+ import { ContactImportantFields, ContactUpdatableValuePair, InfoUpdateInterface, RoomImportantFields, RoomUpdatableValuePair } from '../schemas/update.js'
29
29
  import { diffPayload } from '../pure-functions/update.js'
30
30
 
31
31
  const PUPPET_MEMORY_NAME = 'puppet'
@@ -443,15 +443,58 @@ const puppetMixin = <MixinBase extends WechatifyUserModuleMixin & GErrorMixin &
443
443
  const oldPayload = JSON.parse(JSON.stringify(contact?.payload || {}))
444
444
  await contact?.ready(true)
445
445
  const newPayload = JSON.parse(JSON.stringify(contact?.payload || {}))
446
- const updateEvent: InfoUpdateInterface = {
447
- type: payloadType,
448
- id: payloadId,
449
- updates: diffPayload(oldPayload, newPayload),
450
- }
451
- if (updateEvent.updates.length > 0) {
446
+
447
+ const differences = diffPayload<PUPPET.payloads.Contact>(oldPayload, newPayload)
448
+ const importangDifferences = differences.filter(ele => ele && ContactImportantFields.some(key => key === ele.key))
449
+ const regularDifferences = differences.filter(ele => ele && !ContactImportantFields.some(key => key === ele.key)) as ContactUpdatableValuePair[]
450
+ if (regularDifferences.length > 0) {
451
+ const updateEvent: InfoUpdateInterface = {
452
+ type: payloadType,
453
+ id: payloadId,
454
+ updates: regularDifferences,
455
+ }
452
456
  this.emit('update', updateEvent)
453
457
  contact?.emit('update', updateEvent)
454
458
  }
459
+ for (const difference of importangDifferences) {
460
+ switch (difference?.key) {
461
+ case 'tags': {
462
+ const oldTagsSet = new Set(difference.oldValue?.map(ele => ele.groupId + FOUR_PER_EM_SPACE + ele.id))
463
+ const newTagsSet = new Set(difference.newValue?.map(ele => ele.groupId + FOUR_PER_EM_SPACE + ele.id))
464
+ const addedTags = difference.newValue?.filter(ele => !oldTagsSet.has(ele.groupId + FOUR_PER_EM_SPACE + ele.id)).map(ele => this.Tag.load(ele)) || []
465
+ const removedTags = difference.oldValue?.filter(ele => !newTagsSet.has(ele.groupId + FOUR_PER_EM_SPACE + ele.id)).map(ele => this.Tag.load(ele)) || []
466
+ if (addedTags.length > 0) {
467
+ this.emit('contact-tag-add', contact, addedTags)
468
+ }
469
+ if (removedTags.length > 0) {
470
+ this.emit('contact-tag-remove', contact, removedTags)
471
+ }
472
+ break
473
+ }
474
+ case 'name': {
475
+ this.emit('contact-name', contact, difference.newValue || '', difference.oldValue || '')
476
+ contact?.emit('name', difference.newValue || '', difference.oldValue || '')
477
+ break
478
+ }
479
+ case 'alias': {
480
+ this.emit('contact-alias', contact, difference.newValue || '', difference.oldValue || '')
481
+ contact?.emit('alias', difference.newValue || '', difference.oldValue || '')
482
+ break
483
+ }
484
+ case 'phone': {
485
+ this.emit('contact-phone', contact, difference.newValue || [], difference.oldValue || [])
486
+ contact?.emit('phone', difference.newValue || [], difference.oldValue || [])
487
+ break
488
+ }
489
+ case 'description': {
490
+ this.emit('contact-description', contact, difference.newValue || '', difference.oldValue || '')
491
+ contact?.emit('description', difference.newValue || '', difference.oldValue || '')
492
+ break
493
+ }
494
+ default:
495
+ log.warn('WechatyPuppetMixin', 'puppet dirty unsupported difference type: %s', JSON.stringify(difference))
496
+ }
497
+ }
455
498
  break
456
499
  }
457
500
  case PUPPET.types.Payload.Room: {
@@ -459,15 +502,32 @@ const puppetMixin = <MixinBase extends WechatifyUserModuleMixin & GErrorMixin &
459
502
  const oldPayload = JSON.parse(JSON.stringify(room?.payload || {}))
460
503
  await room?.ready(true)
461
504
  const newPayload = JSON.parse(JSON.stringify(room?.payload || {}))
462
- const updateEvent: InfoUpdateInterface = {
463
- type: payloadType,
464
- id: payloadId,
465
- updates: diffPayload(oldPayload, newPayload),
466
- }
467
- if (updateEvent.updates.length > 0) {
505
+
506
+ const differences = diffPayload<PUPPET.payloads.Room>(oldPayload, newPayload)
507
+ const importangDifferences = differences.filter(ele => ele && RoomImportantFields.some(key => key === ele.key))
508
+ const regularDifferences = differences.filter(ele => ele && !RoomImportantFields.some(key => key === ele.key)) as RoomUpdatableValuePair[]
509
+ if (regularDifferences.length > 0) {
510
+ const updateEvent: InfoUpdateInterface = {
511
+ type: payloadType,
512
+ id: payloadId,
513
+ updates: regularDifferences,
514
+ }
468
515
  this.emit('update', updateEvent)
469
516
  room?.emit('update', updateEvent)
470
517
  }
518
+ for (const difference of importangDifferences) {
519
+ switch (difference?.key) {
520
+ case 'ownerId': {
521
+ const oldOwner = (await this.Contact.find({ id: difference.oldValue }))!
522
+ const newOwner = (await this.Contact.find({ id: difference.newValue }))!
523
+ this.emit('room-owner', room, newOwner, oldOwner)
524
+ room?.emit('owner', newOwner, oldOwner)
525
+ break
526
+ }
527
+ default:
528
+ log.warn('WechatyPuppetMixin', 'puppet dirty unsupported difference type: %s', JSON.stringify(difference))
529
+ }
530
+ }
471
531
  break
472
532
  }
473
533
  case PUPPET.types.Payload.RoomMember: {