wechaty-puppet-matrix 0.0.12 → 0.0.14
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.
- package/dist/cjs/src/matrix/messages/message-location.d.ts +2 -0
- package/dist/cjs/src/matrix/messages/message-location.d.ts.map +1 -0
- package/dist/cjs/src/matrix/messages/message-location.js +18 -0
- package/dist/cjs/src/matrix/service/request.d.ts +1 -0
- package/dist/cjs/src/matrix/service/request.d.ts.map +1 -1
- package/dist/cjs/src/matrix/service/request.js +99 -61
- package/dist/cjs/src/puppet-matrix.d.ts +1 -0
- package/dist/cjs/src/puppet-matrix.d.ts.map +1 -1
- package/dist/cjs/src/puppet-matrix.js +12 -2
- package/dist/esm/src/matrix/messages/message-location.d.ts +2 -0
- package/dist/esm/src/matrix/messages/message-location.d.ts.map +1 -0
- package/dist/esm/src/matrix/messages/message-location.js +15 -0
- package/dist/esm/src/matrix/service/request.d.ts +1 -0
- package/dist/esm/src/matrix/service/request.d.ts.map +1 -1
- package/dist/esm/src/matrix/service/request.js +99 -61
- package/dist/esm/src/puppet-matrix.d.ts +1 -0
- package/dist/esm/src/puppet-matrix.d.ts.map +1 -1
- package/dist/esm/src/puppet-matrix.js +12 -2
- package/package.json +1 -1
- package/src/matrix/messages/message-location.ts +46 -0
- package/src/matrix/service/request.ts +118 -63
- package/src/puppet-matrix.ts +22 -4
|
@@ -392,20 +392,23 @@ async function getImageInfo (imageUrl: string) {
|
|
|
392
392
|
'.wechaty',
|
|
393
393
|
'puppet-matrix-cache',
|
|
394
394
|
path.sep,
|
|
395
|
-
'temp_image_' + Date.now() + path.extname(imageUrl),
|
|
396
|
-
path.sep,
|
|
397
395
|
)
|
|
398
396
|
const baseDirExist = await fs.pathExists(tempFilePath)
|
|
399
397
|
if (!baseDirExist) {
|
|
400
398
|
await fs.mkdirp(tempFilePath)
|
|
401
399
|
}
|
|
402
|
-
|
|
400
|
+
const finalFilePath = path.join(
|
|
401
|
+
tempFilePath,
|
|
402
|
+
'temp_image_' + Date.now() + path.extname(imageUrl),
|
|
403
|
+
)
|
|
404
|
+
|
|
405
|
+
await fs.writeFile(finalFilePath, response.data)
|
|
403
406
|
|
|
404
407
|
// 4. 获取图片宽高
|
|
405
|
-
const dimensions = imageSize(
|
|
408
|
+
const dimensions = imageSize(finalFilePath)
|
|
406
409
|
|
|
407
410
|
// 5. 删除临时文件
|
|
408
|
-
await fs.unlink(
|
|
411
|
+
await fs.unlink(finalFilePath)
|
|
409
412
|
|
|
410
413
|
return {
|
|
411
414
|
file_size: fileSize, // 文件大小(字节)
|
|
@@ -419,59 +422,81 @@ async function getImageInfo (imageUrl: string) {
|
|
|
419
422
|
}
|
|
420
423
|
}
|
|
421
424
|
|
|
422
|
-
|
|
425
|
+
function splitAddress (address = '') {
|
|
426
|
+
if (!address) {
|
|
427
|
+
return { province: '', city: '', area: '' }
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
let province: any = ''
|
|
431
|
+
let city: any = ''
|
|
432
|
+
let area: any = ''
|
|
433
|
+
|
|
434
|
+
// 省级行政区划
|
|
435
|
+
const provinceRegex = /^(.*?(省|自治区|市))|^(.*?)(北京|天津|上海|重庆)市?$/
|
|
436
|
+
const provinceMatch = address.match(provinceRegex)
|
|
437
|
+
if (provinceMatch) {
|
|
438
|
+
province = provinceMatch[1] || provinceMatch[3]
|
|
439
|
+
address = address.replace(province, '')
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// 市级行政区划
|
|
443
|
+
const cityRegex = /^(.*?(市|自治州|地区|盟))|^([^\u4e00-\u9fa5]*)(北京|天津|上海|重庆)$/
|
|
444
|
+
const cityMatch = address.match(cityRegex)
|
|
445
|
+
if (cityMatch) {
|
|
446
|
+
city = cityMatch[1] || cityMatch[3]
|
|
447
|
+
address = address.replace(city, '')
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// 区/县级行政区划
|
|
451
|
+
const areaRegex = /^(.*?(区|县|市|旗|自治县|林区|特区))|^(.*?(街道|镇|乡))|^([^\u4e00-\u9fa5]*)/
|
|
452
|
+
const areaMatch = address.match(areaRegex)
|
|
453
|
+
if (areaMatch) {
|
|
454
|
+
area = areaMatch[1] || areaMatch[3] || areaMatch[4]
|
|
455
|
+
address = address.replace(area, '')
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return { province, city, area }
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
const genTextPosSnsXml = (wxid: string, content: string, location: any): string => {
|
|
462
|
+
const addressInfo: any = location ? splitAddress(location.address) : {}
|
|
423
463
|
const xmlTemplate = `
|
|
424
464
|
<TimelineObject>
|
|
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
|
-
<contentUrl></contentUrl>
|
|
455
|
-
</ContentObject>
|
|
456
|
-
<actionInfo>
|
|
457
|
-
<appMsg>
|
|
458
|
-
<mediaTagName></mediaTagName>
|
|
459
|
-
<messageExt></messageExt>
|
|
460
|
-
<messageAction></messageAction>
|
|
461
|
-
</appMsg>
|
|
462
|
-
</actionInfo>
|
|
463
|
-
<appInfo><id></id></appInfo>
|
|
464
|
-
<publicUserName></publicUserName>
|
|
465
|
-
<streamvideo>
|
|
466
|
-
<streamvideourl></streamvideourl>
|
|
467
|
-
<streamvideothumburl></streamvideothumburl>
|
|
468
|
-
<streamvideoweburl></streamvideoweburl>
|
|
469
|
-
</streamvideo>
|
|
470
|
-
</TimelineObject>`.replace(/\s+/g, '')
|
|
465
|
+
<id>0</id>
|
|
466
|
+
<username><![CDATA[${wxid}]]></username>
|
|
467
|
+
<createTime><![CDATA[${Math.floor(Date.now() / 1000)}]]></createTime>
|
|
468
|
+
<contentDesc><![CDATA[${content}]]></contentDesc>
|
|
469
|
+
<contentDescShowType>0</contentDescShowType>
|
|
470
|
+
<contentDescScene>3</contentDescScene>
|
|
471
|
+
<private>0</private>
|
|
472
|
+
<sightFolded>0</sightFolded>
|
|
473
|
+
<showFlag>0</showFlag>${location ? `<location city="${addressInfo.city}" longitude="${location.longitude}" latitude="${location.latitude}" poiName="${location.name}" poiAddress="${location.address}" poiScale="11.000000" poiInfoUrl="" poiClassifyId="${location.poiId}" poiClassifyType="1" poiClickableStatus="0" buildingId="0" floorName=""/>` : ''}
|
|
474
|
+
<appInfo>
|
|
475
|
+
<id/>
|
|
476
|
+
<version/>
|
|
477
|
+
<appName/>
|
|
478
|
+
<installUrl/>
|
|
479
|
+
<fromUrl/>
|
|
480
|
+
<isForceUpdate>0</isForceUpdate>
|
|
481
|
+
<isHidden>0</isHidden>
|
|
482
|
+
</appInfo>
|
|
483
|
+
<sourceUserName/>
|
|
484
|
+
<sourceNickName/>
|
|
485
|
+
<statisticsData/>
|
|
486
|
+
<statExtStr/>
|
|
487
|
+
<ContentObject>
|
|
488
|
+
<contentStyle>2</contentStyle>
|
|
489
|
+
<title/>
|
|
490
|
+
<description/>
|
|
491
|
+
<mediaList/>
|
|
492
|
+
</ContentObject>
|
|
493
|
+
</TimelineObject>`
|
|
471
494
|
return xmlTemplate
|
|
472
495
|
}
|
|
473
496
|
|
|
474
|
-
const genVideoSnsXml = (wxid: string, content: string, media: Media): string => {
|
|
497
|
+
const genVideoSnsXml = (wxid: string, content: string, media: Media, location: any): string => {
|
|
498
|
+
const addressInfo: any = location ? splitAddress(location.address) : {}
|
|
499
|
+
|
|
475
500
|
const xmlTemplate = `
|
|
476
501
|
<TimelineObject>
|
|
477
502
|
<id>0</id>
|
|
@@ -482,7 +507,7 @@ const genVideoSnsXml = (wxid: string, content: string, media: Media): string =>
|
|
|
482
507
|
<contentDescScene>0</contentDescScene>
|
|
483
508
|
<private>0</private>
|
|
484
509
|
<sightFolded>0</sightFolded>
|
|
485
|
-
<showFlag>0</showFlag
|
|
510
|
+
<showFlag>0</showFlag>${location ? `<location city="${addressInfo.city}" longitude="${location.longitude}" latitude="${location.latitude}" poiName="${location.name}" poiAddress="${location.address}" poiScale="11.000000" poiInfoUrl="" poiClassifyId="${location.poiId}" poiClassifyType="1" poiClickableStatus="0" buildingId="0" floorName=""/>` : ''}
|
|
486
511
|
<appInfo>
|
|
487
512
|
<id></id>
|
|
488
513
|
<version></version>
|
|
@@ -505,23 +530,24 @@ const genVideoSnsXml = (wxid: string, content: string, media: Media): string =>
|
|
|
505
530
|
<id>0</id>
|
|
506
531
|
<type>6</type>
|
|
507
532
|
<title></title>
|
|
508
|
-
<description
|
|
533
|
+
<description>${content}</description>
|
|
509
534
|
<private>0</private>
|
|
510
535
|
<userData></userData>
|
|
511
536
|
<subType>0</subType>
|
|
512
537
|
<videoSize width="${media.video_width}" height="${media.video_height}"/>
|
|
513
|
-
<url type="1" md5="951a7d7864d685a92fd2624155794bf9" videomd5="577f55635faf44f595a69ded26d87bcc">${media.file_url}</url>
|
|
514
|
-
<thumb type="1">${media.thumb_url}</thumb>
|
|
538
|
+
<url type="1" md5="951a7d7864d685a92fd2624155794bf9" videomd5="577f55635faf44f595a69ded26d87bcc">${media.file_url.replaceAll('&', '&')}</url>
|
|
539
|
+
<thumb type="1">${media.thumb_url.replaceAll('&', '&')}</thumb>
|
|
515
540
|
<size width="${media.thumb_width}.000000" height="${media.thumb_height}.000000" totalSize="${media.file_size}"/>
|
|
516
541
|
<videoDuration>${media.video_duration}.000000</videoDuration>
|
|
517
542
|
</media>
|
|
518
543
|
</mediaList>
|
|
544
|
+
<contentUrl>https://support.weixin.qq.com/cgi-bin/mmsupport-bin/readtemplate?t=page/common_page__upgrade&v=1</contentUrl>
|
|
519
545
|
</ContentObject>
|
|
520
546
|
</TimelineObject>`
|
|
521
547
|
return xmlTemplate
|
|
522
548
|
}
|
|
523
549
|
|
|
524
|
-
const genImageSnsXml = (wxid: string, contentDesc: string, mediaList: Media[]): string => {
|
|
550
|
+
const genImageSnsXml = (wxid: string, contentDesc: string, mediaList: Media[], location: any): string => {
|
|
525
551
|
const mediaTemplate = (media: Media) => `
|
|
526
552
|
<media>
|
|
527
553
|
<id><![CDATA[0]]></id>
|
|
@@ -536,7 +562,7 @@ const genImageSnsXml = (wxid: string, contentDesc: string, mediaList: Media[]):
|
|
|
536
562
|
</media>`
|
|
537
563
|
|
|
538
564
|
const mediaString = mediaList.map(media => mediaTemplate(media)).join('')
|
|
539
|
-
|
|
565
|
+
const addressInfo: any = location ? splitAddress(location.address) : {}
|
|
540
566
|
const xmlTemplate = `
|
|
541
567
|
<TimelineObject>
|
|
542
568
|
<id><![CDATA[0]]></id>
|
|
@@ -563,6 +589,7 @@ const genImageSnsXml = (wxid: string, contentDesc: string, mediaList: Media[]):
|
|
|
563
589
|
<preloadResources></preloadResources>
|
|
564
590
|
</weappInfo>
|
|
565
591
|
<canvasInfoXml></canvasInfoXml>
|
|
592
|
+
${location ? `<location city="${addressInfo.city}" longitude="${location.longitude}" latitude="${location.latitude}" poiName="${location.name}" poiAddress="${location.address}" poiScale="11.000000" poiInfoUrl="" poiClassifyId="${location.poiId}" poiClassifyType="1" poiClickableStatus="0" buildingId="0" floorName=""/>` : ''}
|
|
566
593
|
<ContentObject>
|
|
567
594
|
<contentStyle><![CDATA[1]]></contentStyle>
|
|
568
595
|
<contentSubStyle><![CDATA[0]]></contentSubStyle>
|
|
@@ -2240,6 +2267,33 @@ class Client extends EventEmitter {
|
|
|
2240
2267
|
})
|
|
2241
2268
|
}
|
|
2242
2269
|
|
|
2270
|
+
/**
|
|
2271
|
+
*
|
|
2272
|
+
* @returns
|
|
2273
|
+
*/
|
|
2274
|
+
public async creatRoom (contactIdList: string[], topic: string): Promise<string> {
|
|
2275
|
+
try {
|
|
2276
|
+
const res = await this.postData({
|
|
2277
|
+
path: '/room/create_chatroom',
|
|
2278
|
+
data: {
|
|
2279
|
+
username_list: contactIdList,
|
|
2280
|
+
},
|
|
2281
|
+
})
|
|
2282
|
+
if (res?.baseResponse?.ret) {
|
|
2283
|
+
log.error('creatRoom error: %s', JSON.stringify(res.baseResponse))
|
|
2284
|
+
}
|
|
2285
|
+
const roomId = res.chatRoomName.string
|
|
2286
|
+
if (topic) {
|
|
2287
|
+
void this.setGroupName(roomId, topic)
|
|
2288
|
+
}
|
|
2289
|
+
return roomId
|
|
2290
|
+
|
|
2291
|
+
} catch (error) {
|
|
2292
|
+
log.error(PRE, 'sendContactCard(%s, %s): %s', contactIdList, topic, error)
|
|
2293
|
+
return ''
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2243
2297
|
/**
|
|
2244
2298
|
* 修改群名
|
|
2245
2299
|
* @param groupId 群id
|
|
@@ -2366,7 +2420,7 @@ class Client extends EventEmitter {
|
|
|
2366
2420
|
url,
|
|
2367
2421
|
},
|
|
2368
2422
|
})
|
|
2369
|
-
log.
|
|
2423
|
+
log.verbose('uploadSnsVideo result: %s', JSON.stringify(res))
|
|
2370
2424
|
if (res?.errcode !== 0) {
|
|
2371
2425
|
log.error('uploadSnsVideo error: %s', JSON.stringify(res))
|
|
2372
2426
|
}
|
|
@@ -2397,17 +2451,18 @@ class Client extends EventEmitter {
|
|
|
2397
2451
|
const imageBaseInfo = await getImageInfo(image)
|
|
2398
2452
|
imageInfo.push({ ...res, ...imageBaseInfo })
|
|
2399
2453
|
}
|
|
2400
|
-
xmlContent = genImageSnsXml(wxid, momentInfo.content, imageInfo)
|
|
2454
|
+
xmlContent = genImageSnsXml(wxid, momentInfo.content, imageInfo, momentInfo.location)
|
|
2401
2455
|
|
|
2402
2456
|
}
|
|
2403
2457
|
} else if (momentInfo.videoUrl) {
|
|
2404
2458
|
const mediaInfo: any = await this.uploadSnsVideo(momentInfo.videoUrl)
|
|
2405
2459
|
if (mediaInfo) {
|
|
2406
2460
|
const thumbInfo = await getImageInfo(mediaInfo.thumb_url)
|
|
2407
|
-
xmlContent = genVideoSnsXml(wxid, momentInfo.content, { ...mediaInfo, ...thumbInfo })
|
|
2461
|
+
xmlContent = genVideoSnsXml(wxid, momentInfo.content, { ...mediaInfo, ...thumbInfo }, momentInfo.location)
|
|
2408
2462
|
}
|
|
2409
2463
|
} else {
|
|
2410
|
-
xmlContent =
|
|
2464
|
+
xmlContent = genTextPosSnsXml(wxid, momentInfo.content, momentInfo.location)
|
|
2465
|
+
|
|
2411
2466
|
}
|
|
2412
2467
|
return await this.sendMoment(xmlContent)
|
|
2413
2468
|
} catch (error) {
|
package/src/puppet-matrix.ts
CHANGED
|
@@ -21,6 +21,7 @@ import { parseEmotionMessagePayload } from './matrix/messages/message-emotion.js
|
|
|
21
21
|
import { ImageMessagePayload, parseImageMessagePayload } from './matrix/messages/message-image.js'
|
|
22
22
|
import { parseAudioMessagePayload, AudioMessagePayload } from './matrix/messages/message-audio.js'
|
|
23
23
|
import { parseVideoMessagePayload, VideoMessagePayload } from './matrix/messages/message-video.js'
|
|
24
|
+
import { parseLocationMessagePayload } from './matrix/messages/message-location.js'
|
|
24
25
|
import { CachedPromiseFunc } from './matrix/utils/cached-promise.js'
|
|
25
26
|
import { engineMessageToWechaty } from './matrix/schema-mapper/message.js'
|
|
26
27
|
import { engineContactToWechaty } from './matrix/schema-mapper/contact.js'
|
|
@@ -758,6 +759,23 @@ class PuppetMatrix extends PUPPET.Puppet {
|
|
|
758
759
|
}
|
|
759
760
|
}
|
|
760
761
|
|
|
762
|
+
/**
|
|
763
|
+
* 解析h5链接
|
|
764
|
+
* @param messageId
|
|
765
|
+
*/
|
|
766
|
+
override async messageLocation (messageId: string) : Promise<PUPPET.payloads.Location> {
|
|
767
|
+
const rawPayload = await this.messageRawPayload(messageId)
|
|
768
|
+
const payload = await this.messageRawPayloadParser(rawPayload)
|
|
769
|
+
|
|
770
|
+
if (payload.type !== PUPPET.types.Message.Location) {
|
|
771
|
+
throw new Error('Can not get location from non location payload')
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// FIXME: thumb may not in appPayload.thumburl, but in appPayload.appAttachPayload
|
|
775
|
+
const locationPayload = await parseLocationMessagePayload(rawPayload.msg) as PUPPET.payloads.Location
|
|
776
|
+
return locationPayload
|
|
777
|
+
}
|
|
778
|
+
|
|
761
779
|
/****************************************************************************
|
|
762
780
|
* send message
|
|
763
781
|
***************************************************************************/
|
|
@@ -974,12 +992,12 @@ class PuppetMatrix extends PUPPET.Puppet {
|
|
|
974
992
|
}
|
|
975
993
|
}
|
|
976
994
|
|
|
977
|
-
// 创建群聊
|
|
995
|
+
// 创建群聊
|
|
978
996
|
override async roomCreate (
|
|
979
997
|
contactIdList : string[],
|
|
980
998
|
topic : string,
|
|
981
999
|
): Promise<string> {
|
|
982
|
-
return
|
|
1000
|
+
return this._client?.creatRoom(contactIdList, topic) || ''
|
|
983
1001
|
}
|
|
984
1002
|
|
|
985
1003
|
// 删除群聊 暂不支持
|
|
@@ -1000,7 +1018,7 @@ class PuppetMatrix extends PUPPET.Puppet {
|
|
|
1000
1018
|
return PUPPET.throwUnsupportedError(roomId)
|
|
1001
1019
|
}
|
|
1002
1020
|
|
|
1003
|
-
// 机器人退出群聊
|
|
1021
|
+
// 机器人退出群聊
|
|
1004
1022
|
override async roomQuit (roomId: string): Promise<void> {
|
|
1005
1023
|
return this._client?.roomQuit(roomId)
|
|
1006
1024
|
}
|
|
@@ -1209,7 +1227,7 @@ class PuppetMatrix extends PUPPET.Puppet {
|
|
|
1209
1227
|
if (fileBox.mediaType.startsWith('image/')) {
|
|
1210
1228
|
momentInfo.imageUrls.push(fileUrl)
|
|
1211
1229
|
} else if (fileType.includes('video/mp4') || fileType.includes('.mp4')) {
|
|
1212
|
-
momentInfo.
|
|
1230
|
+
momentInfo.videoUrl = fileUrl
|
|
1213
1231
|
}
|
|
1214
1232
|
}
|
|
1215
1233
|
break
|