How do you send a message in TwitchIO that's not a response to a command?
Question:
I’m setting up a python TwitchIO chat bot. The getting started example has this:
async def event_message(self, message):
print(message.content)
await self.handle_commands(message)
@commands.command(name='test')
async def my_command(self, ctx):
await ctx.send(f'Hello {ctx.author.name}!')
If the incoming message is a command (e.g. !test
), a message is sent back to the channel with ctx.send()
.
I’d like the option to send a message back to the channel (based on come criteria) whenever any message is received, not just commands. For example:
async def event_message(self, message):
print(message.content)
if SOMETHING:
SEND_MESSAGE_HERE
await self.handle_commands(message)
I can’t figure out how to do some type of .send
to make that happen. This answer: TwitchIO: How to send a chat message? show this:
chan = bot.get_channel("channelname")
loop = asyncio.get_event_loop()
loop.create_task(chan.send("Send this message"))
I tried that and the bot sent a ton of messages instantly and got timed out for an hour.
So, the question is: How do you send a message back to the channel inside event_message
Answers:
This is the answer I came up with:
bot_account_name = "BOT_ACCOUNT_NAME"
async def event_message(self, message):
print(message.content)
if message.author.name.lower() != bot_account_name.lower():
ws = self._ws
await ws.send_privmsg('CHANNEL_NAME', 'Message To Send')
await self.handle_commands(message)
You can do other checks, but it’s important to do the check against the bot account user name. If you don’t the bot will see its own messages and reply to them creating a loop. This is one of the issues I ran into where it send a bunch in no time and got timed out by twitch
I found an alternative. I replace the message with a command that I invented for the purpose. The name of the command is "z" but it could have been anything
async def event_message(self, message):
if message.echo:
return
message.content = f"#z {message.content}" # add command name before message
await self.handle_commands(message)
@commands.command()
async def z(self, ctx: commands.Context):
print(f"Original message is {ctx.message.content[3:]}n")
A command passes you a Context
(an instance of of Messageable
, which defines send()
). A Channel
is also a Messageable
, thus it has a send()
. So if your Bot
instance is bot
:
await bot.connected_channels[0].send('...')
Will send a message to the first channel the bot is connected to.
I’m setting up a python TwitchIO chat bot. The getting started example has this:
async def event_message(self, message):
print(message.content)
await self.handle_commands(message)
@commands.command(name='test')
async def my_command(self, ctx):
await ctx.send(f'Hello {ctx.author.name}!')
If the incoming message is a command (e.g. !test
), a message is sent back to the channel with ctx.send()
.
I’d like the option to send a message back to the channel (based on come criteria) whenever any message is received, not just commands. For example:
async def event_message(self, message):
print(message.content)
if SOMETHING:
SEND_MESSAGE_HERE
await self.handle_commands(message)
I can’t figure out how to do some type of .send
to make that happen. This answer: TwitchIO: How to send a chat message? show this:
chan = bot.get_channel("channelname")
loop = asyncio.get_event_loop()
loop.create_task(chan.send("Send this message"))
I tried that and the bot sent a ton of messages instantly and got timed out for an hour.
So, the question is: How do you send a message back to the channel inside event_message
This is the answer I came up with:
bot_account_name = "BOT_ACCOUNT_NAME"
async def event_message(self, message):
print(message.content)
if message.author.name.lower() != bot_account_name.lower():
ws = self._ws
await ws.send_privmsg('CHANNEL_NAME', 'Message To Send')
await self.handle_commands(message)
You can do other checks, but it’s important to do the check against the bot account user name. If you don’t the bot will see its own messages and reply to them creating a loop. This is one of the issues I ran into where it send a bunch in no time and got timed out by twitch
I found an alternative. I replace the message with a command that I invented for the purpose. The name of the command is "z" but it could have been anything
async def event_message(self, message):
if message.echo:
return
message.content = f"#z {message.content}" # add command name before message
await self.handle_commands(message)
@commands.command()
async def z(self, ctx: commands.Context):
print(f"Original message is {ctx.message.content[3:]}n")
A command passes you a Context
(an instance of of Messageable
, which defines send()
). A Channel
is also a Messageable
, thus it has a send()
. So if your Bot
instance is bot
:
await bot.connected_channels[0].send('...')
Will send a message to the first channel the bot is connected to.