@juzi/wechaty-puppet-service 1.0.113 → 1.0.114

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 (31) hide show
  1. package/dist/cjs/src/client/payload-store.js +2 -2
  2. package/dist/cjs/src/client/payload-store.js.map +1 -1
  3. package/dist/cjs/src/client/puppet-service.d.ts +11 -0
  4. package/dist/cjs/src/client/puppet-service.d.ts.map +1 -1
  5. package/dist/cjs/src/client/puppet-service.js +121 -1
  6. package/dist/cjs/src/client/puppet-service.js.map +1 -1
  7. package/dist/cjs/src/client/puppet-service.spec.js.map +1 -1
  8. package/dist/cjs/src/package-json.js +4 -4
  9. package/dist/cjs/src/package-json.js.map +1 -1
  10. package/dist/cjs/src/server/puppet-implementation.d.ts.map +1 -1
  11. package/dist/cjs/src/server/puppet-implementation.js +148 -2
  12. package/dist/cjs/src/server/puppet-implementation.js.map +1 -1
  13. package/dist/esm/src/client/payload-store.js +2 -2
  14. package/dist/esm/src/client/payload-store.js.map +1 -1
  15. package/dist/esm/src/client/puppet-service.d.ts +11 -0
  16. package/dist/esm/src/client/puppet-service.d.ts.map +1 -1
  17. package/dist/esm/src/client/puppet-service.js +122 -2
  18. package/dist/esm/src/client/puppet-service.js.map +1 -1
  19. package/dist/esm/src/client/puppet-service.spec.js +1 -1
  20. package/dist/esm/src/client/puppet-service.spec.js.map +1 -1
  21. package/dist/esm/src/package-json.js +4 -4
  22. package/dist/esm/src/package-json.js.map +1 -1
  23. package/dist/esm/src/server/puppet-implementation.d.ts.map +1 -1
  24. package/dist/esm/src/server/puppet-implementation.js +148 -2
  25. package/dist/esm/src/server/puppet-implementation.js.map +1 -1
  26. package/package.json +4 -4
  27. package/src/client/payload-store.ts +2 -2
  28. package/src/client/puppet-service.spec.ts +3 -1
  29. package/src/client/puppet-service.ts +247 -3
  30. package/src/package-json.ts +4 -4
  31. package/src/server/puppet-implementation.ts +209 -3
@@ -50,7 +50,7 @@ import { packageJson } from '../package-json.js'
50
50
 
51
51
  import { GrpcManager } from './grpc-manager.js'
52
52
  import { PayloadStore } from './payload-store.js'
53
- import { OptionalBooleanUnwrapper, OptionalBooleanWrapper, callRecordPbToPayload, channelPayloadToPb, channelPbToPayload, chatHistoryPbToPayload, contactPbToPayload, postPayloadToPb, roomMemberPbToPayload, urlLinkPbToPayload, channelCardPayloadToPb, channelCardPbToPayload } from '../utils/pb-payload-helper.js'
53
+ import { OptionalBooleanUnwrapper, OptionalBooleanWrapper, callRecordPbToPayload, channelPayloadToPb, channelPbToPayload, chatHistoryPbToPayload, contactPbToPayload, postPayloadToPb, roomMemberPbToPayload, urlLinkPbToPayload, channelCardPayloadToPb, channelCardPbToPayload, miniProgramPayloadToPb, urlLinkPayloadToPb, locationPayloadToPb } from '../utils/pb-payload-helper.js'
54
54
  import type { MessageBroadcastTargets } from '@juzi/wechaty-puppet/dist/esm/src/schemas/message.js'
55
55
  import { timeoutPromise } from 'gerror'
56
56
  import { BooleanIndicator } from 'state-switch'
