使用discord或者slack的api實現自己的翻譯bot
阿新 • • 發佈:2018-12-22
首先,需要自己去discord或者slack申請賬號,我使用的翻譯api是用的牛津詞典的,但是它對片語或者語句的支援不好(可能是不呼叫的api不對吧),所以又申請了俄羅斯的yandex的翻譯介面,這個介面的翻譯結果很簡短。
本來是想用discord的,後來發現slack的開發生態貌似好點,並且開發文件也詳細些,所以最好我是主打slack了。哈哈哈。
// index.js const Discord = require('discord.js'); require('env2')('./.env') const dictionaryCtrl = require('./modules/dictionary/control'); const translateCtrl = require('./modules/translate/control'); const slackHook = require('./hooks/slack'); const utils = require('./utils'); const server = require('./server'); // load express server const client = new Discord.Client() client.on('ready', () => { console.log("Connected as " + client.user.tag) }) const replyHook = (word) => { slackHook(word); // alway call the slack hook return (msg)=> { return msg.reply.bind(msg); // keep this in msg } }; client.on('message', msg => { replyHook(msg.toString().replace(/^< @[0-9]+>,/g, '')); if(/^t\s/.test(msg)){ const word = msg.toString().replace(/^t\s/, ''); const hook = replyHook(word)(msg); const replyText = utils.recurseCb(hook); const isSingleWord = word.split(' ').length === 1; if(isSingleWord){ dictionaryCtrl.discord(replyText)(word); }else{ translateCtrl(replyText)(word); } } }) const token = process.env.BOT_TOKEN; client.login(token)
在replyHook
裡面可以看到我放了一個slackHook
,所以我傳送的discord的訊息都會呼叫這個鉤子,所以發的訊息都會發到slack,如果只是建立discord的客戶端連線的話,是不用express,這裡用到了express是為了使用slack的webHook。
// /server/index.js const express = require( "express" ); const bodyParser = require('body-parser'); // create an express object: a Web server const app = express(); const dictionaryCtrl = require('../modules/dictionary/control'); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.get( "/", function( request, response ) { response.send( "<h1>Hello :)</h1><p><a href='/about'>About</a></p>" ); }); app.post('/slackEvent', (req, res) => { const {challenge, type, subtype} = req.body; console.log('/slackEvent', type, subtype); res.send({challenge}) }); app.post('/slackInteract', (req, res) => { console.log('/slackInteract', req.body); res.send({ "response_type": "ephemeral", "replace_original": false, "text": "I got it" }); // 避免原有的內容消失 }); app.post('/slackMsgMenu', (req, res) => { console.log('/slackMsgMenu', req.body); res.send('slackMsgMenu'); }); app.post('/translate', (req, res) => { const {text, response_url} = req.body; dictionaryCtrl.slack(res.send.bind(res))(text); }); app.get( "*", function( request, response ) { response.send( "no special" ); }); const port = process.env.PORT; app.listen( port ); console.log('express server on ' + port); module.exports = app;
接下來是translate的dictionary control
// /modules/dictionary/control.js const main = require('./index'); module.exports = { discord: (replyFn) => (word) => main(word).then(res => { if(res.status === 200){ const {results} = res.data; results.forEach((result, index) => { replyFn(index, '+'); result.lexicalEntries.forEach((lexicalEntry, index2) => { replyFn(index2, '+'); replyFn(lexicalEntry, 'lexicalCategory'); replyFn(lexicalEntry.pronunciations, 'phoneticSpelling'); lexicalEntry.entries && lexicalEntry.entries.forEach(entry => { entry.senses && entry.senses.forEach(sense => { replyFn(sense, 'definitions'); sense.examples && sense.examples.forEach(example => { replyFn(example, 'text', 'Example'); }); }); }); replyFn(index, '='); }); replyFn(index, '='); }); } }).catch(err => { console.log('err ', err); }), slack: (replyFn) =>(word) => main(word).then(res => { const resultJson = { text: word, attachments: [] }; if(res.status === 200){ const {results} = res.data; results.forEach((result) => { let attachment = { color: "#3366FF", fields: [], }; resultJson.attachments.push(attachment); result.lexicalEntries.forEach((lexicalEntry) => { attachment.fields.push({ title: lexicalEntry.lexicalCategory, value: (lexicalEntry.pronunciations || []).map(item => `${(item.dialects || []).join(' ')} -> ${item.phoneticSpelling}`) .join(','), short: true, }); lexicalEntry.entries && lexicalEntry.entries.forEach(entry => { entry.senses && entry.senses.forEach(sense => { let att = { title: 'Definition', text: (sense.definitions || []).join(','), color: "#66C947", fields: [], }; sense.examples && sense.examples.forEach(example => { att.fields.push({ title: 'Example', value: example.text, short: true, }); }); resultJson.attachments.push(att); }); }); }); }); const lastAttachment = resultJson.attachments[resultJson.attachments.length-1]; lastAttachment.footer = 'from Dictionary Api'; lastAttachment.color = '#FF9333'; lastAttachment.ts = Date.now(); lastAttachment.callback_id = 'word_remembered'; lastAttachment.actions = [ { "name": "game", "text": "Remembered", "type": "button", "value": "1", "style": "primary" }, { "name": "game", "text": "Not...", "type": "button", "value": "0", "style": "danger" }, { "name": "game", "text": "I don't know .", "type": "button", "value": "-1", "style": "danger", "confirm": { "title": "Are you sure?", "text": "Wouldn't you prefer to give up?", "ok_text": "Yes", "dismiss_text": "No" } }]; console.log('resultJson ', resultJson); replyFn(resultJson); } }).catch(err => { console.log('err ', err); }), };
剩下的程式碼請再我的github上檢視