Create Server using Discord Bot - python

If we look at the Guild Create event in the discord dev documentation, we see the following:
I have a couple of questions about this. First of all, I am not sure exactly when I can create a server using a bot account. Following the "when a user is initially connecting" section, I attempted to place the server creation into the on_ready function, like so:
import discord
import asyncio
import bot.client.getkey as _getkey
from bot.utils import get_owner
class ImABot(discord.Client):
async def on_ready(self):
ts = await self.create_server("test")
inv = await self.create_invite(ts.default_channel)
await self.send_message(get_owner()) #get owner simply gets the user who owns the bot, me.
Bot = ImABot()
Bot.run(_getkey.key())
However, I get the following error:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/discord/client.py", line 307, in _run_event
yield from getattr(self, event)(*args, **kwargs)
File "/Users/edl/Desktop/ /Programming/Github/Democracy-Bot/demobot/client/client.py", line 22, in on_ready
inv = await self.create_invite(ts.default_channel)
File "/usr/local/lib/python3.6/site-packages/discord/client.py", line 2628, in create_invite
data = yield from self.http.create_invite(destination.id, **options)
AttributeError: 'NoneType' object has no attribute 'id'
I assume this means the server was not created. I hope someone can give me information on when creating a server will work, and whether or not it is possible in the first place. Thanks!

Guilds no longer have default channels, so it is best to avoid using them.
To get the first created channel for the server, your best bet is to use
discord.utils.get(new_server.channels, type=discord.ChannelType.text)
Or if you use discord.py rewrite, then
new_server.text_channels[0]
Then you can create the invite from that channel.

Related

Discord if statement with message author role

I know that I must not be the first one trying to do this. But I really cannot find the solution to my problem. Here is what i'm trying to do. I'm trying to print the member role in the channel only if is role is "member". The thing is, i'm not able to get is role and use it in the IF statement. I tried a lot of thing until I finally understood that the object Client doesn't have a get_context method. But everyone is using it and seems to be able to make things work. I've read the official API docs and I can clearly see that the object "Client" doesn't have a get_context method, but the ext.command.Bot object does. What can I do to make things work ?.
Here is the error I get:
Ignoring exception in on_message
Traceback (most recent call last):
File "/home/runner/Discord-Moderator/venv/lib/python3.8/site-packages/discord/client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "main.py", line 21, in on_message
ctx = await client.get_context(message)
AttributeError: 'Client' object has no attribute 'get_context'
Here is my code:
import discord
import os
import random
from stayin_alive import stayin_alive
client = discord.Client()
#client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
#client.event
async def on_message(message):
msg = message.content.lower()
ctx = await client.get_context(message)
if message.author == client.user:
return
role = discord.utils.find(lambda r: r.name == 'Member', ctx.message.server.roles)
if role in message.author.roles:
await message.channel.send("You are a member")
I even tried with the commands thing in order to do it like this Discord.py bot.get_context() does not return ctx object
import commands
from stayin_alive import stayin_alive
client = discord.Client()
bot = commands.Bot(command_prefix=("!sm"))
But I get this error:
Traceback (most recent call last):
File "main.py", line 4, in <module>
import commands
ModuleNotFoundError: No module named 'commands'
Here is everything I checked out:
https://www.codegrepper.com/code-examples/python/discord.py+add+role+to+user
https://discordpy.readthedocs.io/en/stable/ext/commands/api.html (Bot command Object official Doc)
https://discordpy.readthedocs.io/en/stable/api.html (Client Object Official Doc)
Discord.py bot.get_context() does not return ctx object
https://www.reddit.com/r/learnpython/comments/o8jpi6/so_im_making_a_discord_bot/
How can I get a Discord Context Object from the on_message event?
Can someone please help me to find the solution to my problem. I simply wanna use the message.author.role in my IF statement.
Here is the solution, I've finally found it, I wasn't that far, I knew I could do it without using ctx

(TwitchIO for Python) Invalid syntax error when importing commands