@@ -72,6 +72,34 @@ export type PuppetServiceOptions = PUPPET.PuppetOptions & {
72
72
  const ResetLoginTimeout = 30 * 1000
73
73
  const ResetReadyTimeout = 20 * 1000 // normally ready comes 15 seconds after login
74
74
 
75
+ type MessageBatchSendResponse = Awaited<ReturnType<PUPPET.impls.PuppetInterface['messageBatchSendText']>>
76
+
77
+ type GrpcUnaryMethod<Request, Response> = {
78
+ (request: Request, callback: (error: Error | null, response: Response) => void): unknown,
79
+ }
80
+
81
+ type GrpcBatchResult = {
82
+ getConversationId(): string,
83
+ getError(): string,
84
+ getId(): string,
85
+ }
86
+
87
+ type GrpcBatchResponse<Result extends GrpcBatchResult> = {
88
+ getResultsList(): Result[],
89
+ }
90
+
91
+ function grpcBatchResultsToPayload<Result extends GrpcBatchResult> (
92
+ response: GrpcBatchResponse<Result>,
93
+ ): MessageBatchSendResponse {
94
+ return {
95
+ results: response.getResultsList().map(result => ({
96
+ conversationId : result.getConversationId(),
97
+ error : result.getError() || undefined,
98
+ id : result.getId() || undefined,
99
+ })),
100
+ }
101
+ }
102
+
75
103
  class PuppetService extends PUPPET.Puppet {
76
104
 
77
105
  static override readonly VERSION = VERSION
@@ -125,6 +153,17 @@ class PuppetService extends PUPPET.Puppet {
125
153
  return JSON.stringify(normalizedFileBox)
126
154
  }
127
155
 
156
+ private async grpcUnary<Request, Response> (
157
+ method : GrpcUnaryMethod<Request, Response>,
158
+ request : Request,
159
+ ): Promise<Response> {
160
+ const promisified = util.promisify(
161
+ method.bind(this.grpcManager.client),
162
+ ) as (request: Request) => Promise<Response>
163
+
164
+ return promisified(request)
165
+ }
166
+
128
167
  override name () {
129
168
  return packageJson.name || 'wechaty-puppet-service'
130
169
  }
@@ -461,7 +500,7 @@ class PuppetService extends PUPPET.Puppet {
461
500
  ): Promise<void> {
462
501
  log.verbose('PuppetService', 'fastDirty(%s<%s>, %s)', PUPPET.types.Dirty[payloadType], payloadType, payloadId)
463
502
 
464
- const dirtyMap = {
503
+ const dirtyMap: Partial<Record<PUPPET.types.Dirty, (id: string) => Promise<unknown>>> = {
465
504
  [PUPPET.types.Dirty.Contact]: async (id: string) => this._payloadStore.contact?.delete(id),
466
505
  [PUPPET.types.Dirty.Friendship]: async (_: string) => {},
467
506
  [PUPPET.types.Dirty.Message]: async (_: string) => {},
@@ -474,7 +513,7 @@ class PuppetService extends PUPPET.Puppet {
474
513
  }
475
514
 
476
515
  try {
477
- await dirtyMap[payloadType](payloadId)
516
+ await dirtyMap[payloadType]?.(payloadId)
478
517
  } catch (error) {
479
518
  this.emit('error', error)
480
519
  }
@@ -1487,6 +1526,211 @@ class PuppetService extends PUPPET.Puppet {
1487
1526
  }
1488
1527
  }
1489
1528
 
1529
+ override async messageBatchSendText (
1530
+ conversationIds : string[],
1531
+ text : string,
1532
+ batchTaskId? : string,
1533
+ ): Promise<MessageBatchSendResponse> {
1534
+ log.verbose('PuppetService', 'messageBatchSendText(%s)', conversationIds.join(','))
1535
+
1536
+ const request = new grpcPuppet.MessageBatchSendTextRequest()
1537
+ request.setConversationIdsList(conversationIds)
1538
+ request.setText(text)
1539
+ if (batchTaskId) {
1540
+ request.setBatchTaskId(batchTaskId)
1541
+ }
1542
+
1543
+ const response = await this.grpcUnary<grpcPuppet.MessageBatchSendTextRequest, grpcPuppet.MessageBatchSendTextResponse>(
1544
+ this.grpcManager.client.messageBatchSendText,
1545
+ request,
1546
+ )
1547
+
1548
+ return grpcBatchResultsToPayload(response)
1549
+ }
1550
+
1551
+ override async messageBatchSendFile (
1552
+ conversationIds : string[],
1553
+ fileBox : FileBoxInterface,
1554
+ batchTaskId? : string,
1555
+ ): Promise<MessageBatchSendResponse> {
1556
+ log.verbose('PuppetService', 'messageBatchSendFile(%s)', conversationIds.join(','))
1557
+
1558
+ const request = new grpcPuppet.MessageBatchSendFileRequest()
1559
+ request.setConversationIdsList(conversationIds)
1560
+ request.setFileBox(await this.serializeFileBox(fileBox))
1561
+ if (batchTaskId) {
1562
+ request.setBatchTaskId(batchTaskId)
1563
+ }
1564
+
1565
+ const response = await this.grpcUnary<grpcPuppet.MessageBatchSendFileRequest, grpcPuppet.MessageBatchSendFileResponse>(
1566
+ this.grpcManager.client.messageBatchSendFile,
1567
+ request,
1568
+ )
1569
+
1570
+ return grpcBatchResultsToPayload(response)
1571
+ }
1572
+
1573
+ override async messageBatchForward (
1574
+ conversationIds : string[],
1575
+ messageIds : string | string[],
1576
+ batchTaskId? : string,
1577
+ ): Promise<MessageBatchSendResponse> {
1578
+ log.verbose('PuppetService', 'messageBatchForward(%s, %s)', conversationIds.join(','), messageIds)
1579
+
1580
+ const request = new grpcPuppet.MessageBatchForwardRequest()
1581
+ request.setConversationIdsList(conversationIds)
1582
+ if (Array.isArray(messageIds)) {
1583
+ request.setMessageIdsList(messageIds)
1584
+ if (messageIds.length === 1) {
1585
+ request.setMessageId(messageIds[0] as string)
1586
+ }
1587
+ } else {
1588
+ request.setMessageId(messageIds)
1589
+ }
1590
+ if (batchTaskId) {
1591
+ request.setBatchTaskId(batchTaskId)
1592
+ }
1593
+
1594
+ const response = await this.grpcUnary<grpcPuppet.MessageBatchForwardRequest, grpcPuppet.MessageBatchForwardResponse>(
1595
+ this.grpcManager.client.messageBatchForward,
1596
+ request,
1597
+ )
1598
+
1599
+ return grpcBatchResultsToPayload(response)
1600
+ }
1601
+
1602
+ override async messageBatchSendContact (
1603
+ conversationIds : string[],
1604
+ contactId : string,
1605
+ batchTaskId? : string,
1606
+ ): Promise<MessageBatchSendResponse> {
1607
+ log.verbose('PuppetService', 'messageBatchSendContact(%s, %s)', conversationIds.join(','), contactId)
1608
+
1609
+ const request = new grpcPuppet.MessageBatchSendContactRequest()
1610
+ request.setConversationIdsList(conversationIds)
1611
+ request.setContactId(contactId)
1612
+ if (batchTaskId) {
1613
+ request.setBatchTaskId(batchTaskId)
1614
+ }
1615
+
1616
+ const response = await this.grpcUnary<grpcPuppet.MessageBatchSendContactRequest, grpcPuppet.MessageBatchSendContactResponse>(
1617
+ this.grpcManager.client.messageBatchSendContact,
1618
+ request,
1619
+ )
1620
+
1621
+ return grpcBatchResultsToPayload(response)
1622
+ }
1623
+
1624
+ override async messageBatchSendUrl (
1625
+ conversationIds : string[],
1626
+ urlLinkPayload : PUPPET.payloads.UrlLink,
1627
+ batchTaskId? : string,
1628
+ ): Promise<MessageBatchSendResponse> {
1629
+ log.verbose('PuppetService', 'messageBatchSendUrl(%s)', conversationIds.join(','))
1630
+
1631
+ const request = new grpcPuppet.MessageBatchSendUrlRequest()
1632
+ request.setConversationIdsList(conversationIds)
1633
+ request.setUrlLink(urlLinkPayloadToPb(grpcPuppet, urlLinkPayload))
1634
+ if (batchTaskId) {
1635
+ request.setBatchTaskId(batchTaskId)
1636
+ }
1637
+
1638
+ const response = await this.grpcUnary<grpcPuppet.MessageBatchSendUrlRequest, grpcPuppet.MessageBatchSendUrlResponse>(
1639
+ this.grpcManager.client.messageBatchSendUrl,
1640
+ request,
1641
+ )
1642
+
1643
+ return grpcBatchResultsToPayload(response)
1644
+ }
1645
+
1646
+ override async messageBatchSendMiniProgram (
1647
+ conversationIds : string[],
1648
+ miniProgramPayload : PUPPET.payloads.MiniProgram,
1649
+ batchTaskId? : string,
1650
+ ): Promise<MessageBatchSendResponse> {
1651
+ log.verbose('PuppetService', 'messageBatchSendMiniProgram(%s)', conversationIds.join(','))
1652
+
1653
+ const request = new grpcPuppet.MessageBatchSendMiniProgramRequest()
1654
+ request.setConversationIdsList(conversationIds)
1655
+ request.setMiniProgram(miniProgramPayloadToPb(grpcPuppet, miniProgramPayload))
1656
+ if (batchTaskId) {
1657
+ request.setBatchTaskId(batchTaskId)
1658
+ }
1659
+
1660
+ const response = await this.grpcUnary<grpcPuppet.MessageBatchSendMiniProgramRequest, grpcPuppet.MessageBatchSendMiniProgramResponse>(
1661
+ this.grpcManager.client.messageBatchSendMiniProgram,
1662
+ request,
1663
+ )
1664
+
1665
+ return grpcBatchResultsToPayload(response)
1666
+ }
1667
+
1668
+ override async messageBatchSendLocation (
1669
+ conversationIds : string[],
1670
+ locationPayload : PUPPET.payloads.Location,
1671
+ batchTaskId? : string,
1672
+ ): Promise<MessageBatchSendResponse> {
1673
+ log.verbose('PuppetService', 'messageBatchSendLocation(%s)', conversationIds.join(','))
1674
+
1675
+ const request = new grpcPuppet.MessageBatchSendLocationRequest()
1676
+ request.setConversationIdsList(conversationIds)
1677
+ request.setLocation(locationPayloadToPb(grpcPuppet, locationPayload))
1678
+ if (batchTaskId) {
1679
+ request.setBatchTaskId(batchTaskId)
1680
+ }
1681
+
1682
+ const response = await this.grpcUnary<grpcPuppet.MessageBatchSendLocationRequest, grpcPuppet.MessageBatchSendLocationResponse>(
1683
+ this.grpcManager.client.messageBatchSendLocation,
1684
+ request,
1685
+ )
1686
+
1687
+ return grpcBatchResultsToPayload(response)
1688
+ }
1689
+
1690
+ override async messageBatchSendChannel (
1691
+ conversationIds : string[],
1692
+ channelPayload : PUPPET.payloads.Channel,
1693
+ batchTaskId? : string,
1694
+ ): Promise<MessageBatchSendResponse> {
1695
+ log.verbose('PuppetService', 'messageBatchSendChannel(%s)', conversationIds.join(','))
1696
+
1697
+ const request = new grpcPuppet.MessageBatchSendChannelRequest()
1698
+ request.setConversationIdsList(conversationIds)
1699
+ request.setChannel(channelPayloadToPb(grpcPuppet, channelPayload))
1700
+ if (batchTaskId) {
1701
+ request.setBatchTaskId(batchTaskId)
1702
+ }
1703
+
1704
+ const response = await this.grpcUnary<grpcPuppet.MessageBatchSendChannelRequest, grpcPuppet.MessageBatchSendChannelResponse>(
1705
+ this.grpcManager.client.messageBatchSendChannel,
1706
+ request,
1707
+ )
1708
+
1709
+ return grpcBatchResultsToPayload(response)
1710
+ }
1711
+
1712
+ override async messageBatchSendChannelCard (
1713
+ conversationIds : string[],
1714
+ channelCardPayload : PUPPET.payloads.ChannelCard,
1715
+ batchTaskId? : string,
1716
+ ): Promise<MessageBatchSendResponse> {
1717
+ log.verbose('PuppetService', 'messageBatchSendChannelCard(%s)', conversationIds.join(','))
1718
+
1719
+ const request = new grpcPuppet.MessageBatchSendChannelCardRequest()
1720
+ request.setConversationIdsList(conversationIds)
1721
+ request.setChannelCard(channelCardPayloadToPb(grpcPuppet, channelCardPayload))
1722
+ if (batchTaskId) {
1723
+ request.setBatchTaskId(batchTaskId)
1724
+ }
1725
+
1726
+ const response = await this.grpcUnary<grpcPuppet.MessageBatchSendChannelCardRequest, grpcPuppet.MessageBatchSendChannelCardResponse>(
1727
+ this.grpcManager.client.messageBatchSendChannelCard,
1728
+ request,
1729
+ )
1730
+
1731
+ return grpcBatchResultsToPayload(response)
1732
+ }
1733
+
1490
1734
  override async messageSendFile (
1491
1735
  conversationId : string,
1492
1736
  fileBox : FileBoxInterface,
@@ -4,7 +4,7 @@
4
4
  import type { PackageJson } from 'type-fest'
5
5
  export const packageJson: PackageJson = {
6
6
  "name": "@juzi/wechaty-puppet-service",
7
- "version": "1.0.113",
7
+ "version": "1.0.114",
8
8
  "description": "Puppet Service for Wechaty",
9
9
  "type": "module",
10
10
  "exports": {
@@ -55,7 +55,7 @@ export const packageJson: PackageJson = {
55
55
  "@chatie/eslint-config": "^1.0.4",
56
56
  "@chatie/semver": "^0.4.7",
57
57
  "@chatie/tsconfig": "^4.6.3",
58
- "@juzi/wechaty-puppet": "^1.0.125",
58
+ "@juzi/wechaty-puppet": "^1.0.137",
59
59
  "@juzi/wechaty-puppet-mock": "^1.0.1",
60
60
  "@swc/core": "1.3.39",
61
61
  "@types/google-protobuf": "^3.15.5",
@@ -74,10 +74,10 @@ export const packageJson: PackageJson = {
74
74
  "why-is-node-running": "^2.2.1"
75
75
  },
76
76
  "peerDependencies": {
77
- "@juzi/wechaty-puppet": "^1.0.84"
77
+ "@juzi/wechaty-puppet": "^1.0.137"
78
78
  },
79
79
  "dependencies": {
80
- "@juzi/wechaty-grpc": "^1.0.100",
80
+ "@juzi/wechaty-grpc": "^1.0.101",
81
81
  "clone-class": "^1.1.1",
82
82
  "ducks": "^1.0.2",
83
83
  "file-box": "^1.5.5",
@@ -46,6 +46,36 @@ import { EventStreamManager } from './event-stream-manager.js'
46
46
  import { OptionalBooleanUnwrapper, OptionalBooleanWrapper, callRecordPayloadToPb, channelPayloadToPb, chatHistoryPayloadToPb, postPbToPayload, urlLinkPayloadToPb, channelCardPayloadToPb } from '../utils/pb-payload-helper.js'
47
47
  import { TextContentType } from '@juzi/wechaty-puppet/types'
48
48
 
49
+ type MessageBatchSendResponse = Awaited<ReturnType<PUPPET.impls.PuppetInterface['messageBatchSendText']>>
50
+
51
+ type GrpcBatchResult = {
52
+ setConversationId(value: string): void,
53
+ setError(value: string): void,
54
+ setId(value: string): void,
55
+ }
56
+
57
+ type GrpcBatchResponse<Result extends GrpcBatchResult> = {
58
+ setResultsList(value: Result[]): void,
59
+ }
60
+
61
+ const setGrpcBatchResults = <Result extends GrpcBatchResult> (
62
+ response : GrpcBatchResponse<Result>,
63
+ ResultClass : new () => Result,
64
+ payload : MessageBatchSendResponse,
65
+ ): void => {
66
+ response.setResultsList(payload.results.map(result => {
67
+ const pbResult = new ResultClass()
68
+ pbResult.setConversationId(result.conversationId)
69
+ if (result.id) {
70
+ pbResult.setId(result.id)
71
+ }
72
+ if (result.error) {
73
+ pbResult.setError(result.error)
74
+ }
75
+ return pbResult
76
+ }))
77
+ }
78
+
49
79
  function puppetImplementation (
50
80
  puppet : PUPPET.impls.PuppetInterface,
51
81
  FileBoxUuid : typeof FileBox,
@@ -1251,6 +1281,180 @@ function puppetImplementation (
1251
1281
  }
1252
1282
  },
1253
1283
 
1284
+ messageBatchSendText: async (call, callback) => {
1285
+ log.verbose('PuppetServiceImpl', 'messageBatchSendText()')
1286
+
1287
+ try {
1288
+ const results = await puppet.messageBatchSendText(
1289
+ call.request.getConversationIdsList(),
1290
+ call.request.getText(),
1291
+ call.request.getBatchTaskId(),
1292
+ )
1293
+ const response = new grpcPuppet.MessageBatchSendTextResponse()
1294
+ setGrpcBatchResults(response, grpcPuppet.MessageBatchSendTextResponse.Result, results)
1295
+ return callback(null, response)
1296
+ } catch (e) {
1297
+ return grpcError('messageBatchSendText', e, callback)
1298
+ }
1299
+ },
1300
+
1301
+ messageBatchSendFile: async (call, callback) => {
1302
+ log.verbose('PuppetServiceImpl', 'messageBatchSendFile()')
1303
+
1304
+ try {
1305
+ const results = await puppet.messageBatchSendFile(
1306
+ call.request.getConversationIdsList(),
1307
+ FileBoxUuid.fromJSON(call.request.getFileBox()),
1308
+ call.request.getBatchTaskId(),
1309
+ )
1310
+ const response = new grpcPuppet.MessageBatchSendFileResponse()
1311
+ setGrpcBatchResults(response, grpcPuppet.MessageBatchSendFileResponse.Result, results)
1312
+ return callback(null, response)
1313
+ } catch (e) {
1314
+ return grpcError('messageBatchSendFile', e, callback)
1315
+ }
1316
+ },
1317
+
1318
+ messageBatchForward: async (call, callback) => {
1319
+ log.verbose('PuppetServiceImpl', 'messageBatchForward()')
1320
+
1321
+ try {
1322
+ const messageIds = call.request.getMessageIdsList()
1323
+ const results = await puppet.messageBatchForward(
1324
+ call.request.getConversationIdsList(),
1325
+ messageIds.length > 0 ? messageIds : call.request.getMessageId(),
1326
+ call.request.getBatchTaskId(),
1327
+ )
1328
+ const response = new grpcPuppet.MessageBatchForwardResponse()
1329
+ setGrpcBatchResults(response, grpcPuppet.MessageBatchForwardResponse.Result, results)
1330
+ return callback(null, response)
1331
+ } catch (e) {
1332
+ return grpcError('messageBatchForward', e, callback)
1333
+ }
1334
+ },
1335
+
1336
+ messageBatchSendContact: async (call, callback) => {
1337
+ log.verbose('PuppetServiceImpl', 'messageBatchSendContact()')
1338
+
1339
+ try {
1340
+ const results = await puppet.messageBatchSendContact(
1341
+ call.request.getConversationIdsList(),
1342
+ call.request.getContactId(),
1343
+ call.request.getBatchTaskId(),
1344
+ )
1345
+ const response = new grpcPuppet.MessageBatchSendContactResponse()
1346
+ setGrpcBatchResults(response, grpcPuppet.MessageBatchSendContactResponse.Result, results)
1347
+ return callback(null, response)
1348
+ } catch (e) {
1349
+ return grpcError('messageBatchSendContact', e, callback)
1350
+ }
1351
+ },
1352
+
1353
+ messageBatchSendUrl: async (call, callback) => {
1354
+ log.verbose('PuppetServiceImpl', 'messageBatchSendUrl()')
1355
+
1356
+ try {
1357
+ const payload = call.request.getUrlLink()?.toObject()
1358
+ if (!payload) {
1359
+ throw new Error('no url link payload found')
1360
+ }
1361
+ const results = await puppet.messageBatchSendUrl(
1362
+ call.request.getConversationIdsList(),
1363
+ payload,
1364
+ call.request.getBatchTaskId(),
1365
+ )
1366
+ const response = new grpcPuppet.MessageBatchSendUrlResponse()
1367
+ setGrpcBatchResults(response, grpcPuppet.MessageBatchSendUrlResponse.Result, results)
1368
+ return callback(null, response)
1369
+ } catch (e) {
1370
+ return grpcError('messageBatchSendUrl', e, callback)
1371
+ }
1372
+ },
1373
+
1374
+ messageBatchSendMiniProgram: async (call, callback) => {
1375
+ log.verbose('PuppetServiceImpl', 'messageBatchSendMiniProgram()')
1376
+
1377
+ try {
1378
+ const payload = call.request.getMiniProgram()?.toObject()
1379
+ if (!payload) {
1380
+ throw new Error('no mini program payload found')
1381
+ }
1382
+ const results = await puppet.messageBatchSendMiniProgram(
1383
+ call.request.getConversationIdsList(),
1384
+ payload,
1385
+ call.request.getBatchTaskId(),
1386
+ )
1387
+ const response = new grpcPuppet.MessageBatchSendMiniProgramResponse()
1388
+ setGrpcBatchResults(response, grpcPuppet.MessageBatchSendMiniProgramResponse.Result, results)
1389
+ return callback(null, response)
1390
+ } catch (e) {
1391
+ return grpcError('messageBatchSendMiniProgram', e, callback)
1392
+ }
1393
+ },
1394
+
1395
+ messageBatchSendLocation: async (call, callback) => {
1396
+ log.verbose('PuppetServiceImpl', 'messageBatchSendLocation()')
1397
+
1398
+ try {
1399
+ const payload = call.request.getLocation()?.toObject()
1400
+ if (!payload) {
1401
+ throw new Error('no location payload found')
1402
+ }
1403
+ const results = await puppet.messageBatchSendLocation(
1404
+ call.request.getConversationIdsList(),
1405
+ payload,
1406
+ call.request.getBatchTaskId(),
1407
+ )
1408
+ const response = new grpcPuppet.MessageBatchSendLocationResponse()
1409
+ setGrpcBatchResults(response, grpcPuppet.MessageBatchSendLocationResponse.Result, results)
1410
+ return callback(null, response)
1411
+ } catch (e) {
1412
+ return grpcError('messageBatchSendLocation', e, callback)
1413
+ }
1414
+ },
1415
+
1416
+ messageBatchSendChannel: async (call, callback) => {
1417
+ log.verbose('PuppetServiceImpl', 'messageBatchSendChannel()')
1418
+
1419
+ try {
1420
+ const payload = call.request.getChannel()?.toObject()
1421
+ if (!payload) {
1422
+ throw new Error('no channel payload found')
1423
+ }
1424
+ const results = await puppet.messageBatchSendChannel(
1425
+ call.request.getConversationIdsList(),
1426
+ payload,
1427
+ call.request.getBatchTaskId(),
1428
+ )
1429
+ const response = new grpcPuppet.MessageBatchSendChannelResponse()
1430
+ setGrpcBatchResults(response, grpcPuppet.MessageBatchSendChannelResponse.Result, results)
1431
+ return callback(null, response)
1432
+ } catch (e) {
1433
+ return grpcError('messageBatchSendChannel', e, callback)
1434
+ }
1435
+ },
1436
+
1437
+ messageBatchSendChannelCard: async (call, callback) => {
1438
+ log.verbose('PuppetServiceImpl', 'messageBatchSendChannelCard()')
1439
+
1440
+ try {
1441
+ const payload = call.request.getChannelCard()?.toObject()
1442
+ if (!payload) {
1443
+ throw new Error('no channel card payload found')
1444
+ }
1445
+ const results = await puppet.messageBatchSendChannelCard(
1446
+ call.request.getConversationIdsList(),
1447
+ payload,
1448
+ call.request.getBatchTaskId(),
1449
+ )
1450
+ const response = new grpcPuppet.MessageBatchSendChannelCardResponse()
1451
+ setGrpcBatchResults(response, grpcPuppet.MessageBatchSendChannelCardResponse.Result, results)
1452
+ return callback(null, response)
1453
+ } catch (e) {
1454
+ return grpcError('messageBatchSendChannelCard', e, callback)
1455
+ }
1456
+ },
1457
+
1254
1458
  messageSendUrl: async (call, callback) => {
1255
1459
  log.verbose('PuppetServiceImpl', 'messageSendUrl()')
1256
1460
 
@@ -1494,9 +1698,11 @@ function puppetImplementation (
1494
1698
  const inviteOnly = call.request.getInviteOnly()
1495
1699
  const quoteIds = call.request.getQuoteIdsList()
1496
1700
 
1497
- const target = contactIds.length > 0 ? contactIds : contactId
1498
-
1499
- await puppet.roomAdd(roomId, target, inviteOnly, quoteIds)
1701
+ if (contactIds.length > 1) {
1702
+ await puppet.roomAddV2(roomId, contactIds, inviteOnly, quoteIds)
1703
+ } else {
1704
+ await puppet.roomAdd(roomId, contactId || contactIds[0] || '', inviteOnly, quoteIds)
1705
+ }
1500
1706
 
1501
1707
  return callback(null, new grpcPuppet.RoomAddResponse())
1502
1708