ヘッダー

自作Discord Botで絵文字を大きな画像に変換する

カスタム絵文字は楽しいけど元絵の密度が高いと潰れて見えなくなってしまう。かといってプラグインで絵を投げるのは自分しか対応しない…。そんな悩める初心者サーバー管理者の私が、絵文字に反応して画像を返してくれるBotを作成・運用してみました。
これ絶対もう誰か作ってるはずなんだけど、腰を入れて探すよりは作ったほうが早いし融通も効くので自作しました。

Before

こんな感じでサーバーに絵文字を登録して入力しても・・・

画像1

before_入力

送信される絵文字は小さい。

before_絵文字

この例のキノコは見やすい部類だからいいですが、もっと密度のある画像になるとこの大きさでは何がなんだかわかりません。せっかく頑張って編集した素材が潰れてしまうのは悲しい…。

After

自作Bot導入後。
絵文字を入力すると・・・?

after_入力

元メッセージのかわりにBotが大きな画像を投げてくれます!

after_画像

元メッセージを直接書き換えたかったけどdiscord.pyの仕様上無理でした。
この例では絵文字と画像を同じファイルにしていますが、実際にはそれぞれ別の画像ファイルを使えます(実運用では絵文字側はわかりやすくサムネに文字を重ねた画像にしています)。

また、元の絵文字を残してBotがレスポンスを返してくれるのも面白いと思い、エイリアスの記述によって返信モードで動くようにしました。

Bot作成(&運用)解説

参考記事

この記事とdiscord.pyのリファレンスだけです。

コード

基本構造は参考記事のままです。
トークンは適当な文字列に変えてあります。

import os
import re
import discord

# BOTのアクセストークン
TOKEN = '123456789.abcdefghijklmnopqrstuvwxyz.ABCDEFGHIJKLMNOPQRSTUV'
# 画像ファイルを格納しているディレクトリのパス
FILE_DIR = "image/"
# 画像ファイルの拡張子
FILE_SUFFIX = ".png"
# オリジナルユーザー名の前につける文字
USER_PREFIX = ""
# オリジナルユーザー名の後につける文字
USER_SUFFIX = "さん から"


# クライアントを生成
client = discord.Client()

async def send_response(message, file_name, user_description):
   # 絵文字名と同名の画像ファイル名を作成
   image_path = FILE_DIR + file_name + FILE_SUFFIX

   # 画像ファイルが存在しない場合、戻る
   if not os.path.isfile(image_path):
       await message.channel.send(content=image_path + " is not found")
       return

   # 画像ファイルを取得
   image_file = discord.File(image_path)
   # メッセージ+画像を送信
   await message.channel.send(content=user_description, file=image_file)

# 起動時のイベント
@client.event
async def on_ready():
   # 起動表示兼リビジョン確認
   print('rev1.11 start')

# メッセージ送信時のイベント
@client.event
async def on_message(message):
   # print(message.content)

   # 送信者がBOTの時は何もせずに終了
   if message.author.bot:
       return

   # 絵文字を投稿した場合、コンテンツは"<:絵文字名:任意数列>"となる。
   # 正規表現で先頭が<:__任意文字列:>で始まる文字列をマッチして絵文字名を判別

   # 絵文字英エイリアスが___で始まる場合、返信モード。
   emoji_id = re.match(r'<:___(.+):.+>', message.content)
   if emoji_id:
       file_name = emoji_id.group(1)

       # 返信モードの時はメッセージは設定しない
       user_description = None

       # BOTによるメッセージ送信
       await send_response(message, file_name, user_description)

       return

   # 絵文字英エイリアスが__で始まる場合、変換モード。
   emoji_id = re.match(r'<:__(.+):.+>', message.content)
   if emoji_id:
       file_name = emoji_id.group(1)

       # オリジナルユーザー名からメッセージ文字列を作成
       user_description = USER_PREFIX + message.author.name + USER_SUFFIX

       # BOTによるメッセージ送信
       await send_response(message, file_name, user_description)
       # オリジナルメッセージを削除
       await message.delete()

       return


# BOTの起動とDiscordサーバーへの接続
client.run(TOKEN)

discord.pyのmessage.edit()はBot本人のメッセージ以外は編集できないので、前述の通り、元メッセージを消してBotが画像を投げる方式で実装しました。
エイリアスの最初が“_”(アンダーバー)3文字の場合は元メッセージを残して画像を送信、“_”2文字の場合は元メッセージを削除して画像+元メンバー名を送信しています。
画像は事前にimageディレクトリ直下に配置しておいて、エイリアスから“___”または“__”を削除して拡張子を追加したものを取得しています。

少しハマったのは処理を別関数に出すところで、関数定義にasyncを付けて呼び出し側にはawaitを付ける必要がありました。

運用

これもほぼ参考記事のまま、herokuに登録してデプロイしました。何から何までありがたい。
一ヶ月あたり完全無料で動かすのにクレジットカードを登録する必要があるのですが、英語力が雑兵レベルなので無駄にハマりました。“Billing”の欄でした…。
herokuはアプリケーション名やデプロイ状態に合わせてしれっとデプロイ用のコマンドを動的に表示変更してくれるのが地味に便利ですね。

思ったより簡単にBotが作れて(コードより画像の加工に時間がかかった)達成感があるし面白かったのでまた何か作ってみたいですね。■

この記事が気に入ったらサポートをしてみませんか?