26
15

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

Slackの絵文字を全て取得する

Last updated at Posted at 2019-06-17

Slackで使われている絵文字を標準カスタム全て欲しかったのですが、割と面倒だったので記録しておきます

やりたいこと

Slackのリアクション名から絵文字をHTMLで描画したい

例えば:grin:から😁を描画したい

方法として以下どっちかかなと思って調べました。

  1. 画像として描画する
  2. 絵文字として描画する

後述する理由により、カスタムアイコンは画像として描画する。組み込みアイコンは絵文字として描画する

という方法になりました。

画像として描画する

Slackにはemoji.listというAPIが用意されているので、これを使えばカスタムアイコンの一覧がURLとして取得できます。

参考 emoji.list method | Slack

使い方は簡単で、以下のようにHTTPリクエストを投げるだけ

curl https://slack.com/api/emoji.list?token=<自分のアクセストークン>&pretty=1

こんな感じのJSONが返ってくるので、この情報から画像を取得すればOK

{
    "ok": true,
    "emoji": {
        "name1": "https:\/\/emoji.slack-edge.com\/<teamID>\/name1\/f3d58f2bb0.png",
        "name2": "https:\/\/emoji.slack-edge.com\/<teamID>\/name2\/4650f4c0e0.png"
    }
}

ただし、カスタムアイコンしか取得できないので、最初から組み込まれているアイコンは習得できません。
組み込みで入っている絵文字も含めて欲しかったのですが、このAPIではとれないということで断念。

Slackでは組み込みの画像をどうしてるか

ちなみに、Slackはどうしてるんだろう?と思って確認してみたらアイコン一つ分のhtmlは以下のようになってました。

<span role="img" aria-label="woman lifting weights emoji"
 class="emoji-outer emoji-sizer"
 data-codepoints="1f3cb-fe0f-200d-2640-fe0f"
 style="background-image: url(&quot;https://cfr.slack-edge.com/c00d19/img/emoji_2017_12_06/sheet_apple_64_indexed_256.png&quot;); background-position: 19.6078% 90.1961%; background-size: 5200% 5200%;"
>:woman-lifting-weights:</span>

https://cfr.slack-edge.com/c00d19/img/emoji_2017_12_06/sheet_apple_64_indexed_256.pngには全アイコンが敷き詰められた画像が置いてあって、それを座標で切り取って使ってるみたいです。
何度もダウンロードしないための処理っぽいですね

この方法を再現するのは流石に面倒ということで断念。

絵文字として描画する

Slack組み込みの絵文字はUnicode 11.0準拠の絵文字を採用しているということで、絵文字コードとして描画すれば画像なしでも問題なさそうです。

絵文字とエモティコンの使用 – Slack
Slack では、標準の絵文字コードを採用しています。絵文字コードを入力すると、絵文字を手早くメッセージに追加できます!

ということなので、絵文字の名前と絵文字コードを対応付けできればOKですね
で、その対応表どこかにないかなと探しました。

How can I get the FULL list of slack emoji through API? - Stack Overflow で紹介されていた以下のリポジトリを利用させていただきました。

iamcal/emoji-data: Easy to parse data and spritesheets for emoji

このリポジトリには絵文字データと画像の情報をまとめくれています。
画像も用意されているので、自分で用意すれば画像としての描画もできましたが今回は遠慮しておきました。

使い方

npm install emoji-datasource

とするとインストールできるので、Node.jsで読み込んで使えます。

const emojiData = require('emoji-datasource')

emojiDataは以下のような絵文字データの配列になってます。

[
    {
        "name": "WHITE UP POINTING INDEX",
        "unified": "261D-FE0F",
        "non_qualified": "261D",
        "docomo": null,
        "au": "E4F6"
        ...
    },
    {
        "name": "WHITE UP POINTING INDEX",
        "unified": "261D-FE0F",
        "non_qualified": "261D",
        "docomo": null,
        "au": "E4F6"        
        ...
    }
    ...
]

