アドベントカレンダー19日目
- はじめに -
ぼくはやりたくないですね。
334Rankerは深夜のツイッター早押し大会のことです。毎日午前の3時34分にBOTが"334"ツイートの時間を取得、集計し、ランキング形式で発表します。
他にも称号や階級制度等あるのですが今回の実装には関係がないので割愛、リンク張っておきます。
blog.ranker.page
- やること -
今回の実装では最低限の機能として、
・該当ツイート(メッセージ)が送信されたときにIDを取得し、GMTに変換したものを送信する、に
・Discord上で動作する
を加えた2つを満たした時点でゴールとしています。
- メッセージIDをGMTに変換 -
上の画像はDiscordの公式リファレンスから引っ張ってきたものです。はじめにこれを参考にしつつメッセージIDから現在時刻を取り出す方法を解説していきます。
1. 125928847299117063
↓ 2進数に変換
2. 0000001001110001000001100101101011000001000*
↓ 上位42ビットを10進数に変換
3. 41944705796
↓ 1420070400000を加える
4. 1462015105796
5. 2016/04/30 11:18:25;796
1. 最初の18桁の数字がメッセージIDになっています。これはDiscordのチャット右クリックして"IDをコピー"を選択するともらえるやつです。
2. DiscordはメッセージIDの生成方式にSnowflakeを採用しており、64ビットうち上位42ビットがタイムスタンプとなっています。そのため、IDを2進数に変換した後、下位22ビットを落とす必要があります。
3. タイプスタンプを10進数に変換したものです。
4. タイムスタンプはUNIX時間で記述されています。Discordサービス開始からUNIX時間のカウントアップが開始された1970年までの差分を足しています。たぶん。
5. 画像ではUTCに変換していますが、今回の実装では分までしか見ないので関係ありません。
つぎに1~5までのプロセスをC++で書きます。可能であれば後述する入出力の時に使う言語でコーディングしたほうが良いのですがぼくはPython無理なので。
ソースコード丸投げします。
13, 14行目と57行目以降は次の章でお話しします。
pybind11以外はすべて標準ライブラリです。pybindはpipでインストールするためライブラリをそのままC++でインクルード出来ません。showコマンドでpybindの場所を探してインクルードパスに追加する必要があります。
Ubuntu 18.04では、
でした。
- CPPファイルをPythonから呼び出す -
pybindを用いてC++をPythonのコードに組み込むことが出来ます、すごい。上記のCPPファイルをコンパイルすることでPythonからのimportが可能になります、すごい。
コンパイルはclangをインストールした上で、
を実行します。ここで警告が出ますが、スルーします(200IQ)。
.soファイルが生成されると、同階層のPYファイルにインポートしてC++で定義した関数を使用することが出来ます。
- 入出力 -
Discordのテキストチャンネルで該当ツイートを検知、ID取得を行い、結果を送信します。今回はpybindを使用するためDiscord.pyを使用しますがBOT入出力自体は他の言語でも動作します。ちょっと遊ぶだけなら環境構築が必要でないJSのがいいなと思いました。
例によってソース丸投げしますが、ほぼ写経。
4行目の空文字列にBOTのトークンを入れます。BOTの作り方はMusicBOT等と変わらないため割愛。
- 実行 -
実際にDiscord上で動かすとこんな感じになります。
56
0.0
373
→N時56分0.373秒
ほんとに最低限しか作っていないため無機質な感じですがそのうち表示の仕方やランキング機能も実装したいですね。
というか誰か作って。
- さいごに -
2000文字を超えてしまいました、単位が出ますね。ここまで読んでくださっている皆様ほんとうに大好きです。
- 参考 -
覚えているハンイで参考になったページ載せておきます、全然覚えていない。