6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-12-17

この記事は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)

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を使い、スプレッドシートに発言を溜める

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?