情報はいっぱいあったんですが、short_nameが絵文字名、unifiedが文字コードとなってそうだったのでその2つだけ使いました。

とりあえず描画

😁の情報を取ってみると

{ name: 'GRINNING FACE WITH SMILING EYES',
  unified: '1F601',
  non_qualified: null,
  docomo: 'E753',
  au: 'EB80',
  softbank: 'E404',
  google: 'FE333',
  image: '1f601.png',
  sheet_x: 30,
  sheet_y: 25,
  short_name: 'grin',
  short_names: [ 'grin' ],
  text: null,
  texts: null,
  category: 'Smileys & People',
  sort_order: 2,
  added_in: '6.0',
  has_img_apple: true,
  has_img_google: true,
  has_img_twitter: true,
  has_img_facebook: true,
  has_img_messenger: true }

こんな情報がとれたので、unifiedに文字参照を付けて

test.html
<div>&#x1F601;:grin</div>

grin

やったぜ😁

マルチバイト文字で問題発生

grinの場合は1F601というシンプルなものだったのでよかったんですが、例えば🙋‍♀️だと以下のように長いです。

{
    "short_name": "woman-raising-hand",
    "unified": "1F64B-200D-2640-FE0F"
}

同じ方法で行くと

alt

残念

まあ複数バイトで表しているので当然か

ということで、-を文字参照に置換しました

//@ts-check
const emojiData = require('emoji-datasource')

const dic = {}
emojiData.forEach(emoji => {
    dic[emoji.short_name] = `&#x${emoji.unified};`.replace(/-/g, ";&#x")
})
console.log(JSON.stringify(dic, null, 2))

こんな感じにすると、キーが絵文字名でバリューが文字コードの対応表が作成できます。
ひとまずこれで十分かなと

Gistに上げといたので、必要となったらどうぞ

確認

確認用にhtmlとして吐き出してみましたが大丈夫そうでした。

...
<div>&#x1F641;:slightly_frowning_face</div>
<div>&#x1F642;:slightly_smiling_face</div>
<div>&#x1F643;:upside_down_face</div>
<div>&#x1F644;:face_with_rolling_eyes</div>
<div>&#x1F645;&#x200D;&#x2640;&#xFE0F;:woman-gesturing-no</div>
<div>&#x1F645;&#x200D;&#x2642;&#xFE0F;:man-gesturing-no</div>
<div>&#x1F645;:no_good</div>
<div>&#x1F646;&#x200D;&#x2640;&#xFE0F;:woman-gesturing-ok</div>
<div>&#x1F646;&#x200D;&#x2642;&#xFE0F;:man-gesturing-ok</div>
<div>&#x1F646;:ok_woman</div>
<div>&#x1F647;&#x200D;&#x2640;&#xFE0F;:woman-bowing</div>
<div>&#x1F647;&#x200D;&#x2642;&#xFE0F;:man-bowing</div>
<div>&#x1F647;:bow</div>
<div>&#x1F648;:see_no_evil</div>
<div>&#x1F649;:hear_no_evil</div>
<div>&#x1F64A;:speak_no_evil</div>
<div>&#x1F64B;&#x200D;&#x2640;&#xFE0F;:woman-raising-hand</div>
<div>&#x1F64B;&#x200D;&#x2642;&#xFE0F;:man-raising-hand</div>
<div>&#x1F64B;:raising_hand</div>
<div>&#x1F64C;:raised_hands</div>
...

alt

備考

スペース注意

文字の間にスペースがあると別々の文字という風に判定されます。

<div>&#x1F64B;&#x200D;&#x2642;&#xFE0F;:man-raising-hand</div>
<div>&#x1F64B; &#x200D; &#x2642; &#xFE0F; :man-raising-hand</div>

alt

ラインとかで見るやつ

アイコン似すぎ問題

alt

変換に漏れがあるのかと思ったら単純にアイコンが似すぎてて草

26
15
1

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?