wechaty-qnamaker
Version:
QnAMaker.ai Plugin for Wechaty
136 lines (102 loc) • 4.12 kB
text/typescript
import {
Wechaty,
WechatyPlugin,
log,
Message,
} from 'wechaty'
import {
matchers,
} from 'wechaty-plugin-contrib'
import { asker } from './asker'
import { normalizeConfig } from './normalize-config'
import { mentionMatcher } from './mention-matcher'
import { QnAMakerOptions } from './qnamaker'
interface WechatyQnAMakerConfigMatcher {
contact? : matchers.ContactMatcherOptions,
room? : matchers.RoomMatcherOptions,
mention? : boolean,
skipMessage? : matchers.MessageMatcherOptions,
}
export type WechatyQnAMakerConfig = WechatyQnAMakerConfigMatcher & Partial<QnAMakerOptions>
function WechatyQnAMaker (config: WechatyQnAMakerConfig): WechatyPlugin {
log.verbose('WechatyQnAMaker', 'WechatyQnAMaker(%s)', JSON.stringify(config))
const normalizedConfig = normalizeConfig(config)
const ask = asker(normalizedConfig)
const matchContact = typeof config.contact === 'undefined'
? () => true
: matchers.contactMatcher(config.contact)
const matchRoom = typeof config.room === 'undefined'
? () => true
: matchers.roomMatcher(config.room)
const matchSkipMessage = typeof config.skipMessage === 'undefined'
? () => false // default not skip any messages
: matchers.messageMatcher(config.skipMessage)
const matchMention = (typeof config.mention === 'undefined')
? mentionMatcher(true) // default: true
: mentionMatcher(config.mention)
const matchLanguage = (typeof config.language === 'undefined')
? () => true // match all language by default
: matchers.languageMatcher(config.language)
const isPluginMessage = async (message: Message): Promise<boolean> => {
if (message.self()) { return false }
if (message.type() !== Message.Type.Text) { return false }
const mentionList = await message.mentionList()
if (mentionList.length > 0) {
if (!await message.mentionSelf()) { return false }
}
return true
}
const isConfigMessage = async (message: Message): Promise<boolean> => {
const from = message.from()
const room = message.room()
if (await matchSkipMessage(message)) { return false }
if (room) {
if (!await matchRoom(room)) { return false }
if (!await matchMention(message)) { return false }
/**
* Mention others but not include the bot
*/
const mentionList = await message.mentionList()
const mentionSelf = await message.mentionSelf()
if (mentionList.length > 0 && !mentionSelf) { return false }
} else {
if (from && !await matchContact(from)) { return false }
}
const text = await message.mentionText()
if (!matchLanguage(text)) { return false }
return true
}
/**
* Connect with Wechaty
*/
return function WechatyQnAMakerPlugin (wechaty: Wechaty) {
log.verbose('WechatyQnAMaker', 'WechatyQnAMakerPlugin(%s)', wechaty)
wechaty.on('message', async message => {
log.verbose('WechatyQnAMaker', 'WechatyQnAMakerPlugin() wechaty.on(message) %s', message)
if (!await isPluginMessage(message)) {
log.silly('WechatyQnAMaker', 'WechatyQnAMakerPlugin() wechaty.on(message) message not match this plugin, skipped.')
return
}
if (!await isConfigMessage(message)) {
log.silly('WechatyQnAMaker', 'WechatyQnAMakerPlugin() wechaty.on(message) message not match config, skipped.')
return
}
const text = await message.mentionText()
if (!text) { return }
const answers = await ask(text)
if (answers.length <= 0) { return }
const answer = answers[0].answer
if (!answer) {
throw new Error('no answer?')
}
const from = message.from()
const room = message.room()
if (from && room && await message.mentionSelf()) {
await room.say(answer, from)
} else {
await message.say(answer)
}
})
}
}
export { WechatyQnAMaker }