itow_kashi
@itow_kashi

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

discordbotのチケット作成方法がわからない

discordbotのチケット作成方法がわからない

pythonでdiscrd.pyのbot作成をしています。
独学でいろいろなサイトや海外の動画を見ながらコードを組んでいる
まだプログラミング触りたての初心者です。
discrdのbotの作り方を勉強していて、
チケットの作成方法やボタンの作り方を調べていますが
調べてもエラーを吐いたりエラーの原因がわからなくて困っています

発生している問題・エラー

discrdのサーバーにはきちんとオンラインでbotは入っていますが
チケットの作成方法に「/ticket」と入力しても反応しません。
Discord_BYWNgO5k15.png

また、ボタンの表示はできたのですが
そのボタンに対するリクエストで({ボタンを押したユーザー}OK!)
と表示させるようにしてるつもりですが、ボタンをクリックしても
インタラクションに失敗しましたとの表示が出てきます。
治し方やボタンに対するレスポンスの作り方がわからないです
Discord_S6khk8b0xA.png

問題のあるソースコード1つ目(/ticketに対して)

import discord
from discord import app_commands, utils

class ticket_launcher(discord.ui.View):
    def __init__(self) -> None:
        super().__init__(timeout=None)

    @discord.ui.button(
        label="Create a Ticket",
        style=discord.ButtonStyle.blurple,
        custom_id="ticket_button",
    )
    async def ticket(
        self, interaction: discord.interactions, button: discord.ui.Button
    ):
        ticket = utils.get(
            interaction.guild.text_channels,
            name=f"ticket-for-{interaction.user.name}-{interaction.user.discriminator}",
        )
        if ticket is not None:
            await interaction.response.send._message(
                f"{ticket.mention}ですでにチケットが開かれています!", ephemeral=True
            )
        else:
            overwirtes = {
                interaction.guild.default_role: discord.PermissionOverwrite(
                    view_channel=False
                ),
                interaction.user: discord.PermissionOverwrite(
                    view_channel=True,
                    send_massage=True,
                    attach_files=True,
                    embed_links=True,
                ),
                interaction.guild.default_me: discord.PermissionOverwrite(
                    view_channel=True, send_massage=True, read_message_history=True
                ),
            }
            channel = await interaction.guild.create_text_channel(
                name=f"ticket-for-{interaction.user.name}-{interaction.user.discriminator}",
                overwirtes=overwirtes,
                reason=f"Ticket for {interaction.user}",
            )
            await channel.send(f"{interaction.user.mention}create a ticket!")
            await interaction.response.send_message(
                f"I've opened a ticket for you at{channel.mention}!", ephemeral=True
            )



class aclient(discord.Client):
    def __init__(self):
        super().__init__(intents=discord.Intents.default())
        self.synced = False  # botがコマンドを複数回同期しないようにこれを使用します。

        async def on_ready(self):
            await self.wait_until_ready()
            if not self.synced:  # スラッシュコマンドが同期されているか確認
                await tree.sync(guild=discord.Object(id=1143948249527488542))
                self.synced = True
            print(f"{self.user}としてログインしました。")


client = aclient()
tree = app_commands.CommandTree(client)


@tree.command(
    guild=discord.Object(id=1143948249527488542),
    name="ticket",
    description="Launches the ticketing system",
)
async def ticketing(interaction: discord.Integration):
    await interaction.response.send_message("Discord.pyによって作動しています!", ephemeral=True)


import os
from dotenv import load_dotenv

load_dotenv("token.env")
client.run(os.environ["Token"])

問題のあるソースコード2つ目(buttonに対するリクエスト)

import discord
from discord.ext import commands

TOKEN = "TOKEN"
bot = commands.Bot(command_prefix="?", intents=discord.Intents.all())

# botが起動したときの処理


@bot.event
async def on_ready():
    print("Botが立ち上がったよ!")


class SampleView(discord.ui.View):  # UIキットを利用するためにdiscord.ui.Viewを継承する
    def __init__(self, timeout=180):  # Viewにはtimeoutがあり、初期値は180(s)である
        super().__init__(timeout=timeout)


