LoginSignup
2
0

More than 5 years have passed since last update.

#本田とじゃんけん ができなくなって寂しいのでSlackAppで戯れた

Posted at

皆さんは #本田とじゃんけん というTwitterで結構流行ったものを覚えていますでしょうか.流石にこの記事が投稿された2019/4で忘れてしまったという方は少ないでしょうが,時がたつにつれ,記憶というものは風化され,誰からも思い出されなくなってしまいます.そんなの寂しいですよね.

そこで,Slackの中でも本田圭祐と無限にじゃんけんをできるようにすることでいつでもどこでもいつまでも本田とじゃんけんができるわけです.こうすれば,風化されずに済みますね!

Slackapp

SlackにはSlash Commandというものが存在します.例えば

/remind 04/21 11:00 am 書類郵送

などとメッセージボックスに打てば,指定日指定日時にリマインダを設定できます.

今回利用するのは,これを自作できるCustom Slash Commandsです.このインテグレーションを自グループのslackにログイン後,追加しましょう.

そのあと,設定を追加をクリックすることで,自作コマンドの追加が行えます.

適当に名前を設定しましょう.

画面を下に送るとURLとメソッドとラベルが付いたフォームがあるかと思います.要するに,どこかのサーバにPOSTやGETを送って,その結果をSlackに表示できるというわけです.

自分でサーバを借りてGETやPOSTを構築してもいいですがたかが本田とじゃんけんのためにサーバを借りるのはなんか癪です1

そこでGoogle Apps Scriptを利用して,サーバを借りたりせずにじゃんけんを作ってみましょう.

Google Apps Script

起動方法は何でもいいのですが,https://script.google.com/ に移動して新規スクリプトを作るのが一番早いでしょう.このScriptでは,SlackからのGETやPOSTを受けて,何かしらの処理を行うことができます.

GETを受けるにはfunction doGet(e)という関数を用います.POSTはdoPost(e)です.eにはSlackからの送信データがe.parameter以下のように入っています.

token=********
team_id=T0001
team_domain=example
channel_id=C2147483705
channel_name=test
user_id=U2147483697
user_name=Steve
command=/weather
text=94070
response_url=https://hooks.slack.com/commands/1234/5678

この場合はSteveがtestチャンネルで/weather 94070というコマンドを打ったということを意味しています.

ですので/janken チョキのようなデータを送られてくるものとして,本田にじゃんけんを行わせましょう.

スクリプトは以下です.


function doGet(e) {
  var text = e.parameter.text;
  var hand = 0;
  // 正規表現を用いて手がなんなのかをhandに保存しときます
  if((/(グー|こぶし|fist|グーパンチ|パンチ|facepunch)/g).test(text)) hand = 1;
  if((/(チョキ|ピース|v)/g).test(text)) hand = 2;
  if((/(パー|手|手のひら|hand|開いた手を挙げる|raised_hand_with_fingers_splayed)/g).test(text)) hand = 3;
  var restxt = "";
  var resurl = "";
  var win = 0.98 < Math.random();
  if(hand === 1){
    if(win){
      restxt = "ジャンケンポン!\n\nYOU WIN!\n\nやるやん\n\n明日俺にリベンジさせて\n\nでは,どうぞ";
      resurl = "https://チョキの画像.png";
    }else{
      restxt = "ジャンケンポン!\n\nYOU LOSE\n\n俺の勝ち!\n\n負けは次につながるチャンスです\nネバーギブアップ\n\nほな,いただきます";
      resurl = "https://パーの画像.png";
    }
  }
  if(hand === 2){
    if(win){
      restxt = "ジャンケンポン!\n\nYOU WIN!\n\nやるやん\n\n明日俺にリベンジさせて\n\nでは,どうぞ";
      resurl = "https://パーの画像.png";
    }else {
      restxt = "ジャンケンポン!\n\nYOU LOSE\n\n俺の勝ち!\n\nたかがジャンケン,そう思ってないですか\nそれやったら明日も\n俺が勝ちますよ\n\nほな,いただきます";
      resurl = "https://グーの画像.png";
    }
  }
  if(hand === 3){
    if(win){
      restxt = "ジャンケンポン!\n\nYOU WIN!\n\nやるやん\n\n明日俺にリベンジさせて\n\nでは,どうぞ";
      resurl = "https://グーの画像.png";
    }else{
      restxt = "ジャンケンポン!\n\nYOU LOSE\n\n俺の勝ち!\n\nなんで負けたか明日まで考えといてください\nそしたら何かが\n見えてくるはずです\n\nほな,いただきます";
      resurl = "https://チョキの画像.png";
    }
  }
  if(hand === 0)restxt = "お前ケイスケホンダやな?"
  var res = {
    "parse": "full",
    "response_type": "in_channel",
    "text": restxt,
    "attachments":[
      {
        "image_url": resurl
      }
    ]
  };

  return ContentService.createTextOutput(JSON.stringify(res)).setMimeType(ContentService.MimeType.JSON);
}

