2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Qiita×Findy記事投稿キャンペーン 「自分のエンジニアとしてのキャリアを振り返ろう!」

discord pyで簡単にメッセージリンクを検知して埋め込みが表示されるbotの作り方

Last updated at Posted at 2024-02-19

今回はメッセージリンクをサーバーに送信するとこんな感じに埋め込み(embed)が送信されるbotを作っていきます。
スクリーンショット 2024-01-04 124632.png

具材(用意するもの)

python (ver3.9以上を推奨)
discord py

作り方

まずは基本のソースコードを貼り付けます。

sample.py
import discord
from discord.ui import Button, View

lass SampleView(discord.ui.View): 
    def __init__(self, timeout=None): 
        super().__init__(timeout=timeout)

@bot.event
async def on_message(message):
    # メッセージの内容をチェック
    if "https://discord.com/channels/" in message.content:
        # メッセージリンクが含まれている場合
        link = message.content.split("https://discord.com/channels/")[1]
        guild_id, channel_id, message_id = map(int, link.split("/"))

        # メッセージリンクが現在のサーバーに属しているかどうかをチェック
        if message.guild.id != guild_id:
            # 現在のサーバー以外のリンクには反応しない
            return

        try:
            # リンク先のメッセージオブジェクトを取得
            target_channel = bot.get_guild(guild_id).get_channel(channel_id)
            target_message = await target_channel.fetch_message(message_id)

            # リンク先のメッセージオブジェクトから、メッセージの内容、送信者の名前とアイコンなどの情報を取得
            content = target_message.content
            author = target_message.author
            name = author.name
            icon_url = author.avatar.url if author.avatar else author.default_avatar.url
            timestamp = target_message.created_at
            target_message_link = f"https://discord.com/channels/{guild_id}/{channel_id}/{message_id}"

            # Embedオブジェクトを作成
            embed = discord.Embed(description=content, color=0x00bfff, timestamp=timestamp)
            embed.set_author(name=name, icon_url=icon_url)
            embed.set_footer(text=f"From #{target_message.channel}")

            # 画像添付ファイルがある場合、最初の画像をEmbedに追加
            if target_message.attachments:
                attachment = target_message.attachments[0]  # 最初の添付ファイルを取得
                if any(attachment.filename.lower().endswith(image_ext) for image_ext in ['png', 'jpg', 'jpeg', 'gif', 'webp']):
                    embed.set_image(url=attachment.url)  # 画像をEmbedに設定

            # ボタンコンポーネントを使ったViewオブジェクトを作成
            view = discord.ui.View(timeout=None)
            view.add_item(discord.ui.Button(label="メッセージ先はこちら", style=discord.ButtonStyle.link, url=target_message_link))

            # EmbedとViewをメッセージとして送信
            await message.channel.send(embed=embed, view=view)

            # リンク先のメッセージがembedだった場合は、元のembedも表示する
            for original_embed in target_message.embeds:
                await message.channel.send(embed=original_embed, view=view)

        except Exception as e:
            print(f"エラーらしい: {e}")

ちなみにこれで完成です。
興味がある人は解説をみてくださいね。

解説

まず、細かな機能として、悪用防止のため他のサーバーのメッセージリンクには反応しないように作られています。
反応させたい場合は適当に下ののところを消すと反応するようにはなります。

sample.py
  if message.guild.id != guild_id:
            # 現在のサーバー以外のリンクには反応しない
            return

        try:

次に装飾部分について大まかに説明します

sample.py
 target_channel = bot.get_guild(guild_id).get_channel(channel_id)
            target_message = await target_channel.fetch_message(message_id)

            # リンク先のメッセージオブジェクトから、メッセージの内容、送信者の名前とアイコンなどの情報を取得
            content = target_message.content
            author = target_message.author
            name = author.name
            icon_url = author.avatar.url if author.avatar else author.default_avatar.url
            timestamp = target_message.created_at
            target_message_link = f"https://discord.com/channels/{guild_id}/{channel_id}/{message_id}"

            # Embedオブジェクトを作成
            embed = discord.Embed(description=content, color=0x00bfff, timestamp=timestamp)
            embed.set_author(name=name, icon_url=icon_url)
            embed.set_footer(text=f"From #{target_message.channel}")

            # 画像添付ファイルがある場合、最初の画像をEmbedに追加
            if target_message.attachments:
                attachment = target_message.attachments[0]  # 最初の添付ファイルを取得
                if any(attachment.filename.lower().endswith(image_ext) for image_ext in ['png', 'jpg', 'jpeg', 'gif', 'webp']):
                    embed.set_image(url=attachment.url)  # 画像をEmbedに設定

まぁコメントにある通り、装飾にはメッセージリンクリンク先のユーザーアイコン(ヘッダー)
メッセージリンク先のメッセージ、画像がある場合には画像なども表示、フッターにどこのチャンネルか、いつのメッセージかを表示されるようにしてます。

これだけだとオリジナリティがないので他のbotにはないメッセージリンク先に飛ぶためのurlbuttonも作ってみました。

sample.py
view = discord.ui.View(timeout=None)
view.add_item(discord.ui.Button(label="メッセージ先はこちら", style=discord.ButtonStyle.link, url=target_message_link))

ここの部分ですね、discord uiみたいなのを使って作ってみました気になる人はdiscord ui buttonと検索すると
多分出てきます。
このボタンをおすと、ユーザーが送信したメッセージリンク先に行けます。

あとがき

いい感じにできたのでコードを共有したいと思って今回の記事を書きました。
何かエラーや書いてほしい記事などがありましたらコメントにかいていただけると幸いです。
それと、こんなん作っても一生起動とか無理や!って人用にこの機能を兼ね備えたbotのurlを配布します。
https://discord.com/oauth2/authorize?client_id=1276463409747198003&scope=bot+applications.commands&permissions=8
それでは良いdiscordライフを

2
0
0

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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?