はじめに
- この記事は Mastodon Advent Calendar 2017 - Qiita の20日目の記事です。
summoners-riftodon.jp を建てました
LoL(League of Legends)をプレイする人たちが交流するマストドン、 https://summoners-riftodon.jp/ を yota くんという人と一緒に建てました。
LoLの話題で交流したり、集まってプレメイドでもぐったりするのに利用されています。
Mastodon に絵文字を追加する
https://summoners-riftodon.jp/ には、チャンピオンの絵文字などがいくつか追加されています。
今のMastodonであればCusotm emojiを使える
Mastodon v2.0.0 から Custom emoji の機能が追加されました。
Release v2.0.0 · tootsuite/mastodon · GitHub
Features:
Custom emoji (#4988, #5243, #5258, #5002)
Admins may upload 50KB PNG images and assign them shortcodes. These images act as custom emojis that can be embedded inline in statuses using those shortcodes, like :example:. The emojis display correctly between different instances, but users can only use their local emojis. However, it is simple enough to make a local copy of a desired emoji.
簡単に日本語すると
絵文字拡張 管理者は50KBのPNGをアップロードして、ショートコードを記述します。
:example:
のようにショートコードを記述すると、それがタイムライン上で絵文字として表示されます。この絵文字は異なるインスタンスでも他アシク動作しますが、tootできるのは自分の登録しているマストドンにある絵文字のみです。絵文字を使いたい場合は、自分のマストドンに登録してください。
summoners-riftodon を作ったときの Mastodon は v1.2 だった
しかし、 https://summoners-riftodon.jp/ インスタンスを作った時のMastodonはv1.2で絵文字の機能がないため、コードを修正して絵文字を追加しました。
Mastodonの絵文字の仕組み
Mastodonの絵文字ですが、server-client間では基本的にunicodeでやり取りしています。v1.2 時代では、Mastodonで使える絵文字は unicode に存在する絵文字のみでした。例えば 🙇 という絵文字をMastodonに投稿しようとした場合、
- 🙇 (絵文字)をそのまま投稿する
:bow:
(ショートコード)を投稿する
の2つの方法があります。仮に、:bow: と投稿された場合、投稿ボタンが押された時に JavaScript 側で :bow:
を 🙇 に変換してサーバーサイドにpostしています。おそらくサーバーサイドでは 🙇 をそのままDBに格納していると思われます。
tootを表示する際には、 🙇 を <image>
タグに置き換えて表示しています。これにより、絵文字が見られない環境でも絵文字を表示できるようにしているわけです。
summoners-riftodon での絵文字の仕組み
summoners-riftodonではunicodeの絵文字以外にチャンピオンの絵文字を利用できるようになっています。
このコードは以下の部分で実装されています。
mastodon/emoji.jsx at summoners-riftodon · summoners-riftodon/mastodon · GitHub
挙動としてはこうです
- :lux: とtootする
- そのまま :lux: という文字列の状態でpostされてDBに入る
- 表示時に、JSで :lux: という部分を
<image>
タグに置き換えて表示
標準の絵文字と違って unicode に置き換えたりはしません。
具体的にどう実装されているのか
まず、文字列を <image>
タグに正規表現で置き換える関数を実装します。正規表現はよく考えないとバグの元になるので気をつけます。json
は 絵文字名: 画像URL
のマップです。
const originalToImage = str => str.replace(/:([a-zA-Z0-9_]+):/g, (emoji, emojiName) => { var jsonKeys = Object.keys(json); if (!jsonKeys.includes(emojiName)) { return emoji; } return `<img draggable="false" class="emojione" alt="${emoji}" src="${json[emojiName]}" />`; });
続いて、上記関数を使って実際に置き換えるようにします。以下の様に書き換えます。
- const toImage = str => shortnameToImage(unicodeToImage(str)); + const toImage = str => originalToImage(shortnameToImage(unicodeToImage(str)));
shortnameToImage(unicodeToImage(str));
これは、unicodeの絵文字を <image>
タグに置き換える実装です。ここに originalToImage
をかませます。
チャンピオンの画像についてはRiot公式のcdn(画像とか素材を置いているサーバー)があるのでそこのURLを利用します。これで絵文字が表示できるようになるわけです。意外と簡単です。
この実装の問題点
この実装の問題点や、Custom emoji と比べて劣っている点が大きく3つあります。
絵文字名がサジェストされたりしないので入力ミスしたら終わる
例えば、 :Aatrox:
と入力するところを :Atrox:
と入力してしまったり、:aatrox:
と入力されてしまうと絵文字になりません。しかし、toot時にこのような入力ミスには気づきません。 Custom emoji はこのあたりしっかりサジェストされるようになっているでしょうから、Custom emojiの方が優れていると思います。Emoji picker(UIで絵文字を選ぶやつ)を使えないのもマイナスポイントですね。
他のインスタンスで絵文字が見られない
当然ですが他のインスタンスでは :lux: のように文字で表示されてしまいます。スマホアプリなんかで見たときもそうですね。残念。
ヴァイが 🇻🇮になってしまう事件
これは v2.0.0 の Custom Emoji でも同じ事かとおもいますが、絵文字名が被っていると登録できません。
LoLには Vi というチャンピオンがいます。そこで summoners-riftodon で :vi:
と入力すると、🇻🇮 が表示されてしまいます。🇻🇮はイギリスヴァージン諸島の旗らしく、 Virgin Island 略して :vi: のようです。先程述べたように、Mastodonは絵文字をunicodeでやり取りしていますので、 :vi:
という文字列は 🇻🇮 というunicodeでやり取りされてしまいます。なので正規表現の :vi: には引っかからないようです。これは :chanpion_vi: などで置き換える必要がありますが、Emoji picker が存在しないので、初心者はしばしばヴァージン諸島の旗を表示させてしまいます。
おわりに
実は絵文字はプロフィール名とかにも使えるので、自分の得意なチャンピオンを名前の最後に書くといった、summoners-riftodon 独特な絵文字の使われ方をしています。非常に面白いです。
リーグオブレジェンドをやってる方はぜひ https://summoners-riftodon.jp に登録しましょう。*1
*1:昔はkatsudionさんとかいたけど最近は見ないなぁ...