TwitchIO: Delete a single message in channel - python-3.x

How can I delete a single message sent by a user using TwitchIO?
#bot.event
async def event_message(ctx):
await ctx.content.delete() # Does not work
await ctx.content.remove() # Does not work
await ctx.channel.timeout(ctx.author, 1) # Does not work

The question is older, but I'll answer it anyway.
Twitchio doesn't directly support this.
But you can delete individual messages in Twitch Chat, see the Twitch IRC documentation.
CLEARMSG (Twitch Commands)
You need the message ID for this. You get the ID in the message tags.
Message tags
Code example:
async def event_message(message):
if not message.author.name == self.bot.nick:
message_id = message.tags['id']
await message.channel.send(f"/delete {message_id}")
If you want to timeout someone, do the following:
await message.channel.timeout(message.author.name, 120, f"reason")
Twitchio documentation Channel.timeout

Related

Echo a message from another app in discord

I have a bot running in a separate app, but there is a specific variable holding data that I want to also be echo'd on my discord server. The bot itself is huge, but I can pin the specific method here
import discord
import asyncio
import rpChat
global note
class EchoBot(rpChat.ChatClient):
def on_PRI(self, character, message):
super().on_PRI(character, message)
note = character + ": " + message
global note
if message[:1] == "~":
super().PRI("A GameMaster", note)
to try to send this message to discord, I have the following. This is not put in the class above, but just below it, and is not in a class itself:
client = discord.Client()
async def discordEcho():
"""Background task that sends message sent from chat to an appropriate Discord channel
when global messege data is updated"""
await client.wait_until_ready()
channel = client.get_channel(serverroom}
while not client.is_closed():
global note
await channel.send(channel, note)
The data to grab the channel IDs are found in a json
file = open("credentials.json", "r", encoding="utf-8")
info = json.load(file)
file.close()
token = info["discord"]
serverroom = info["serverroom"]
client.loop.create_task(discordEcho())
client.run(token)
When I try this, I obtain:
await client.send_message(channel, message)
AttributeError: 'Client' object has no attribute 'send_message'
And I am unsure why. I have built a bot for both this chat platform, and for discord, but this is the first time I've ever attempted to bridge messages between the two. I am sure what I have offered is clear as mud, but any help would be appreciated, if possible.
Edit:
Edited changes to code. It is working thanks to comment below.
client.send_message is an old, outdated method, it has been replaced with Messageable.send
async def discordEcho():
"""Background task that sends message sent from chat to an appropriate Discord channel
when global messege data is updated"""
await client.wait_until_ready()
channel = client.get_channel(serverroom)
while not client.is_closed():
global note
await channel.send(note)
Side note: you first need to wait_until_ready before getting the channel to wait until the cache is done loading, otherwise channel will be None

Check TextChannel's id and do some actions

Hey everyone I want to delete all messages from a specific text channel I use this method
#client.event
async def on_message(message):
for guild in client.guilds:
for channel in guild.text_channels:
if channel.id == 818522056261369906:
await message.delete()
it works but it delete all text channels messages not just that text channel with the id above
What is the problem
it works but it delete all text channels messages not just that text channel with the id above What is the problem
You're deleting the message upon checking if a certain channel exists in your bot (i.e by checking if that channel exists in any of all the guilds your bot is in). You're not checking if the message's channel's id matches the provided ID or not. That's why it only checks if that specific channel exists and continues to delete the message regardless of weather they're in that specific channel or not.
for channel in guild.text_channels:
# you're checking if a certain channel in guild's
# text_channel matches the ID or not
if channel.id == 818522056261369906:
await message.delete()
But you ought to check if your message's channel's id matches the ID or not. You can do so by message.channel.id == 818522056261369906. So your code should look something like this
if message.channel.id == 818522056261369906:
await message.delete()
The simplest way to do this would be to include get_channel(id) and await purge if you want to continuously delete messages from a channel.
#client.event
async def on_message(message):
channel = client.get_channel(818522056261369906) # this gets the specific channel through id
await channel.purge()
await client.process_commands(message)
However, if you only want to purge it once in a given channel, you would use a #client.command with similar code as above.
#client.command()
async def test(ctx):
channel = ctx.channel # getting the current channel
await channel.purge()
Edit: Don't forget to add your await client.process_commands(message) if you're using both the commands extension and the on_message event!