順にみていきましょう.

  if((/(グー|こぶし|fist|グーパンチ|パンチ|facepunch)/g).test(text)) hand = 1;
  if((/(チョキ|ピース|v)/g).test(text)) hand = 2;
  if((/(パー|手|手のひら|hand|開いた手を挙げる|raised_hand_with_fingers_splayed)/g).test(text)) hand = 3;

は正規表現にテキストがマッチするかをboolで返す/regexp/.test(text)の形式のtest関数を利用します.色々種類があるのは絵文字に対応するためです.(/janken :hand_splayed: と打っても反応してくれたら嬉しいじゃないですか)

  var win = 0.98 < Math.random();

本田の勝率はなんと怒涛の98%以上らしいです.0-1の乱数が0.98を超えていたらあなたの勝ちです.この数値を変えれば本田の強さが変えられます.ケイスケホンダの真髄がこの一行に込められています.

  if(hand === 1){
    if(win){
      restxt = "ジャンケンポン!\n\nYOU WIN!\n\nやるやん\n\n明日俺にリベンジさせて\n\nでは,どうぞ";
      resurl = "https://チョキの画像.png";
    }else{
      restxt = "ジャンケンポン!\n\nYOU LOSE\n\n俺の勝ち!\n\n負けは次につながるチャンスです\nネバーギブアップ\n\nほな,いただきます";
      resurl = "https://パーの画像.png";
    }
  }

// ...中略...

  if(hand === 0)restxt = "お前ケイスケホンダやな?"

予め本田の画像がどこかに上がっているとしてそのURLをresurl,ホンダの至言をrestxtに代入します.

ついでに該当しなかった場合の処理を書いています.

  var res = {
    "parse": "full", // URL エスケープする
    "response_type": "in_channel", // 送られた場所に返してあげよう
    "text": restxt,
    "attachments":[ // 追加でつける装飾
      {
        "image_url": resurl // 画像のURL
      }
    ]
  };

レスポンスをJSONで書きます.Attachmentには色々種類があり,ここで実際にAttachmentがどのように投稿に影響するかを試すことができます.

  return ContentService.createTextOutput(JSON.stringify(res)).setMimeType(ContentService.MimeType.JSON);

JSONを送り返します.

これだけで非常に簡単にチャットボットまがいのものが作れます.

Slackに登録しよう

これでできたGASからWebアプリケーションとして公開して,slackのcustom slash commandsに登録します.URLを得るためには,GASのスクリプトエディタのツールバーより,「公開」→「ウェブ アプリケーションとして導入...」とします.この際,アプリケーションにアクセスできるユーザのところは「全員(匿名ユーザーを含む)」を選択します.その後,URLが生成されます.そのURLを先ほどのSlackのCustom Slash Commandsに入力します.

GETなのでメソッドは「取得する」にします.

そして保存しましょう.

これで完成です!

実際に呼び出してみた画像はこちらです.

Image from Gyazo

いい感じです.なかなか勝てないところにケイスケホンダを感じます.

おわりに

遊び心もボットの醍醐味ですよね.そこそこ羽休め的コーディングになるかと思います.


  1. なんかすごく失礼なこと言ってますね.すみません... 

2
0
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
2
0