RustでSlackにカスタム絵文字を登録するツールを作成してみた
Slackのカスタム絵文字
以下みたいなアクションで使う絵文字
このカスタム絵文字の登録をSlackから実施出来るようにRustでAPIを実装してみました。
このソースはgithubにもあげています。 github.com
概要
以下のようなAPIになっています。
・スラッシュコマンドで画像のURLと登録絵文字名をリクエストとして受け取る
・画像のURLからアップロードする画像を取得する
・Slackの絵文字アップロード画面をPOSTで叩く
Slackではカスタム絵文字登録を行うAPIは公開されていませんでした。
なので、Slackの画像アップロード画面を直接APIから叩くような仕様になっています。
api_tokenの取得方法について
Slackの画像アップロード画面を叩く際にapi_tokenが認証に必要になります。
api_tokenは以下から取得できます。
https://[自身のワークスペース].slack.com/customize/emoji
ページを開いたらF12を押してデベロッパーツールを開きます。
その状態でページを再読み込みし、上部のSourcesを選択します。
そこで表示されるHTML内のapi_token
を使用しています。
実装
リクエストの分解
// 空白で文字列を分割する 絵文字画像URL 登録絵文字名 let v: Vec<&str> = params.get("text").unwrap().split(' ').collect(); let emoji_url: &str = v.get(0).unwrap(); let emoji_name: &str = v.get(1).unwrap();
スラッシュコマンドで送られてきたリクエストからparamsを取得、
そのparamsを空白で分割し、1つ目を画像URL、2つ目を絵文字登録名として取り出します。
画像の取得
// URLから画像を取得してローカルに保存する fn download_image(url: &str) { // 画像データの取得 let image = reqwest::get(url).unwrap(); let file = File::create(FILE_NAME).unwrap(); let mut br = BufWriter::new(&file); for byte in image.bytes() { br.write(&[byte.unwrap()]).unwrap(); } br.flush().unwrap(); // 保存した画像に読み取り権限を付与 let mut perms = file.metadata() .expect("メタデータの取得に失敗しました。") .permissions(); perms.set_readonly(true); file.set_permissions(perms) .expect("権限付与に失敗しました。"); }
リクエストから取得した画像URLで画像を取得し、
それを一時的にローカルに保存しています。
後でSlackにアップロードするために読み取り権限を付与しています。
絵文字アップロード
// 絵文字のアップロードを行う fn upload_emoji(url: &str, form: Form, emoji_name: &str, api_token: &str) -> impl Future<Item = String, Error = Error> { // カスタム絵文字アップロードリクエスト let mut res = Client::new() .post(url) .query(&[ ("mode", "data"), ("name", emoji_name), ("token", api_token)]) .multipart(form) .send() .unwrap(); match res.text() { Err(e) => fut_ok(String::from(format!("アップロード失敗:{:?}", e))), Ok(result) => { let v: Value = serde_json::from_str(result.as_str()).unwrap(); // エラー判定 match v["ok"].as_bool() { Some(true) => fut_ok(String::from(format!("アップロード完了::{}:", emoji_name))), Some(false) => fut_ok(String::from(format!("アップロード失敗:{}", v["error"]))), None => fut_ok(String::from(format!("アップロード失敗:{}", v["error"]))), } } } }
Slackへの絵文字のアップロードを行なっています。
crateはrequwest
を使用しています。
ここで設定しているemoji_name
はスラッシュコマンドから、
api_token
は上で記載した取得方法で取得したものを使用しています。
Slackからのレスポンスも判定しており、
正常に登録できた場合は応答として「アップロード完了:[登録した絵文字]」が、
登録に失敗した場合は「アップロード失敗:[エラーメッセージ]」が返却されるようになっています。
使用イメージ
addemoji
というスラッシュコマンドを使用しています。
cat_icon
という名前で登録してみます。
登録が完了すると以下のように表示されます。
これでスマホのSlackアプリからも登録出来るようになりました。