JavaScript
GoogleAppsScript
spreadsheet
翻訳
bot

【Google Apps Script】その18 日本語で話しかけると3ヶ国語で返すChatwork botを作る

この記事はGoogle Apps Scriptを実例交えて基礎からざっくり学ぶ Advent Calendar 2017 18日目の記事です。

本アドベントカレンダーは@rt_pの個人プロジェクトですが、筆者はAteam Brides Inc. Advent Calendar 2017にも参加しています。そちらでも出張版記事を書いているので、覗いていただけると嬉しいです。

はじめに

今回はChatworkのWebhookを使い、マイチャットで発言すると3ヶ国語に翻訳して返すchatwork bot(のようなもの)を作ってみましょう。

完成品はマイチャットに日本語を発言すると、英語・中国語(簡体字)・ヒンディー語の3ヶ国語を返します(世界のネイティブスピーカー人口上位3位の言語です)。

trans.png

GASファイルの作成

今回はスプレッドシートを使う必要がないのでGoogle Apps Scriptファイルを直接作成しましょう。
Googleドライブの新規作成→その他から作成できます。
見つからなければ+アプリを追加から探してください。

以下コードを入力しましょう。
承認が必要ですメッセージが出た際の対処法が分からない場合は
アドベントカレンダー1日目のHello, world!記事をご参照ください。

translation.gs
// doPostのデバッグ用
function dummyPost() {
  var webhookEvent = {
    'webhook_event': {
      'body': 'こんにちは'
    }
  };
  var e = {
    'postData': {
      'contents': JSON.stringify(webhookEvent)
    }
  };
  var res = doPost(e);
  var postData = JSON.parse(res);
  Logger.log(postData);
}

function doPost(e) {
  var json = JSON.parse(e.postData.contents);
  var body = json.webhook_event.body;
  if (body.indexOf('[info][title]') === 0) { // エコー(無限ループ)状態を防ぐ為、[info][title]から始まっているメッセージは自動投稿と判定し処理しない
    return;
  }
  var trans = translation(body);
  return postToChatworkMessage(body, trans);
}

// 3ヶ国語に翻訳して返す
function translation(body) {
  var en    = LanguageApp.translate(body, 'ja', 'en'); // 英語
  var china = LanguageApp.translate(body, 'ja', 'zh-CN'); // 中国語(簡体字)
  var hindi = LanguageApp.translate(body, 'ja', 'hi'); // ヒンディー語
  return "英語:" + en + "\r\n" + "中国語(簡体字):" + china + "\r\n" + 'ヒンディー語:' + hindi;
}

// chatworkにメッセージ投稿
function postToChatworkMessage(subject, body) {
  var roomId = 'YOUR_ROOM_ID'; // ここに投稿したい部屋のIDを入力
  var token = 'YOUR_TOKEN'; // ここにトークンを入力
  var body  = '[info][title]' + subject + '[/title]' + body + '[/info]';
  var payload = {
    'body': body
  }
  var headers = {
    'X-ChatWorkToken': token
  }
  var options = {
    'method' : 'POST',
    'payload' : payload,
    'headers' : headers
  }
  var url = 'https://api.chatwork.com/v2/rooms/' + roomId + '/messages';
  return UrlFetchApp.fetch(url, options);
}

新出はこれぐらいでしょうか。

translate(text, sourceLanguage, targetLanguage)

https://developers.google.com/apps-script/reference/language/language-app#translatetext-sourcelanguage-targetlanguage

Google翻訳を使い、あらゆる言語に翻訳が可能です。
超便利!

  var roomId = 'YOUR_ROOM_ID'; // ここに投稿したい部屋のIDを入力
  var token = 'YOUR_TOKEN'; // ここにトークンを入力

roomIdは部屋のIDです。URLの#!ridXXXXXとなっている、rid以降の数値です。
Chatworkトークンの取得方法は16日目の記事を参照してください。

Webhookのパラメータがどう渡ってくるかは公式ドキュメントを参照。
http://developer.chatwork.com/ja/webhook.html

dummyPost()を実行するとdoPost()のテストができます。
実行して以下のようなメッセージがマイチャットに届いたらdoPost()は正常に動くでしょう。

test.png

APIの公開

公開→ウェブアプリケーションとして導入から、
アプリケーションにアクセスできるユーザー:全員(匿名ユーザーを含む)に設定して公開します。

なお、設定後は当然ながらこのAPIにアクセスに誰でもPOSTを投げられるようになります。誤ってURLを漏洩でもしない限りよっぽど大丈夫かと思いますが、自己責任でお願い致します。

Webhookの設定

ChatworkのAPI設定リンクからWebhook設定ページに飛び、以下の通り新規作成します。

webhook.png

設定が問題なく済むと、マイチャットに投げた発言が3ヶ国語に翻訳されて即座に返ってきます。

trans.png

中国語とヒンディー語が正しいか分かりませんが:sweat_smile:英語が合っているようなので恐らく大丈夫でしょう!

余談ですが、

  if (body.indexOf('[info][title]') === 0) { // エコー(無限ループ)状態を防ぐ為、[info][title]から始まっているメッセージは自動投稿と判定し処理しない
    return;
  }

これめちゃくちゃ重要です…!
もしこの処理が無いとどうなるでしょう?

正解は…
マイチャットで自分が発言する

Webhookが発火し、翻訳が投稿される

翻訳の投稿にWebhookが発火し、翻訳発言が更に翻訳されて投稿される

という無限ループが発生して、以下のような状態になります。

infinity.png

要注意です。

おわりに

今回はWebhookとGASでbotを作成しましたが、凝ったbotを作るにはHubot等が一般的かと思います。
このアドベントカレンダーでは触れませんが、興味のある方は見てみてください。

明日

【Google Apps Script】その19 Chatwork Webhookを使い、スプレッドシートに発言を溜める
となります。
今回使ったWebhookをスプレッドシートとも連携させてみます。

前の記事
【Google Apps Script】その17 デイリーでの目標進捗をChatworkの部屋名に自動反映する
次の記事
【Google Apps Script】その19 Chatwork Webhookを使い、スプレッドシートに発言を溜める