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

この記事は[Google Apps Scriptを実例交えて基礎からざっくり学ぶ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/gas_beginner)　18日目の記事です。

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

# はじめに

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

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

![trans.png](https://qiita-image-store.s3.amazonaws.com/0/199678/89daff19-0e2d-39c4-58f8-c53ce297c17d.png)

# GASファイルの作成

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

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

```javascript: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翻訳を使い、あらゆる言語に翻訳が可能です。
超便利！

```javascript
  var roomId = 'YOUR_ROOM_ID'; // ここに投稿したい部屋のIDを入力
  var token = 'YOUR_TOKEN'; // ここにトークンを入力
```
roomIdは部屋のIDです。URLの#!ridXXXXXとなっている、rid以降の数値です。
Chatworkトークンの取得方法は[16日目の記事](https://qiita.com/rf_p/items/3e20e4114a1182deb7bc)を参照してください。

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

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

![test.png](https://qiita-image-store.s3.amazonaws.com/0/199678/539f1e3b-42ec-316a-5ee3-c8e294af0785.png)

# APIの公開

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

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

# Webhookの設定

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

![webhook.png](https://qiita-image-store.s3.amazonaws.com/0/199678/e3f1f796-c8f0-9fcc-a0cc-c208cec455ae.png)

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

![trans.png](https://qiita-image-store.s3.amazonaws.com/0/199678/89daff19-0e2d-39c4-58f8-c53ce297c17d.png)

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

余談ですが、

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

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

正解は…
マイチャットで自分が発言する
↓
Webhookが発火し、翻訳が投稿される
↓
翻訳の投稿にWebhookが発火し、翻訳発言が更に翻訳されて投稿される
↓
…

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

![infinity.png](https://qiita-image-store.s3.amazonaws.com/0/199678/5287ca28-0e5c-798a-a2f0-a11c2158a094.png)

要注意です。

# おわりに

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

# 明日

[【Google Apps Script】その19　Chatwork Webhookを使い、スプレッドシートに発言を溜める](https://qiita.com/rf_p/items/897d93f7beca83cd5902)
となります。
今回使ったWebhookをスプレッドシートとも連携させてみます。

前の記事
[【Google Apps Script】その17　デイリーでの目標進捗をChatworkの部屋名に自動反映する](https://qiita.com/rf_p/items/828c9f8147131b57e570)
次の記事
[【Google Apps Script】その19　Chatwork Webhookを使い、スプレッドシートに発言を溜める](https://qiita.com/rf_p/items/897d93f7beca83cd5902)