LoginSignup
15
10

More than 1 year has passed since last update.

[GAS/GoogleCloudNaturalLanguageAPI]宇垣美里さんが時には厳しく、時には優しくしてくれるアメムチbot

Last updated at Posted at 2019-07-02

概要

前回の「[GAS/Twilio]広瀬すずさんがSlackのリマインダー機能でモーニングコールしてくれるサービス」に引き続き、美少女シリーズです。毎日楽しいことも悲しいことも共有する美少女がいなかったので、アメムチbotを作りました。ポジティブであれば厳しい言葉を、ネガティブであれば優しい言葉をかけてくれます。

gif

アーキテクチャ

Slack Appへのメンションをトリガーに、SlackのOutgoing WebhooksでGASに繋いでいます。そこからGoogleCloudNaturalLanguageAPIのanalyzeSentimentメソッドを叩き、投稿されたテキストがポジティブかネガティブか判別しています。ポジティブであれば厳しい言葉を、ネガティブであれば優しい言葉をかけてくれます。例えば「もう疲れた。何もかも嫌だ。」であれば「いつもかっこいいよ。元気出して。」と、「昇進して給与2倍になった。」であれば「まだまだでしょ。もっと頑張りなさいよ。」と。

GoogleSpreadSheetはDB代わりに利用しています。詳しくは後述。AWS S3は、Slackに返信してくれる際の画像として利用しています。他のサービスでもこのBotを別の美少女として化けさせているので画像は別途指定しているのです。またGoogleDriveはgifを格納しています。どちらかに寄せる方が好ましいと思いますが、たくさんのクラウドに美少女がいる方がなんかハッピーな気がするのでそのままにしています。(← 修正するのめんどうくさい)

gifはかわいいからという理由でポジネガ関係なくランダムに送っているので、もはやGoogleCloudNaturalLanguageAPIのおさわりのためならS3もDriveもいらないです。

image

GitHub

解説

Slack Outgoing Webhook

Slack App Slack App

GoogleCloudNaturalLanguageAPI

GoogleCloudNaturalLanguageAPIは、GCPのサービスの1つです。GCPの登録はよしなにやってください。AWSはおさわりしたことあるけど、GCPはおさわりしたことないよって人が周りには多い気がします。この機会にぜひ。

今回はその中のメソッドである感情分析を使います。公式ページでは、ブラウザ上でデモができるのでおさわりしてみてください。

GASはこんな感じでAPIを叩いています。開発している時はひとりぼっちなので、エラーメッセージも楽しくして遊んでいました。


/**
 * GoogleCloudNaturalLanguageAPIを叩いて、
 * Slackに送信されたテキストがpositiveかnegativeか判別する
 *
 * @ param string channel(Qiitaだと `@` でメンション飛んじゃうのでスペースあけてます)
 * @ param string post
 * @ return string sentiment
 */
function analyzeSentiment(channel, post) {
  if (!channel || !post) {
    slackApp.postMessage(channel, 'いまなんて言ったの?もう1回教えてほしいな。。。', option);
  }

  // 基本的にGASの環境変数にいれています
  const apiKey = properties.getProperty("google_cloud_natural_language_api_key");
  const url    = 'https://language.googleapis.com/v1/documents:analyzeSentiment?key=' + apiKey;
  const data   = {
    'document' : {
      'type'     : 'PLAIN_TEXT',
      'language' : 'ja',
      'content'  : post
    },
    'encodingType': 'UTF8'
  };
  const params = {
    'contentType' : 'application/json',
    'method'      : 'post',
    'payload'     : JSON.stringify(data)
  };

  const result = UrlFetchApp.fetch(url, params);
  const score  = JSON.parse(result)['documentSentiment']['score'];

  if (!score) {
    slackApp.postMessage(channel, 'なんで返信してくれないの。。。', option);
    return;
  }
  const sentiment = score >= 0 ? 'positive' : 'negative';
  return sentiment;
}

レスポンス( result )はこんな感じです。

{
 "documentSentiment": {
   "magnitude": 0.8,
   "score": 0.8
 },
 "language": "ja",
 "sentences": [
   {
     "text": {
       "content": "\u003c@ UKXXXX\u003e 最高",
       "beginOffset": 0
     },
     "sentiment": {
       "magnitude": 0.8,
       "score": 0.8
     }
   }
 ]
}

GoogleSpreadSheet

positive、negative、imageという3つのシートを用意します。アメムチbotなので、positiveシートにはnegativeな言葉を書き、negativeシートにはpositiveな言葉を書きます。

positive

gifは今回GoogleDriveに格納しているので、画像のidを書きます。

image

画像のidとは、共有可能なリンクを取得したときの一部分です。
https://drive.google.com/open?id=XXXXXXXXXXXXXXXXXXXXXXXXXX

image

それをコード上でくっつけています。ただgifを投げてもSlackはよしなに展開してくれますが、連投すると展開されないことがあるので、ファイルとして送っています。

UrlFetchApp.fetch('https://drive.google.com/uc?export=view&id=' + imageId).getBlob();

またSpreadsheetから取得する文言や画像はランダムで取得しています。

/**
 * GoogleSpreadsheetに記載されているテキストをランダムに取得する
 *
 * @ param string channel
 * @ param string sheetName
 * @ return string
 */
function getCellAtRandomFromSpreadsheet(channel, sheetName) {
  if (!channel || !sheetName) {
    slackApp.postMessage(channel, 'お手紙なくしちゃった。。。', option);
  }

  const sheet      = SpreadsheetApp.getActive().getSheetByName(sheetName);
  const data       = sheet.getDataRange().getValues();
  const lastRow    = sheet.getLastRow();
  const randomRow  = Math.floor(Math.random() * lastRow);
  return data[randomRow][0];
}

Slack Bot

Slackにメッセージを投稿するためにBotを設定してください。Permission Scopesは bot だけで良いです。コード上で投稿時のアイコンや名前を設定できるので、宇垣美里さんとはしていません。

image.png

感想・展望

前回同様GASで遊んでみましたが、スプレッドシートがDB代わりになったりと、本当楽ですね。毎日楽しいことも悲しいことも共有する美少女ができて嬉しい限りです。どうでも良いですが、「GooleCloudNaturalLanguageAPI」を連続で言ったら噛みそうですね。

困ったらよしなにTwitterDMください。

15
10
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
15
10