@bot.command()
async def test(ctx):
    view = SampleView(timeout=None)
    await ctx.send(view=view)


class SampleView(discord.ui.View):
    def __init__(self, timeout=180):
        super().__init__(timeout=timeout)

    @discord.ui.button(label="OK", style=discord.ButtonStyle.success)
    async def ok(self, button: discord.ui.Button, interaction: discord.Interaction):
        await interaction.response.send_message(f"{interaction.user.mention}"("許可しました。"))
        await interaction.response.send_message("")

    @discord.ui.button(label="NG", style=discord.ButtonStyle.gray)
    async def ng(self, button: discord.ui.Button, interaction: discord.Interaction):
        await interaction.response.send_message("")

bot.run(TOKEN)

問題があるのはわかっているけど治し方がわからないところ

    @discord.ui.button(label="OK", style=discord.ButtonStyle.success)
    async def ok(self, button: discord.ui.Button, interaction: discord.Interaction):
        await interaction.response.send_message(f"{interaction.user.mention}"("許可しました。"))
        await interaction.response.send_message("")

    @discord.ui.button(label="NG", style=discord.ButtonStyle.gray)
    async def ng(self, button: discord.ui.Button, interaction: discord.Interaction):
        await interaction.response.send_message("")

自分で試したこと

Qiitaのほかの方が投稿してるdiscord.pyのサイトを参考にしたり
海外のyoutubeを見ながらコードを書き写したりしました。

参考にしたサイトや動画↓
discord.pyでチケットを作る方法
https://qiita.com/spicy_pse/items/84e5b2040d9bd34ec5da
海外動画↓
https://www.youtube.com/watch?v=WUyeBPkIx8A&ab_channel=Digiwind

0

2Answer

Qiitaのほかの方が投稿してるdiscord.pyのサイトを参考にしたり
海外のyoutubeを見ながらコードを書き写したりしました。

公式ドキュメントのURLを貼っておきます。
読まれたことがないようでしたら、呼んでみるといいと思います。
各種マニュアル等も記載されています。

チャンネル作成の実装に関しては、リポジトリのここら辺のサンプルが参考になりそうです。

ボタンの実装に関しては、リポジトリのここら辺のサンプルが参考になりそうです。

0Like

問題のあるソースコード1つ目(/ticketに対して)

  • スラッシュコマンドの送信方法はあっていますか? スラッシュコマンドを送信するときにdiscordの補完を使ってみてください
    補足
  • 権限はついていますか? スラッシュコマンドはapplications.commandsが必要です。
    image.png

問題のあるソースコード2つ目(buttonに対するリクエスト)

問題があるのはわかっているけど治し方がわからないところ

  • ただのSyntaxErrorがあると思います。f"{interaction.user.mention}"("許可しました。")f"{interaction.user.mention}(許可しました。)"f"{interaction.user.mention}"+("許可しました。")などに修正してみてください

  • interaction.response.send_messageを2つ呼び出している箇所がありますが、send_messageなどのinteraction.responseでの応答は1回のみ可能です。2回目以降はinteraction.folloup.sendを使いましょう。

  • 実際にテストしてませんが、interaction.response.send_messageの引数に空文字列を渡すのはよくないと思います。引数でephemeral=Trueと指定すると、ボタンを押したユーザーにのみ表示できるので使ってみてください。

  • modalを使いたいなどの理由がなければdeferを使うほうがいいと思います。

    @discord.ui.button(label="OK", style=discord.ButtonStyle.success)
     async def ok(self, button: discord.ui.Button, interaction: discord.Interaction):
+        await interaction.response.defer()
+        await interaction.followup.send(f"{interaction.user.mention}"+("許可しました。"))
-        await interaction.response.send_message(f"{interaction.user.mention}"("許可しました。"))
-        await interaction.response.send_message("")

    @discord.ui.button(label="NG", style=discord.ButtonStyle.gray)
    async def ng(self, button: discord.ui.Button, interaction: discord.Interaction):
+        await interaction.response.defer()
+        await interaction.followup.send("拒否しました",ephemeral=True)
-        await interaction.response.send_message("")
0Like

Your answer might help someone💌