提交 2cd28d87 编写于 作者: Huan (李卓桓)'s avatar Huan (李卓桓)

message with attachment file caused by Message.ext() BREAKING CHANGE (fix #1175)

上级 2250ce12
...@@ -85,17 +85,30 @@ bot ...@@ -85,17 +85,30 @@ bot
) )
if (/^(ding|ping|bing|code)$/i.test(m.text()) && !m.self()) { if (/^(ding|ping|bing|code)$/i.test(m.text()) && !m.self()) {
m.say('dong') /**
* 1. reply 'dong'
*/
log.info('Bot', 'REPLY: dong') log.info('Bot', 'REPLY: dong')
m.say('dong')
const joinWechaty = `Join Wechaty Developers' Community\n\n` + const joinWechaty = `Join Wechaty Developers' Community\n\n` +
`Wechaty is used in many ChatBot projects by hundreds of developers.\n\n` + `Wechaty is used in many ChatBot projects by hundreds of developers.\n\n` +
`If you want to talk with other developers, just scan the following QR Code in WeChat with secret code: wechaty,\n\n` + `If you want to talk with other developers, just scan the following QR Code in WeChat with secret code: wechaty,\n\n` +
`you can join our Wechaty Developers' Home at once` `you can join our Wechaty Developers' Home at once`
await m.say(joinWechaty) await m.say(joinWechaty)
await m.say(new bot.Message(BOT_QR_CODE_IMAGE_FILE))
/**
* 2. reply qrcode image
*/
const imageMessage = new bot.Message(BOT_QR_CODE_IMAGE_FILE)
log.info('Bot', 'REPLY: %s', imageMessage)
await m.say(imageMessage)
/**
* 3. reply 'scan now!'
*/
await m.say('Scan now, because other Wechaty developers want to talk with you too!\n\n(secret code: wechaty)') await m.say('Scan now, because other Wechaty developers want to talk with you too!\n\n(secret code: wechaty)')
log.info('Bot', 'REPLY: Image')
} }
} catch (e) { } catch (e) {
log.error('Bot', 'on(message) exception: %s' , e) log.error('Bot', 'on(message) exception: %s' , e)
......
...@@ -336,14 +336,14 @@ export class PuppetPuppeteer extends Puppet { ...@@ -336,14 +336,14 @@ export class PuppetPuppeteer extends Puppet {
let mediatype: MediaType let mediatype: MediaType
switch (ext) { switch (ext) {
case 'bmp': case '.bmp':
case 'jpeg': case '.jpeg':
case 'jpg': case '.jpg':
case 'png': case '.png':
case 'gif': case '.gif':
mediatype = MediaType.IMAGE mediatype = MediaType.IMAGE
break break
case 'mp4': case '.mp4':
mediatype = MediaType.VIDEO mediatype = MediaType.VIDEO
break break
default: default:
...@@ -507,7 +507,7 @@ export class PuppetPuppeteer extends Puppet { ...@@ -507,7 +507,7 @@ export class PuppetPuppeteer extends Puppet {
}, },
}, },
} }
let mediaId let mediaId: string
try { try {
mediaId = <string>await new Promise((resolve, reject) => { mediaId = <string>await new Promise((resolve, reject) => {
try { try {
...@@ -537,7 +537,7 @@ export class PuppetPuppeteer extends Puppet { ...@@ -537,7 +537,7 @@ export class PuppetPuppeteer extends Puppet {
log.error('PuppetPuppeteer', 'uploadMedia(): upload fail') log.error('PuppetPuppeteer', 'uploadMedia(): upload fail')
throw new Error('PuppetPuppeteer.uploadMedia(): upload fail') throw new Error('PuppetPuppeteer.uploadMedia(): upload fail')
} }
return Object.assign(mediaData, { MediaId: mediaId as string }) return Object.assign(mediaData, { MediaId: mediaId })
} }
public async sendMedia(message: PuppeteerMessage): Promise<boolean> { public async sendMedia(message: PuppeteerMessage): Promise<boolean> {
...@@ -556,8 +556,9 @@ export class PuppetPuppeteer extends Puppet { ...@@ -556,8 +556,9 @@ export class PuppetPuppeteer extends Puppet {
} }
let mediaData: MediaData let mediaData: MediaData
const rawObj = message.rawObj as MsgRawObj const rawObj = message.rawObj || {} as MsgRawObj
if (!rawObj.MediaId) {
if (!rawObj || !rawObj.MediaId) {
try { try {
mediaData = await this.uploadMedia(message, destinationId) mediaData = await this.uploadMedia(message, destinationId)
message.rawObj = Object.assign(rawObj, mediaData) message.rawObj = Object.assign(rawObj, mediaData)
...@@ -1090,14 +1091,14 @@ export class PuppetPuppeteer extends Puppet { ...@@ -1090,14 +1091,14 @@ export class PuppetPuppeteer extends Puppet {
public extToType(ext: string): MsgType { public extToType(ext: string): MsgType {
switch (ext) { switch (ext) {
case 'bmp': case '.bmp':
case 'jpeg': case '.jpeg':
case 'jpg': case '.jpg':
case 'png': case '.png':
return MsgType.IMAGE return MsgType.IMAGE
case 'gif': case '.gif':
return MsgType.EMOTICON return MsgType.EMOTICON
case 'mp4': case '.mp4':
return MsgType.VIDEO return MsgType.VIDEO
default: default:
return MsgType.APP return MsgType.APP
......
...@@ -81,9 +81,9 @@ export class PuppeteerMessage extends Message { ...@@ -81,9 +81,9 @@ export class PuppeteerMessage extends Message {
log.silly('PuppeteerMessage', 'constructor()') log.silly('PuppeteerMessage', 'constructor()')
this.obj = {} as MsgObj this.obj = {} as MsgObj
// this.rawObj = {} as MsgRawObj
if (!fileOrObj) { if (!fileOrObj) {
this.rawObj = <MsgRawObj>{}
return return
} }
...@@ -137,39 +137,39 @@ export class PuppeteerMessage extends Message { ...@@ -137,39 +137,39 @@ export class PuppeteerMessage extends Message {
* @private * @private
*/ */
public toString() { public toString() {
return `PuppeteerMessage<${Misc.plainText(this.obj.content)}>` return `PuppeteerMessage<${Misc.plainText(this.obj && this.obj.content)}>`
} }
/** // /**
* @private // * @private
*/ // */
public toStringDigest() { // public toStringDigest() {
const text = Misc.digestEmoji(this.obj.digest) // const text = Misc.digestEmoji(this.obj.digest)
return '{' + this.typeEx() + '}' + text // return '{' + this.typeEx() + '}' + text
} // }
/** // /**
* @private // * @private
*/ // */
public getSenderString() { // public getSenderString() {
const from = PuppeteerContact.load(this.obj.from) // const from = PuppeteerContact.load(this.obj.from)
from.puppet = this.puppet // from.puppet = this.puppet
const fromName = from.name() // const fromName = from.name()
const roomTopic = this.obj.room // const roomTopic = this.obj.room
? (':' + PuppeteerRoom.load(this.obj.room).topic()) // ? (':' + PuppeteerRoom.load(this.obj.room).topic())
: '' // : ''
return `<${fromName}${roomTopic}>` // return `<${fromName}${roomTopic}>`
} // }
/** // /**
* @private // * @private
*/ // */
public getContentString() { // public getContentString() {
let content = Misc.plainText(this.obj.content) // let content = Misc.plainText(this.obj.content)
if (content.length > 20) { content = content.substring(0, 17) + '...' } // if (content.length > 20) { content = content.substring(0, 17) + '...' }
return '{' + this.type() + '}' + content // return '{' + this.type() + '}' + content
} // }
/** /**
* @private * @private
...@@ -347,7 +347,43 @@ export class PuppeteerMessage extends Message { ...@@ -347,7 +347,43 @@ export class PuppeteerMessage extends Message {
*/ */
public type(): MsgType { public type(): MsgType {
log.silly('PuppeteerMessage', 'type() = %s', MsgType[this.obj.type]) log.silly('PuppeteerMessage', 'type() = %s', MsgType[this.obj.type])
return this.obj.type || MsgType.TEXT
/**
* 1. A message created with rawObj
*/
if (this.obj.type) {
return this.obj.type
}
/**
* 2. A message created with TEXT
*/
const ext = this.extFromFile()
if (!ext) {
return MsgType.TEXT
}
/**
* 3. A message created with local file
*/
switch (ext.toLowerCase()) {
case '.bmp':
case '.jpg':
case '.jpeg':
case '.png':
return MsgType.IMAGE
case '.gif':
return MsgType.EMOTICON
case '.mp4':
return MsgType.VIDEO
case '.mp3':
return MsgType.VOICE
}
throw new Error('unknown type: ' + ext)
} }
/** /**
...@@ -378,12 +414,12 @@ export class PuppeteerMessage extends Message { ...@@ -378,12 +414,12 @@ export class PuppeteerMessage extends Message {
return this.rawObj.AppMsgType return this.rawObj.AppMsgType
} }
/** // /**
* Get the typeEx from the message. // * Get the typeEx from the message.
* // *
* @returns {MsgType} // * @returns {MsgType}
*/ // */
public typeEx() { return MsgType[this.obj.type] } // public typeEx() { return MsgType[this.obj.type] }
/** /**
* Check if a message is sent by self. * Check if a message is sent by self.
...@@ -608,38 +644,38 @@ export class PuppeteerMessage extends Message { ...@@ -608,38 +644,38 @@ export class PuppeteerMessage extends Message {
return this return this
} }
/** // /**
* @private // * @private
*/ // */
public get(prop: string): string { // public get(prop: string): string {
log.warn('PuppeteerMessage', 'DEPRECATED get() at %s', new Error('stack').stack) // log.warn('PuppeteerMessage', 'DEPRECATED get() at %s', new Error('stack').stack)
if (!prop || !(prop in this.obj)) { // if (!prop || !(prop in this.obj)) {
const s = '[' + Object.keys(this.obj).join(',') + ']' // const s = '[' + Object.keys(this.obj).join(',') + ']'
throw new Error(`Message.get(${prop}) must be in: ${s}`) // throw new Error(`Message.get(${prop}) must be in: ${s}`)
} // }
return this.obj[prop] // return this.obj[prop]
} // }
/** // /**
* @private // * @private
*/ // */
public set(prop: string, value: string): this { // public set(prop: string, value: string): this {
log.warn('PuppeteerMessage', 'DEPRECATED set() at %s', new Error('stack').stack) // log.warn('PuppeteerMessage', 'DEPRECATED set() at %s', new Error('stack').stack)
if (typeof value !== 'string') { // if (typeof value !== 'string') {
throw new Error('value must be string, we got: ' + typeof value) // throw new Error('value must be string, we got: ' + typeof value)
} // }
this.obj[prop] = value // this.obj[prop] = value
return this // return this
} // }
/** /**
* @private * @private
*/ */
public dump() { public dump() {
console.error('======= dump message =======') console.error('======= dump message =======')
Object.keys(this.obj).forEach(k => console.error(`${k}: ${this.obj[k]}`)) Object.keys(this.obj!).forEach(k => console.error(`${k}: ${this.obj![k]}`))
} }
/** /**
...@@ -648,7 +684,7 @@ export class PuppeteerMessage extends Message { ...@@ -648,7 +684,7 @@ export class PuppeteerMessage extends Message {
public dumpRaw() { public dumpRaw() {
console.error('======= dump raw message =======') console.error('======= dump raw message =======')
if (!this.rawObj) { if (!this.rawObj) {
throw new Error('no this.obj') throw new Error('no this.rawObj')
} }
Object.keys(this.rawObj).forEach(k => console.error(`${k}: ${this.rawObj && this.rawObj[k]}`)) Object.keys(this.rawObj).forEach(k => console.error(`${k}: ${this.rawObj && this.rawObj[k]}`))
} }
...@@ -729,13 +765,16 @@ export class PuppeteerMessage extends Message { ...@@ -729,13 +765,16 @@ export class PuppeteerMessage extends Message {
* } * }
* }) * })
*/ */
public filename(): string { public filename(): string | null {
log.verbose('PuppeteerMessage', 'filename()')
if (this.parsedPath) { if (this.parsedPath) {
// https://nodejs.org/api/path.html#path_path_parse_path // https://nodejs.org/api/path.html#path_path_parse_path
const filename = path.join( const filename = path.join(
this.parsedPath!.dir || '', this.parsedPath!.dir || '',
this.parsedPath!.base || '', this.parsedPath!.base || '',
) )
log.silly('PuppeteerMessage', 'filename()=%s, build from parsedPath', filename)
return filename return filename
} }
...@@ -747,10 +786,12 @@ export class PuppeteerMessage extends Message { ...@@ -747,10 +786,12 @@ export class PuppeteerMessage extends Message {
const ext = this.rawObj.MMAppMsgFileExt || this.ext() const ext = this.rawObj.MMAppMsgFileExt || this.ext()
filename += '.' + ext filename += '.' + ext
} }
log.silly('PuppeteerMessage', 'filename()=%s, build from rawObj', filename)
return filename return filename
} }
throw new Error('no rawObj') return null
} }
...@@ -766,38 +807,75 @@ export class PuppeteerMessage extends Message { ...@@ -766,38 +807,75 @@ export class PuppeteerMessage extends Message {
* }) * })
*/ */
public ext(): string { public ext(): string {
if (this.parsedPath && this.parsedPath.ext) const fileExt = this.extFromFile()
if (fileExt) {
return fileExt
}
const typeExt = this.extFromType()
if (typeExt) {
return typeExt
}
throw new Error('unknown ext()')
}
private extFromFile(): string | null {
if (this.parsedPath && this.parsedPath.ext) {
return this.parsedPath.ext return this.parsedPath.ext
}
return null
}
switch (this.type()) { private extFromType(): string {
let ext: string
const type = this.type()
switch (type) {
case MsgType.EMOTICON: case MsgType.EMOTICON:
return '.gif' ext = '.gif'
break
case MsgType.IMAGE: case MsgType.IMAGE:
return '.jpg' ext = '.jpg'
break
case MsgType.VIDEO: case MsgType.VIDEO:
case MsgType.MICROVIDEO: case MsgType.MICROVIDEO:
return '.mp4' ext = '.mp4'
break
case MsgType.VOICE: case MsgType.VOICE:
return '.mp3' ext = '.mp3'
break
case MsgType.APP: case MsgType.APP:
switch (this.typeApp()) { switch (this.typeApp()) {
case AppMsgType.URL: case AppMsgType.URL:
return '.url' // XXX ext = '.url' // XXX
break
default:
ext = '.' + this.type()
break
} }
break break
case MsgType.TEXT: case MsgType.TEXT:
if (this.typeSub() === MsgType.LOCATION) { if (this.typeSub() === MsgType.LOCATION) {
return '.jpg' ext = '.jpg'
} }
ext = '.' + this.type()
break break
}
default:
log.silly('PuppeteerMessage', `ext() got unknown type: ${this.type()}`) log.silly('PuppeteerMessage', `ext() got unknown type: ${this.type()}`)
return String('.' + this.type()) ext = '.' + this.type()
}
return ext
} }
/** /**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册