Examples¶
All aiocord
terminal commands assume you either:
Set the
DISCORD_TOKEN
environment variableUse the
--token <TOKEN>
flag before any subcommands
Widgets¶
Make a blep/__init__.py
python package:
import aiocord
async def __load__(info):
print('loaded', __name__)
async def __drop__(info):
print('dropped', __name__)
@aiocord.widget.callback(aiocord.events.CreateMessage)
async def _callback_create_message(info, core_event):
print('message created!', core_event.message.content)
@aiocord.widget.interact('blep')
async def _interact_blep(info, core_event):
users = core_event.interaction.data.resolved.users
blepping = ' '.join(user.mention() for user in users)
return aiocord.model.protocols.InteractionResponse(
type = aiocord.model.enums.InteractionResponseType.channel_message_with_source,
data = aiocord.model.protocols.MessageInteractionResponse(
content = f'blep {blepping}'
)
)
Note
Relative imports of package level are allowed.
Note
Loading other modules using aiocord.widget.load()
is allowed.
Then, run the following:
aiocord start blep
Integration¶
Finer control over starting, loading, dropping and stopping.
import asyncio
import aiocord
async def start(client):
await client.start()
await client.ready()
await aiocord.widget.load(client, 'blep', './modules')
async def stop(client):
await aiocord.widget.drop(client, 'blep')
await client.stop()
loop = asyncio.get_event_loop()
client = aiocord.client.Client(token = ...)
loop.run_until_complete(start(client))
try:
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
loop.run_until_complete(stop(client))
Commands¶
Make a commands.py
python script and define a commands
variable:
import aiocord
commands = [
aiocord.model.protocols.ApplicationCommand(
name = 'blep',
type = aiocord.model.enums.ApplicationCommandType.chat_input,
description = 'blep someone',
options = [
aiocord.model.protocols.ApplicationCommandOption(
name = 'user',
description = 'the user to blep',
type = aiocord.model.enums.ApplicationCommandOptionType.user
)
]
)
]
Then, run the following:
aiocord update commands
A commands.json
will be created and the application’s commands will be updated with its contents.
Interactions¶
Naive Approach¶
Creating a shop
command routine for buying sweets and potentially gifting them.
import aiocord
import secrets
@aiocord.widget.interact('shop')
async def _interact_shop(info: aiocord.widget.Info, core_event: aiocord.events.CreateInteraction):
# define the stock
stock = {
'ice-cream': {
'name': 'Ice Cream',
'emoji': '🍦'
},
'cake': {
'name': 'Cake',
'emoji': '🍰'
},
'waffle': {
'name': 'Waffle',
'emoji': '🧇'
}
}
# unique identifier
select_custom_id = secrets.token_hex(16)
# compose the response
response = aiocord.model.protocols.InteractionResponse(
type = aiocord.model.enums.InteractionResponseType.channel_message_with_source,
data = aiocord.model.protocols.MessageInteractionResponse(
content = 'What would you like to buy?',
components = [
aiocord.model.protocols.MessageActionRowComponent(
type = aiocord.model.enums.MessageComponentType.action_row,
components = [
aiocord.model.protocols.MessageSelectMenuComponent(
custom_id = select_custom_id,
type = aiocord.model.enums.MessageComponentType.string_select,
options = [
aiocord.model.protocols.MessageSelectMenuComponentOption(
value = key,
label = item['name'],
description = 'Sweet, fluffy, chunky and super tasty.',
emoji = aiocord.model.protocols.Emoji(
name = item['emoji']
)
)
for key, item in stock.items()
]
)
]
)
],
# ensure only the invoker can see this
flags = aiocord.model.enums.MessageFlags.ephemeral
)
)
# condition for the expected interaction
async def check(core_event: aiocord.events.CreateInteraction):
# only accept an interaction to the identifer
return core_event.interaction.type == aiocord.model.enums.InteractionType.message_component and core_event.interaction.data.custom_id == select_custom_id
# make the waiter
sentinel = info.client.wait(aiocord.events.CreateInteraction, check)
# send the response
await info.client.create_interaction_response(core_event.interaction.id, core_event.interaction.token, **response)
# wait the interaction
core_event = await sentinel
# resolve the picked item
item = stock[core_event.interaction.data.values[0]]['name']
# unique identifiers
negative_button_custom_id = secrets.token_hex(16)
positive_button_custom_id = secrets.token_hex(16)
# compose the response
response = aiocord.model.protocols.InteractionResponse(
type = aiocord.model.enums.InteractionResponseType.channel_message_with_source,
data = aiocord.model.protocols.MessageInteractionResponse(
content = 'Is it a gift for someone?',
components = [
aiocord.model.protocols.MessageActionRowComponent(
type = aiocord.model.enums.MessageComponentType.action_row,
components = [
aiocord.model.protocols.MessageButtonComponent(
custom_id = positive_button_custom_id,
type = aiocord.model.enums.MessageComponentType.button,
label = 'Yes',
style = aiocord.model.enums.MessageButtonComponentStyle.primary
),
aiocord.model.protocols.MessageButtonComponent(
custom_id = negative_button_custom_id,
type = aiocord.model.enums.MessageComponentType.button,
label = 'No',
style = aiocord.model.enums.MessageButtonComponentStyle.secondary
)
]
)
],
# ensure only the invoker can see this
flags = aiocord.model.enums.MessageFlags.ephemeral
)
)
# unique identifier group
custom_id_button_group = [negative_button_custom_id, positive_button_custom_id]
# condition for the expected interaction
async def check(core_event: aiocord.events.CreateInteraction):
# only accept an interaction to the identifers
return core_event.interaction.type == aiocord.model.enums.InteractionType.message_component and core_event.interaction.data.custom_id in custom_id_button_group
# make the waiter
sentinel = info.client.wait(aiocord.events.CreateInteraction, check)
# send the response
await info.client.create_interaction_response(core_event.interaction.id, core_event.interaction.token, **response)
# wait the interaction
core_event = await sentinel
# resolve whether positive
is_gift = custom_id_button_group.index(core_event.interaction.data.custom_id)
# ...is it?
if is_gift:
# unique identifier
select_custom_id = secrets.token_hex(16)
# compose the response
response = aiocord.model.protocols.InteractionResponse(
type = aiocord.model.enums.InteractionResponseType.channel_message_with_source,
data = aiocord.model.protocols.MessageInteractionResponse(
content = 'Who is this a gift for?',
components = [
aiocord.model.protocols.MessageActionRowComponent(
type = aiocord.model.enums.MessageComponentType.action_row,
components = [
aiocord.model.protocols.MessageSelectMenuComponent(
custom_id = select_custom_id,
type = aiocord.model.enums.MessageComponentType.user_select
)
]
)
],
flags = aiocord.model.enums.MessageFlags.ephemeral
)
)
# condition for the expected interaction
async def check(core_event: aiocord.events.CreateInteraction):
return core_event.interaction.type == aiocord.model.enums.InteractionType.message_component and core_event.interaction.data.custom_id == select_custom_id
# make the waiter
sentinel = info.client.wait(aiocord.events.CreateInteraction, check)
# send the response
await info.client.create_interaction_response(core_event.interaction.id, core_event.interaction.token, **response)
# wait the interaction
core_event = await sentinel
# resolve the recipients
recipient = ' '.join(aiocord.model.mentions.user(user_id) for user_id in core_event.interaction.data.values)
else:
recipient = 'themselves'
# compose the response
response = aiocord.model.protocols.InteractionResponse(
type = aiocord.model.enums.InteractionResponseType.channel_message_with_source,
data = aiocord.model.protocols.MessageInteractionResponse(
# anyone can see this
content = f'{info.client.cache.user.mention()} bought {item} for {recipient}!'
)
)
# send the response
await info.client.create_interaction_response(core_event.interaction.id, core_event.interaction.token, **response)
Smart Approach¶
Using the following:
Funneling with
aiocord.utils.interact()
Returning
response
in elligible functions
Trivializes the following:
Managing
custom_id
Waiting with
client.Client.wait()
Responding with
client.Client.create_interaction_response()
Additionally, code organization and readability improve.
import aiocord
import functools
async def _interact_shop_respond(item, recipient, info: aiocord.widget.Info, core_event: aiocord.events.CreateInteraction):
response = aiocord.model.protocols.InteractionResponse(
type = aiocord.model.enums.InteractionResponseType.channel_message_with_source,
data = aiocord.model.protocols.MessageInteractionResponse(
content = f'{core_event.interaction.member.user.mention()} bought {item} for {recipient}!'
)
)
return response
async def _interact_shop_item_gifting_select(item, info: aiocord.widget.Info, core_event: aiocord.events.CreateInteraction):
# ignore timeouts
if core_event is None:
return
# compose the recipient
recipient = ' '.join(aiocord.model.mentions.user(user_id) for user_id in core_event.interaction.data.values)
# get the response
response = await _interact_shop_respond(item, recipient, info, core_event)
# send the response
return response
async def _interact_shop_item_gifting_accept(item, info: aiocord.widget.Info, core_event: aiocord.events.CreateInteraction):
# ignore timeouts
if core_event is None:
return
# compose the response
response = aiocord.model.protocols.InteractionResponse(
type = aiocord.model.enums.InteractionResponseType.channel_message_with_source,
data = aiocord.model.protocols.MessageInteractionResponse(
content = 'Who is this a gift for?',
components = [
aiocord.model.protocols.MessageActionRowComponent(
type = aiocord.model.enums.MessageComponentType.action_row,
components = [
aiocord.utils.interact(
info.client,
functools.partial(_interact_shop_item_gifting_select, item, info),
aiocord.model.protocols.MessageSelectMenuComponent(
type = aiocord.model.enums.MessageComponentType.user_select
)
)
]
)
],
flags = aiocord.model.enums.MessageFlags.ephemeral
)
)
# send the response
return response
async def _interact_shop_item_gifting_reject(item, info: aiocord.widget.Info, core_event: aiocord.events.CreateInteraction):
# ignore timeouts
if core_event is None:
return
# compose the recipient
recipient = 'themselves'
# get the response
response = await _interact_shop_respond(item, recipient, info, core_event)
# send the response
return response
async def _interact_shop_stock_select(stock, info: aiocord.widget.Info, core_event: aiocord.events.CreateInteraction):
# ignore timeouts
if core_event is None:
return
# get the item name from stock
item = stock[core_event.interaction.data.values[0]]['name']
# compose the response
response = aiocord.model.protocols.InteractionResponse(
type = aiocord.model.enums.InteractionResponseType.channel_message_with_source,
data = aiocord.model.protocols.MessageInteractionResponse(
content = 'Is it a gift for someone?',
components = [
aiocord.model.protocols.MessageActionRowComponent(
type = aiocord.model.enums.MessageComponentType.action_row,
components = [
aiocord.utils.interact(
info.client,
functools.partial(_interact_shop_item_gifting_accept, item, info),
aiocord.model.protocols.MessageButtonComponent(
type = aiocord.model.enums.MessageComponentType.button,
label = 'Yes',
style = aiocord.model.enums.MessageButtonComponentStyle.primary
)
),
aiocord.utils.interact(
info.client,
functools.partial(_interact_shop_item_gifting_reject, item, info),
aiocord.model.protocols.MessageButtonComponent(
type = aiocord.model.enums.MessageComponentType.button,
label = 'No',
style = aiocord.model.enums.MessageButtonComponentStyle.secondary
)
),
]
)
],
flags = aiocord.model.enums.MessageFlags.ephemeral
)
)
# send the response
return response
@aiocord.widget.interact('shop')
async def _interact_shop(info: aiocord.widget.Info, core_event: aiocord.events.CreateInteraction):
# define the stock
stock = {
'ice-cream': {
'name': 'Ice Cream',
'emoji': '🍦'
},
'cake': {
'name': 'Cake',
'emoji': '🍰'
},
'waffle': {
'name': 'Waffle',
'emoji': '🧇'
},
}
# compose the response
response = aiocord.model.protocols.InteractionResponse(
type = aiocord.model.enums.InteractionResponseType.channel_message_with_source,
data = aiocord.model.protocols.MessageInteractionResponse(
content = 'What would you like to buy?',
components = [
aiocord.model.protocols.MessageActionRowComponent(
type = aiocord.model.enums.MessageComponentType.action_row,
components = [
aiocord.utils.interact(
info.client,
functools.partial(_interact_shop_stock_select, stock, info),
aiocord.model.protocols.MessageSelectMenuComponent(
type = aiocord.model.enums.MessageComponentType.string_select,
options = [
aiocord.model.protocols.MessageSelectMenuComponentOption(
value = key,
label = item['name'],
description = 'Sweet, fluffy, chunky and super tasty.',
emoji = aiocord.model.protocols.Emoji(
name = item['emoji']
)
)
for key, item in stock.items()
]
)
)
]
)
],
flags = aiocord.model.enums.MessageFlags.ephemeral
)
)
# send the response
return response
Note
Since aiocord.utils.interact()
only passes the event to the callback, functools.partial()
is necessary for carrying information (such as stock
and item
) along the routine.
HTTP-Only¶
Invoking HTTP routes without connecting to the gateway.
import asyncio
import aiocord
async def main(client):
message = await client.create_message('864902189816273146', content = 'hello!')
await client.create_reaction(message.channel_id, message.id, '🤠')
loop = asyncio.get_event_loop()
client = aiocord.client.Client(token = ...)
loop.run_until_complete(main(client))
Voice¶
Joining a voice channel and playing music via a local file.
import asyncio
import aiocord
async def start(client):
await client.start()
await client.ready()
async def main(client):
voice = await client.start_voice('506536485156739358', '543273600667152384')
audio = aiocord.voice.audio.Audio(source = './song.mp3')
await voice.player.start(audio)
async def stop(client):
await client.stop()
loop = asyncio.get_event_loop()
client = aiocord.client.Client(token = ...)
loop.run_until_complete(start(client))
try:
loop.run_until_complete(main(client))
except KeyboardInterrupt:
pass
finally:
loop.run_until_complete(stop(client))
Audio data may be directly fed programatically.
with open('./song.mp3', 'rb') as file:
data = file.read()
async def main(client):
voice = await client.start_voice('506536485156739358', '543273600667152384')
audio = aiocord.voice.audio.Audio()
audio.feed(data)
await voice.player.start(audio)
Note
For linux and macos, ffmpeg can be installed with homebrew
via brew install ffmpeg
.
Since this creates a shell command, there is no need to specify the executable location.
For windows, ffmpeg.exe
must be on the system. It can be found here.
To avoid having to specify the executable location with Audio(executable = ...)
, it can be added to the PATH.