Slackで$…$や$$…$$を数式にするSlash Command
どうもぴざきゃっとです。
今回は,以下の記事で紹介したクラスSlackの機能の1つである数式入力の話をします。
概要
/formula
に続いて$…$や$$…$$で数式を囲んだメッセージを入力すると、その部分が数式画像で置き換えられたメッセージが届きます。
以前は$$で囲まずに数式だけを書く、という仕様だったので、一応それにも対応しています。
数式をSlackで書けるようにするbotは既に存在していて,実際参考にしているんですが,このように$...$や$$...$$を含む文章に対応しているものはないんじゃないですかね。
実装
入力テキスト→数式画像入りメッセージ
このbotはGASで動かす関係でGAS特有の関数があったりしてNode.js等に転用しにくいものが多いですが、この部分に関してはNode.jsでも動くと思います。ただしTypeScriptなので適宜コンパイルしてください。
流れとしては、
- 正規表現でメッセージを数式部分を取得
- 各数式とそれに先行するテキストをattachment化
という感じです。
正規表現は/([^]*?)((\$\$?)[^]+?\3)/g
で,これを用いるとabc$def$ghi$$jkl$$mno
からabc$def$
とghi$$jkl$$
を抽出できます。
各マッチに対して,数式画像のattachmentを生成します。プレーンテキストから数式画像を生成するのにGoogle Charts APIを使います。リンク先見るとわかるんですがこのAPIはdeprecatedで,いつ使えなくなるかわからないんですが,代案が見つからなかったので当面はこれを使います。クエリパラメータにencodeURIComponentした文字列を書いてあげるとそれが画像へのURLになります。
このURLをattachmentのimage_urlに指定するだけで,Slackに画像付きメッセージを投稿することができます。なので,URLから画像をfetchするような処理は不要です。
また,attachmentのpretextには数式の前の文字列(abc$def$
のabc
の部分)を指定します。
全てのマッチを処理した後はabc$def$ghi$$jkl$$mno
のmno
が残るので,mno
をpretextとしimage_urlを持たないattachmentを最後に追加します。なお最後のattachmentはスマホから見るとtextやimage_urlがないことによる謎の点が出るので,colorを#ffffffにすると見栄えが良いです。
数式画像入りメッセージ→レスポンスJSON
この部分はGAS特有です。
リクエストはPOSTでやってくるので,応答するためのdoPost(e)という関数を作ります。やってくるリクエストは/formula
だけではなく、他のSlash CommandsやEvent APIなども来るので,こんな感じで処理しています。
どのコマンドのリクエストなのかがcommand
というパラメータに入っているので,コマンドの文字列に対応する関数をslackCommands
というオブジェクトに格納しておき,slackCommands['command']
みたいな感じで呼び出すようにしています。関数の実行結果を受け取ったら,JSON文字列に変換してレスポンスを返します。
ちなみにGASWebEvent
とSlackCommandParams
というinterfaceを用意しているので,コードを書くときに補完が効いて快適です。
使い心地
理系クラスなので当然数式を書きたいわけですが,TeXに慣れていなくてよくミスった数式が表示されてしまい,なんども投稿し直すことが多いです。プレビュー機能があると良さそうですね。ephemeral
レスポンスとボタンで作れそうです。