提交 4957489c 编写于 作者: 杉木树下's avatar 杉木树下 提交者: Huan (李卓桓)

add: Message.forward() forward message (#727)

* add: Message.forward(id) forward message

You can directly forward files and multimedia, but limit the file size to 25Mb or less, otherwise it will fail because the server policy.

* fix(forward): parameter support Room/Contact/roomId/ContactId

* fix(message): fix some attributes not exist in the WebWxApp structure

* fix(message): fix forward return Promise<boolean>

In addition, some notes are added.

* fix(message) remove suppot forward(id : string)

* fix(message): add a prompt for file size in forward()

* fix(message): add the code to check if rawObj  is undefined

* fix(message): fix msg content error of forward group message

fix: When forwarding a message within a group, the content is prefixed with @userId.

* add(message): Add the Forward Message Source Settings option

```
m.forward(Room.load(id), { user: '$USER', room: 'Room[$ROOM]', custom: 'forward from $ROOM$USER' })

// source message: 'test msg'
// from room: 'testRoom'
// from user: 'Bot'
// forward message: `forward from Room[testRoom]Bot:\ntest msg`
```

* fix(message): only MsgType is TEXT, add forward from info

* fix(bridge): fix only emoji can't forward

* changge(message): move forward()  from class Message to MediaMessage

* fix(message): fix the error of forward room video

In room msg, the content prefix sender:, need to be removed, otherwise the forwarded sender will display the source message sender, causing self () to determine the error

* fix(message): add '{' and '}'

* doc(message): Supplementary forward() of jsdoc comments

resolved #726

* fix(message): fix the comment for forward()
上级 908aab24
......@@ -42,7 +42,9 @@ export interface MsgRawObj {
MMActualSender: string, // getUserContact(message.MMActualSender,message.MMPeerUserName).isContact()
MMPeerUserName: string, // message.MsgType == CONF.MSGTYPE_TEXT && message.MMPeerUserName == 'newsapp'
ToUserName: string,
FromUserName: string,
MMActualContent: string, // Content has @id prefix added by wx
Content: string,
MMDigest: string,
MMDisplayTime: number, // Javascript timestamp of milliseconds
......@@ -132,6 +134,18 @@ export interface MsgRawObj {
* MsgType == CONF.MSGTYPE_VERIFYMSG
*/
RecommendInfo?: RecommendInfo,
/**
* Transpond Message
*/
MsgIdBeforeTranspond?: string, // oldMsg.MsgIdBeforeTranspond || oldMsg.MsgId,
isTranspond?: boolean,
MMSourceMsgId?: string,
sendByLocal?: boolean, // If transpond file, it must is false, not need to upload. And, can't to call createMessage(), it set to true
MMSendContent?: string,
MMIsChatRoom?: boolean,
}
export interface MsgObj {
......@@ -1098,6 +1112,92 @@ export class MediaMessage extends Message {
throw e
}
}
public forward(room: Room): Promise<boolean>
public forward(contact: Contact): Promise<boolean>
/**
* Forward the received message.
*
* The types of messages that can be forwarded are as follows:
*
* The return value of {@link Message#type} matches one of the following types:
* ```json
* MsgType {
* TEXT = 1,
* IMAGE = 3,
* VIDEO = 43,
* EMOTICON = 47,
* LOCATION = 48,
* APP = 49,
* MICROVIDEO = 62,
* }
* ```
*
* When the return value of {@link Message#type} is `MsgType.APP`, the return value of {@link Message#typeApp} matches one of the following types:
* ```json
* AppMsgType {
* TEXT = 1,
* IMG = 2,
* VIDEO = 4,
* ATTACH = 6,
* EMOJI = 8,
* }
* ```
* But, it should be noted that when forwarding ATTACH type message, if the file size is greater than 25Mb, the forwarding will fail.
* The reason is that the server limits the forwarding of files above 25Mb. You need to download the file and use `new MediaMessage (file)` to send the file.
*
* @param {(Room | Contact)} sendTo
* The recipient of the message, the room, or the contact
* @returns {Promise<boolean>}
* @memberof MediaMessage
*/
public forward(sendTo: Room|Contact): Promise<boolean> {
if (!this.rawObj) {
throw new Error('no rawObj!')
}
let m = Object.assign({}, this.rawObj)
const newMsg = <MsgRawObj>{}
const fileSizeLimit = 25 * 1024 * 1024
let id = ''
// if you know roomId or userId, you can use `Room.load(roomId)` or `Contact.load(userId)`
if (sendTo instanceof Room || sendTo instanceof Contact) {
id = sendTo.id
} else {
throw new Error('param must be Room or Contact!')
}
newMsg.ToUserName = id
newMsg.FromUserName = config.puppetInstance().userId || ''
newMsg.isTranspond = true
newMsg.MsgIdBeforeTranspond = m.MsgIdBeforeTranspond || m.MsgId
newMsg.MMSourceMsgId = m.MsgId
// In room msg, the content prefix sender:, need to be removed, otherwise the forwarded sender will display the source message sender, causing self () to determine the error
newMsg.Content = UtilLib.unescapeHtml(m.Content.replace(/^@\w+:<br\/>/, '')).replace(/^[\w\-]+:<br\/>/, '')
newMsg.MMIsChatRoom = sendTo instanceof Room ? true : false
// The following parameters need to be overridden after calling createMessage()
// If you want to forward the file, would like to skip the duplicate upload, sendByLocal must be false.
// But need to pay attention to file.size> 25Mb, due to the server policy restrictions, need to re-upload
if (m.FileSize >= fileSizeLimit) {
log.warn('Message', 'forward() file size >= 25Mb,the message may fail to be forwarded due to server policy restrictions.')
}
newMsg.sendByLocal = false
newMsg.MMActualSender = config.puppetInstance().userId || ''
if (m.MMSendContent) {
newMsg.MMSendContent = m.MMSendContent.replace(/^@\w+:\s/, '')
}
if (m.MMDigest) {
newMsg.MMDigest = m.MMDigest.replace(/^@\w+:/, '')
}
if (m.MMActualContent) {
newMsg.MMActualContent = UtilLib.stripHtml(m.MMActualContent.replace(/^@\w+:<br\/>/, '')).replace(/^[\w\-]+:<br\/>/, '')
}
m = Object.assign(m, newMsg)
return config.puppetInstance()
.forward(m, newMsg)
}
}
/*
......
......@@ -21,11 +21,10 @@ import { parseString } from 'xml2js'
/* tslint:disable:no-var-requires */
const retryPromise = require('retry-promise').default
import { log } from '../config'
import { log } from '../config'
import {
PuppetWeb,
} from './puppet-web'
import PuppetWeb from './puppet-web'
import { MsgRawObj } from '../message'
export interface MediaData {
ToUserName: string,
......@@ -424,6 +423,20 @@ export class Bridge {
})
}
public forward(baseData: MsgRawObj, patchData: MsgRawObj): Promise<boolean> {
if (!baseData.ToUserName) {
throw new Error('UserName not found')
}
if (!patchData.MMActualContent && !patchData.MMSendContent && !patchData.Content) {
throw new Error('cannot say nothing')
}
return this.proxyWechaty('forward', baseData, patchData)
.catch(e => {
log.error('PuppetWebBridge', 'forward() exception: %s', e.message)
throw e
})
}
/**
* Proxy Call to Wechaty in Bridge
*/
......
......@@ -29,6 +29,7 @@ import Contact from '../contact'
import {
Message,
MediaMessage,
MsgRawObj,
} from '../message'
import {
Puppet,
......@@ -522,6 +523,26 @@ export class PuppetWeb extends Puppet {
return ret
}
public async forward(baseData: MsgRawObj, patchData: MsgRawObj): Promise<boolean> {
log.silly('PuppetWeb', 'forward() destination: %s, content: %s)',
patchData.ToUserName,
patchData.MMActualContent,
)
let ret = false
try {
// log.info('PuppetWeb', `forward() baseData: ${JSON.stringify(baseData)}\n`)
// log.info('PuppetWeb', `forward() patchData: ${JSON.stringify(patchData)}\n`)
ret = await this.bridge.forward(baseData, patchData)
} catch (e) {
log.error('PuppetWeb', 'forward() exception: %s', e.message)
Raven.captureException(e)
throw e
}
return ret
}
public async send(message: Message | MediaMessage): Promise<boolean> {
const to = message.to()
const room = message.room()
......
......@@ -516,6 +516,31 @@
return true
}
function forward(baseData, patchData) {
var chatFactory = WechatyBro.glue.chatFactory
var confFactory = WechatyBro.glue.confFactory
if (!chatFactory || !confFactory) {
log('forward() chatFactory or confFactory not exist.')
return false
}
try {
var m = chatFactory.createMessage(baseData)
// Need to override the parametes after called createMessage()
m = Object.assign(m, patchData)
chatFactory.appendMessage(m)
chatFactory.sendMessage(m)
} catch (e) {
log('forward() exception: ' + e.message)
return false
}
return true
}
function send(ToUserName, Content) {
var chatFactory = WechatyBro.glue.chatFactory
var confFactory = WechatyBro.glue.confFactory
......@@ -917,6 +942,7 @@
, getPassticket: getPassticket
, getUploadMediaUrl: getUploadMediaUrl
, sendMedia: sendMedia
, forward: forward
// for Wechaty Contact Class
, contactFindAsync: contactFindAsync
......
......@@ -28,6 +28,7 @@ import Contact from './contact'
import {
Message,
MediaMessage,
MsgRawObj,
} from './message'
import Room from './room'
......@@ -54,6 +55,7 @@ export abstract class Puppet extends EventEmitter implements Sayable {
public abstract self(): Contact
public abstract send(message: Message | MediaMessage): Promise<boolean>
public abstract forward(baseData: MsgRawObj, patchData: MsgRawObj): Promise<boolean>
public abstract say(content: string): Promise<boolean>
public abstract reset(reason?: string): void
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册