app.js 6.39 KB
const TelegramBot = require('node-telegram-bot-api');

const config = require('./config');

// Create a bot that uses 'polling' to fetch new updates
const bot = new TelegramBot(config.telegram.token, { polling: true });

var request = require('request');

// Translation api url
const translate_api_url = 'https://openapi.naver.com/v1/papago/n2mt';

// Language detection api url
const languagedetect_api_url = 'https://openapi.naver.com/v1/papago/detectLangs'

// /echo [whatever]
bot.onText(/\/echo (.+)/, (msg, match) => {
  // 'msg' is the received Message from Telegram
  // 'match' is the result of executing the regexp above on the text content
  // of the message

  const chatId = msg.chat.id;
  const resp = match[1]; // the captured "whatever"

  // send back the matched "whatever" to the chat
  bot.sendMessage(chatId, resp);
});

/**
 * Translate given message and send it to the specified chatroom.
 *
 * @param {*} message Message to translate
 * @param {*} chatId  Id of the chatroom to send translated message to
 */
function translate(message, chatId) {
  // Language detection options
  var lang_detect_options = {
    url: languagedetect_api_url,
    form: { 'query': message },
    headers: {
      'X-Naver-Client-Id': config.papago.client_id,
      'X-Naver-Client-Secret': config.papago.client_secret
    }
  };

  // Papago language detection
  request.post(lang_detect_options, function (error, response, body) {
    console.log(response.statusCode);
    if (!error && response.statusCode == 200) {
      var detect_body = JSON.parse(response.body);
      var source = '';
      var target = '';
      var result = { type: 'text', text: '' };

      // Check if detection was successful
      console.log('Language detected: ' + detect_body.langCode);

      // Translate using papago
      // Target defaults to English for Korean source, or Korean for all other langs
      if (detect_body.langCode != 'unk') {
        source = detect_body.langCode;
        target = source == 'ko' ? 'en' : 'ko';

        // Papago translation options
        var translate_options = {
          url: translate_api_url,
          form: {
            'source': source, // Before translation
            'target': target, // After translation
            'text': message // Message to translate
          },
          headers: {
            'X-Naver-Client-Id': config.papago.client_id,
            'X-Naver-Client-Secret': config.papago.client_secret
          }
        };

        // Send translatation request
        request.post(translate_options, function (error, response, body) {
          // On success
          if (!error && response.statusCode == 200) {
            var objBody = JSON.parse(response.body);
            result.text = objBody.message.result.translatedText;

            // Send translated message
            console.log('Before: ' + message);
            console.log('After: ' + result.text);
            bot.sendMessage(chatId, result.text);
          }
        });
      }
      // Language not detected
      else {
        result.text = '언어를 감지할 수 없습니다.';
        bot.sendMessage(chatId, result.text);
      }
    }
  });
}

// [Any normal message which is not a command (not starting with '/')]
bot.onText(/^(?!\/)((.|\n)+)/, (msg, match) => {
  const chatId = msg.chat.id;
  const chatType = msg.chat.type;
  const received_msg = match[1];

  // Ignore if we are not on a private chat,
  // since direct translation is to be used only on private chats.
  if (chatType != 'private') {
    return;
  }

  translate(received_msg, chatId);
});

// /t(ranslate) [Whatever]
// Translate the 'whatever' and show the result in any kind of chatroom.
// Also, if the given '/t' message is a reply to another message,
// translate the reply target message as well.
bot.onText(/^\/(t|translate)($| ((.|\n)+))/, (msg, match) => {
  const chatId = msg.chat.id;
  const chatType = msg.chat.type;
  const received_msg = match[3];
  // Whether the given '/t' message is a reply to another message
  const isReply = msg.reply_to_message != undefined;
  // Whether a message has been given after '/t' command
  const msgExists = received_msg != undefined;

  // Translate the reply's target message
  if (isReply) {
    const replyMsg = msg.reply_to_message.text;
    translate(replyMsg, chatId);
  }

  // Translate the message after '/t' if exists
  if (msgExists) {
    translate(received_msg, chatId);
  }
});

// /l(anguage)
// Let user select the language he wants his message to translate to.
// When triggered, bot will send an inline keyboard message with a list
// of available langauges. For an example of an inline keyboard message,
// see https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating.
bot.onText(/^\/(l|anguage)/, (msg, match) => {
  const chatId = msg.chat.id;
  const msgId = msg.message_id;

  const inlineKeyboard = {
    inline_keyboard: [
      // Languages supported by papago language detection
      // One array per line
      [
        { text: '한국어', callback_data: 'ko' },
        { text: '영어', callback_data: 'en' },
        { text: '일본어', callback_data: 'ja' }
      ],
      [
        { text: '중국어 간체', callback_data: 'zh-cn' },
        { text: '중국어 번체', callback_data: 'zh-tw' }
      ],
      [
        { text: '힌디어', callback_data: 'hi' },
        { text: '스페인어', callback_data: 'es' },
        { text: '프랑스어', callback_data: 'fr' }
      ],
      [
        { text: '독일어', callback_data: 'de' },
        { text: '포루트갈어', callback_data: 'pt' },
        { text: '베트남어', callback_data: 'vi' }
      ],
      [
        { text: '인도네시아어', callback_data: 'id' },
        { text: '페르시아어', callback_data: 'fa' }
      ],
      [
        { text: '아랍어', callback_data: 'ar' },
        { text: '미얀마어', callback_data: 'mm' },
        { text: '태국어', callback_data: 'th' }
      ],
      [
        { text: '러시아어', callback_data: 'ru' },
        { text: '이탈리아어', callback_data: 'it' }
      ],
    ]
  }
  const options = {
    reply_to_message_id: msgId,
    reply_markup: inlineKeyboard
  }

  bot.sendMessage(chatId, '무슨 언어로 번역할까요? 선택은 기억됩니다.', options);
});

bot.on('callback_query', (query) => {
  const data = query.data;

  const options = {
    text: 'From now on, your messages will be translated into ' + data
  }

  bot.answerCallbackQuery(query.id, options);
});