I'm trying to follow a TwitchIO tutorial in the documentation here: https://twitchio.readthedocs.io/en/latest/quickstart.html
I jumped to trying the second block of code which adds an event_message so I copied that code. I just want to run the code so I can begin making a chat bot for twitch. Here is that example code that I copied, the only changes I have made to it have been adding my token and initial_channels (Obviously, not included for privacy):
class Bot(commands.Bot):
def __init__(self):
# Initialise our Bot with our access token, prefix and a list of channels to join on boot...
# prefix can be a callable, which returns a list of strings or a string...
# initial_channels can also be a callable which returns a list of strings...
super().__init__(token='ACCESS_TOKEN', prefix='?', initial_channels=['...'])
async def event_ready(self):
# Notify us when everything is ready!
# We are logged in and ready to chat and use commands...
print(f'Logged in as | {self.nick}')
async def event_message(self, message):
# Messages with echo set to True are messages sent by the bot...
# For now we just want to ignore them...
if message.echo:
return
# Print the contents of our message to console...
print(message.content)
# Since we have commands and are overriding the default `event_message`
# We must let the bot know we want to handle and invoke our commands...
await self.handle_commands(message)
#commands.command()
async def hello(self, ctx: commands.Context):
# Here we have a command hello, we can invoke our command with our prefix and command name
# e.g ?hello
# We can also give our commands aliases (different names) to invoke with.
# Send a hello back!
# Sending a reply back to the channel is easy... Below is an example.
await ctx.send(f'Hello {ctx.author.name}!')
bot = Bot()
bot.run()
When I run this code, I receive this error (Changing user to keep info private lol):
Traceback (most recent call last):
File "C:\Users\-USER-\eclipse-workspace\TwitchIO\src\botRD.py", line 13, in <module>
from twitchio.ext import commands
File "C:\Users\-USER-\AppData\Local\Programs\Python\Python36\lib\site-packages\twitchio\__init__.py", line 33, in <module>
from .client import Client
File "C:\Users\-USER-\AppData\Local\Programs\Python\Python36\lib\site-packages\twitchio\client.py", line 36, in <module>
from .http import TwitchHTTP
File "<fstring>", line 1
(await resp.json())
^
SyntaxError: invalid syntax
I don't know where to begin with this issue. I tried going into the twitchio\client.py but it appears to be importing something from .http and I am not sure how to make changes to that or where to go from there. I tried resetting my computer just in case, but that did not fix the error. This is a bit out of my knowledge range, so I would appreciate it if anyone could recommend a good solution. I'm using Eclipse IDE and Windows 10 if that is important.
Thanks!
TwitchIO requires python 3.7+ and it looks like you're running 3.6. I suspect this is your problem.
Source: https://twitchio.readthedocs.io/en/latest/installing.html

Discord.py: How to print last message on specific channel?

my code is this but output is terrible
import os
import discord
import asyncio
from discord.ext import tasks, commands
client = discord.Client()
#client.event
async def on_ready():
print(f'Connected to Discord!')
channel = client.get_channel(231231321213)
messages = await channel.history(limit=1).flatten()
print(messages)
client.run('token', bot=False)
My Output:
Connected to Discord!
[<Message id=826111938424864848 channel= type=<MessageType.default: 0> author= flags=>]
Traceback (most recent call last):
File "C:\Users\cinar\untitled0.py", line 18, in
client.run('Bot Token', bot=False)
File "D:\Users\cinar\anaconda3\lib\site-packages\discord\client.py", line 714, in run
_cleanup_loop(loop)
File "D:\Users\cinar\anaconda3\lib\site-packages\discord\client.py", line 95, in _cleanup_loop
loop.close()
File "D:\Users\cinar\anaconda3\lib\asyncio\selector_events.py", line 89, in close
raise RuntimeError("Cannot close a running event loop")
RuntimeError: Cannot close a running event loop
I think you are trying to do self bot with an actual bot token, I'm not gonna recommend continuing this as self botting is against ToS. But if you really want to do it anyway, use your email and password instead of a bot token. I'm gonna warn you once again that self botting is against ToS and might get your account banned, so do this at your own risk. Anyway someone already asked how to log in as a user here.
Also as I said in the comment earlier, I looked into discord.py docs and found out history() is yielding message. So maybe you should try to do print(message[0].content) instead.