Add a reaction to a ctx.send message in discord.py

I am making a poll command, the bot will send a ctx message and will say the poll question. I want to make it so when the poll message is sent, the bot adds two reaction, a thumbs up and a thumbs down. I have tried several different ways but non of them work. Here is the code from my latest try (everything is already imported)
reactions = ["👍", "👎"]
#bot.command(pass_context=True)
async def poll(self, ctx, message,*, question):
poll_msg = f"Poll: {question} -{ctx.author}"
reply = await self.bot.say(poll_msg)
for emoji_id in reactions:
emoji = get(ctx.server.emojis, name=emoji_id)
await message.add_reaction(reply, emoji or emoji_id)
The code is all over the place because I tried putting different solutions together to see if it would work but it doesn't work at all.
It looks like you're operating from some old examples. You should read the official documentation to find examples of the modern interfaces.
from discord.ext import commands
from discord.utils import get
bot = commands.Bot("!")
reactions = ["👍", "👎"]
#bot.command()
async def poll(ctx, *, question):
m = await ctx.send(f"Poll: {question} -{ctx.author}")
for name in reactions:
emoji = get(ctx.guild.emojis, name=name)
await m.add_reaction(emoji or name)

Delete all the bot's messages in a channel

I am trying to create a command in my bot that will delete all the bot's messages only. Is there a way to iterate through all the channel's messages and if it is a message the bot sent, the bot would delete it? I've understood delete_message but I can't figure out how to iterate through all the channel's messages, if that is even possible.
The following code wouldn't iterate through all the channel's messages, but it would delete the message if the author ID is 383804325077581834:
#bot.event
async def on_message(message):
if message.author.id == '383804325077581834':
await bot.delete_message(message)
383804325077581834 is my bot's ID. So I would like to know how I can iterate through all channel messages and delete those that were sent by my bot. Thank you so much!
EDIT: Tried doing this:
#bot.command(pass_context=True)
async def delete(ctx, number):
msgs = []
number = int(number)
async for msg in bot.logs_from(ctx.message.channel, limit=number):
if msg.author.id == '383804325077581834':
msgs.append(msg)
await bot.delete_messages(msgs)
But I get the error discord.ext.commands.errors.MissingRequiredArgument: number is a required argument that is missing.
#bot.command(pass_context=True)
async def delete(ctx):
msgs = []
async for msg in bot.logs_from(ctx.message.channel):
if msg.author.id == '383804325077581834':
msgs.append(msg)
await bot.delete_messages(msgs)
The command you tried using needed a number parameter which would delete that number of messages from the channel.
The logs_from function will delete all messages from that channel if the limit is not passed into it.
EDIT: Forgot to remove number, whoops.

discord.py module how do i remove the command text afterwards?

from discord.ext.commands import Bot
import secrets
from time import sleep
discordBot = Bot(command_prefix = ".")
listStrings = ['add a reaction', 'adnd']
#discordBot.event
async def on_read():
print('Client logged in')
#discordBot.command()
async def s(*args):
return await discordBot.say (" ".join(args))
#discordBot.command()
async def close():
quit()
discordBot.run(secrets.token)
I wanted to say ".s (text)" and that the bot says the text(works already) but deletes your message, how can i do this? i got the part working of on_message:
#discordbot.event
async def on_message(message):
await discordBot.delete_message(message)
What is the best way to do this? Thanks in advance.
I'm sorry you haven't got an answer for 26 days. If you are still looking for an answer, I hope I can provide some help. So I ran your code, and the bot ran the command, my message deleted, then the bot's message also deleted. One way to fix this is to provide an if statement which means the bot only deletes the message if the author is not a bot.
#test_bot.event
async def on_message(message):
if not (message.author).bot:
await test_bot.delete_message(message)
await test_bot.process_commands(message)
Another way to remove only messages that are the commands is to use another if statement. The following code is specific, so you only delete commands, not just all user's messages if they aren't a bot. The following code uses message.content which returns the message as a string.
#test_bot.event
async def on_message(message):
if message.content.startswith('.s'):
await test_bot.delete_message(message)
await test_bot.process_commands(message)

Resources