0

Sorry for the unclear question title. I don't know any other way to put it.

I made a command that says p!channel [channel_id] which basically makes a channel where my bot will respond with "e". I want the command to store the channel_id and guild_id into a json file called channel.json, and when a user sends a message, it will check if the message is in the channel_id channel, and if it is in the channel, will send "e". However, it's not responding and no error codes are showing up. Can someone help? Code is below:

def get_channel(client,message):
    with open("channel.json", "r") as f:
        e = json.load(f)
        return e[str(message.guild.id)]

@client.command()
@commands.has_permissions()
async def channel(ctx, *, channelid):
    with open("channel.json", "r") as f:
        e = json.load(f)
    e[str(ctx.guild.id)] = channelid
    with open("channel.json", "w") as f:
        json.dump(e,f)    
    await ctx.send(f"Successfully setup <#{channelid}>")

@client.event
async def on_message(message):
    if message.channel.id == get_channel:
        await message.channel.send('e')
Nicholas Chen
  • 144
  • 1
  • 11

1 Answers1

1

There are several immediate problems that are keeping this from functioning.

  • You're only referencing get_channel, not calling it. The channel's ID isn't equal to the function itself, so the message is never sent. You want get_channel(client, message).
  • Your on_message event ensures that your command never gets called.
  • You attempt to use ctx.send() instead of ctx.channel.send().
  • Channel IDs are integers, but command arguments are always read in as strings. Without converting the argument to an integer, comparing it against a channel's ID will always return False.

In addition, there are several things you could improve:

  • The get_channel function doesn't ever use client, so you could alter your function definition to simply get_channel(message).
  • Furthermore, channel IDs are globally unique, so you don't need to save the guild ID in order to unambiguously identify a channel.
  • It would be more efficient not to read the whole file every time you need to check for an ID.
  • The has_permissions check doesn't check anything if you supply it no arguments, so in your code it does nothing.
  • You probably don't want your bot to respond to its own messages.

Here's an improved version that reads a saved file on startup, if one exists. It then keeps the IDs as a set in memory, and only opens the file when it needs to add a new ID.

from discord.ext import commands
import json

client = commands.Bot(command_prefix='p!')

try:
    with open('channels.json') as f:
        client.ids = set(json.load(f))
    print("Loaded channels file")
except FileNotFoundError:
    client.ids = set()
    print("No channels file found")

@client.command()
async def channel(ctx, channel_id):
    try:
        channel_id = int(channel_id)
    except ValueError:
        await ctx.channel.send("Channel must be all digits")
        return

    if channel_id in client.ids:
        await ctx.channel.send(f"Channel <#{channel_id}> is already set up.")
        return

    client.ids.add(channel_id)
    with open('channels.json', 'w') as f:
        json.dump(list(client.ids), f)    
    await ctx.channel.send(f"Successfully set up <#{channel_id}>")

@client.event
async def on_message(message):
    if message.channel.id in client.ids and message.author != client.user:
        await message.channel.send('e')
    
    # Pass processing on to the bot's command(s)
    await client.process_commands(message)

client.run(TOKEN)
CrazyChucky
  • 3,263
  • 4
  • 11
  • 25
  • My code is stuck on the part where my bot loads the json file (client.ids = set(json.load(f))). `File "main.py", line 1124, in on_message if message.channel.id in client.ids and message.author != client.user: AttributeError: 'Bot' object has no attribute 'ids'` – Nicholas Chen May 11 '21 at 00:42
  • 1
    @NicholasChen Those are two different places in the code. And it sounds like you must not have run the `try`/`except` block that initializes `client.ids`. The `on_message` method tries to check `client.ids`, which doesn't exist. Did you copy everything? – CrazyChucky May 11 '21 at 00:44
  • I'm sorry, I put the `try`/`except` before `client` was defined, thanks! – Nicholas Chen May 11 '21 at 02:44