8
0

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 3 years have passed since last update.

デカい(絵)文字を投稿するSlackアプリを作ってみた

Last updated at Posted at 2020-12-17

はじめに

この記事はHamee Advent Calendar 2020の18日目の記事です。

概要

スラッシュコマンドでチームメンバーへの溢れる感謝や賛辞を伝えることができます。

awesome.gif

スラッシュコマンドが入力されると、GoogleAppsScriptにデプロイ済みのAPIにPOSTリクエストが送られたのち、処理結果がSlackに投稿されます。

事前準備

透過色だけの絵文字を用意して、ワークスペースのカスタム絵文字にblankとして登録しておきます。
こちらのサイトを利用させていただきました。
https://zk-phi.github.io/MEGAMOJI/

本記事ではGASのデプロイやスラッシュコマンドの導入については省略します。以下の記事を参考にさせていただきました。
GASで作るSlack Slash Commands入門

GASのコード

POSTパラメータのtextフィールドに入力内容が含まれているので取り出します。
(/big awesome :parrot:と入力した場合awesome :parrot:)

入力メッセージを事前に定義した「アルファベット→デカ文字」のマッピング配列に基づいて
指定された絵文字に変換しています。
(マッピングの定義を書くのが一番大変でした)


// アルファベットのみ対応、小文字は自動で大文字に変換
// 長すぎると邪魔なので最大長を設ける
const MESSAGE_MAX_LENGTH = 7;
const BLANK_EMOJI = ':blank:';
const MARK_EXIST = '1';
const MARK_NONE  = '0';

function doPost(e) {
  let message = e.parameter.text.split(' ')[0];
  let emoji = e.parameter.text.split(' ')[1];
  let response = {};
  
  try {
    response = makeBigMoji(message, emoji);
  } catch(err) {
    response = {
      'response_type': 'ephemeral',
      'text': err.message
    };
  }
  
  Logger.log(response);

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

function makeBigMoji(message, emoji) {
  if (message.match(/[^A-Za-z]/)) {
    throw new Error('アルファベットのみで入力してください。');
  }
  if (message.length > MESSAGE_MAX_LENGTH) {
    throw new Error(MESSAGE_MAX_LENGTH + '文字以内で入力してください。');
  }
  
  let message_capital = message.toUpperCase();
  let characters = message_capital.split('');
  let mojis = ['', '', '', '', ''];
  for (let character of characters) {
    let moji_before = MOJI[character];
    for (let index in moji_before) {
      mojis[index] += moji_before[index].replace(/0/gi, BLANK_EMOJI + ' ').replace(/1/gi, emoji + ' ') + BLANK_EMOJI + ' ';
    }
  }
  
  return {
    'response_type': 'in_channel',
    'text': mojis.join("\n")
  };
}
マッピング配列
const MOJI = {
  'A': [
    '0110',
    '1001',
    '1111',
    '1001',
    '1001',
  ],
  'B': [
    '1110',
    '1001',
    '1110',
    '1001',
    '1110',
  ],
  'C': [
    '0111',
    '1000',
    '1000',
    '1000',
    '0111',
  ],
  'D': [
    '1110',
    '1001',
    '1001',
    '1001',
    '1110',
  ],
  'E': [
    '1111',
    '1000',
    '1111',
    '1000',
    '1111',
  ],
  'F': [
    '1111',
    '1000',
    '1111',
    '1000',
    '1000',
  ],
  'G': [
    '0111',
    '1000',
    '1011',
    '1001',
    '0111',
  ],
  'H': [
    '1001',
    '1001',
    '1111',
    '1001',
    '1001',
  ],
  'I': [
    '111',
    '010',
    '010',
    '010',
    '111',
  ],
  'J': [
    '0111',
    '0010',
    '0010',
    '1010',
    '0100',
  ],
  'K': [
    '1001',
    '1010',
    '1100',
    '1010',
    '1001',
  ],
  'L': [
    '1000',
    '1000',
    '1000',
    '1000',
    '1111',
  ],
  'M': [
    '10001',
    '11011',
    '10101',
    '10001',
    '10001',
  ],
  'N': [
    '10001',
    '11001',
    '10101',
    '10011',
    '10001',
  ],
  'O': [
    '01110',
    '10001',
    '10001',
    '10001',
    '01110',
  ],
  'P': [
    '1110',
    '1001',
    '1110',
    '1000',
    '1000',
  ],
  'Q': [
    '01110',
    '10001',
    '10101',
    '10011',
    '01110',
  ],
  'R': [
    '1110',
    '1001',
    '1110',
    '1001',
    '1001',
  ],
  'S': [
    '0111',
    '1000',
    '0110',
    '0001',
    '1110',
  ],
  'T': [
    '11111',
    '00100',
    '00100',
    '00100',
    '00100',
  ],
  'U': [
    '10001',
    '10001',
    '10001',
    '10001',
    '01110',
  ],
  'V': [
    '10001',
    '10001',
    '01010',
    '01010',
    '00100',
  ],
  'W': [
    '10101',
    '10101',
    '10101',
    '10101',
    '01010',
  ],
  'X': [
    '10001',
    '01010',
    '00100',
    '01010',
    '10001',
  ],
  'Y': [
    '10001',
    '01010',
    '00100',
    '00100',
    '00100',
  ],
  'Z': [
    '11111',
    '00010',
    '00100',
    '01000',
    '11111',
  ],
};

response_fieldパラメータにin_channelを指定するとコマンドの呼び出しと実行結果がチャンネルのメンバー全員に見える形で投稿されます。
visible.png

一方、'response_type': 'ephemeral'を指定するとコマンドを実行した本人にしか見えない形でメッセージが投稿されるため、入力エラーの通知に使っています。
invisible.png

なお、コマンドの呼び出し自体 (/big good :parrot:など) を非表示にすることはできないようです(違ってたらこっそり教えて下さい)。
また、リクエストの認証面倒なのでしていませんが、APIを一般公開などする際には対応したほうが良いと思います。

おわりに

リクエスト・レスポンスパラメータの仕様さえ分かってしまえば意外と簡単にSlackのスラッシュコマンドの実装ができました。今回はネタの実装でしたが、うまく使えば色々便利ツールが出来そうな気がします。

参考

GASで作るSlack Slash Commands入門
Enabling interactivity with Slash Commands

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?