AttributeError: 'str' object has no attribute 'get' -- Discord.py

I am trying to set a custom Emoji as my bot presence. However, I get this error.
AttributeError: 'str' object has no attribute 'get'
How could I fix this?
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
Bot = commands.Bot(command_prefix="&", intents=intents)
#Bot.event
async def on_ready():
await Bot.change_presence(activity=discord.Activity(type=4, emoji="😁", name="hello")) # The error is related to this line
print("ready!")
Bot.run(TOKEN)
Ignoring exception in on_ready
Traceback (most recent call last):
File "E:\projects\Virtual Environment\discord-bot\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "E:\projects\discord-bot\base.py", line 114, in on_ready
await Bot.change_presence(activity=discord.Activity(type=4, emoji="😁", name="hello"))
File "E:\projects\Virtual Environment\discord-bot\lib\site-packages\discord\activity.py", line 193, in __init__
self.emoji = PartialEmoji.from_dict(emoji)
File "E:\projects\Virtual Environment\discord-bot\lib\site-packages\discord\partial_emoji.py", line 83, in from_dict
animated=data.get('animated', False),
AttributeError: 'str' object has no attribute 'get'
There are a few things to have in mind within your problem.
First of all is that bot accounts are not allowed to set Custom activities (Activity type 4 in your case), this is a limitation from Discord API itself, nothing to do about this, I suggest you look at the other types of activities.
Second, when trying to build a CustomActivity object, you are passing a string of the emoji as parameter, where the documentation asks for a PartialEmoji object, you should first retrieve the PartialEmoji object and pass that as parameter regarding the documentation, but keep reading the following point.
Third and last, there is a known issue in discord.py when creating CustomActivity objects. The problem arises from a mistake in the documentation, where as I mentioned it tells you to pass a PartialEmoji as paramater, but this would only be right for the latest version of discord.py (if you look in the github issue it was updated yesterday). The problem is that the code does not expect a PartialEmoji, it is actually expecting a dict object with a PartialEmoji in it (hence why it is looking for a get() function). I suggest you to make use of this last way of passing the emoji parameter.
You can check this by looking at the source code of discord.py

Getting a discord bot to mention other users

I am working on a bot to do some simple commands for my discord server and I haven't been able to figure out how to get the bot to mention people who aren't the author.
if message.content.startswith("+prank"):
user = client.get_user_info(id)
await client.send_message(message.channel, user.mention + 'mention')
When I try to run the command i come up with the error message:
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python36\lib\site-packages\discord\client.py", line 307, in _run_event
yield from getattr(self, event)(*args, **kwargs)
File "C:/Users/user/Desktop/Murk-Bot 2.0.py", line 130, in on_message
await client.send_message(message.channel, user.mention + 'mention')
AttributeError: 'generator' object has no attribute 'mention'
This happens if I use the command with a mention before, after, and not at all. If it gives some more context here are the imports I am using
import discord
from discord.ext.commands import Bot
from discord.ext import commands
import asyncio
import time
import random
The specific error you are getting is caused by not awaiting a coroutine. client.get_user_info is a coroutine and must use await.
If you want "+prank" to work by mentioning by username, you can find a member object by using server.get_member_named.
Example code provided below. This will check the server the command was called from for the specified username and return the member object.
if message.content.startswith("+prank"):
username = message.content[7:]
member_object = message.server.get_member_named(username)
await client.send_message(message.channel, member_object.mention + 'mention')
It looks like you're trying to implement commands without actually using commands. Don't put everything in the on_message event. If you're not sure how to use the discord.ext.commands module, you can look at the documentation for the experimental rewrite branch.
import discord
from discord.ext.commands import Bot
bot = Bot(command_prefix='+')
#bot.command()
async def prank(target: discord.Member):
await bot.say(target.mention + ' mention')
bot.run('token')
You would use this command with +prank Johnny. The bot would then respond in the same channel #Johnny mention

Categories