-
Notifications
You must be signed in to change notification settings - Fork 5
Extensions Developing
Because the functionality this extension provides is useless on its own, other extensions are supposed to make use of it to achieve the easier integration with other extensions also making use of interactions, as such we provide a set of APIs to make your life easier.
In a lot of cases you want to hook into the interactionCreate
event so you can emit your own events, for example you may want to parse the interaction object and figure out what type of app commands it is and then emit slashCommand
event, or to emit modalSubmit
events, etc.
This is made possible with pre-listeners and post-listeners, here is an example:
local discordia_interactions = require("discordia-interactions")
function discordia_interactions.EventHandler.interaction_create_prelisteners.slashCommands(intr, client)
if intr.type == enums.interactionType.applicationCommand and intr.data.type == 1 then
client:emit('slashCommand', intr)
end
end
function discordia_interactions.EventHandler.interaction_create_prelisteners.autocomplete(intr, client)
if intr.type == enums.interactionType.applicationCommandAutocomplete and intr.data.type == 1 then
client:emit('slashCommandAutocomplete', intr)
end
end
In this example, the extension will execute this listener before interactionCreate
has been fired giving you a chance to fire all kind of events. It is also possible to hook a listener to when an interactionCreate
even has been fired with interaction_create_postlisteners
, the difference between a post-listener and listening directly to interactionCreate
is that you are always guaranteed to get this fired after all other listeners have been already fired, as well as that client:removeListener
will not affect it (i.e. the end-user can't just remove your extension listeners).
You can also find a usage of this in discordia-modals to emit the custom event modalSubmit
Note that interactionCreate
WILL still be fired, and you cannot prevent it from firing. This is an intentional design and you shall not do anything preventing it from firing.
discordia-interactions offers methods that respond with the raw structures of Discord (the only exception is reply
, as the Discordia behavior is used for that), this might not be desired to the end-user, as such it is possible for your extension to offer a higher level input with resolvers wrappers.
Wrappers are functions that are called by discordia-interactions, they will take the user input and will be expected to return the raw structure to sent to Discord. When a wrapper returns something, the rest of wrappers are cancelled and the first to match wrapper will be used.
For example, imagine you have a Modal
class that represents a higher level representation of a modal, and you want to allow the following usage:
local my_modal = createModal(...)
-- ...
interaction:modal(my_modal)
You can achieve this with discordia_interactions.resolver.modal_resolvers
, for example:
table.insert(discordia_interactions.resolver.modal_resolvers, function(content)
if isInstance(content, Modal) then
return content:raw()
elseif type(content) == 'table' and content.id and content.title then
return Modal(content):raw()
end
end)
Note: you may also use the map portion of the table, but other extensions may override that.
This is called on Interaction.reply
and Interaction.replyDeferred
in addition to the Discordia resolver. You are expected to return a raw Message Structure.
This is called on Interaction.autocomplete(choices)
, you will receive user-provided choices
, the resolver is expected to return an Autocomplete Response Structure. See Autocomplete for more information.
This is called on Interaction.modal(modal)
, you will receive user-provided modal
, the resolver is expected to return a Modal Structure.
It is also possible to run callbacks on the resolved value just before sending the request, this allows you to bypass whatever resolver has been used so you can always alter the final result. You will be given the raw data, and you are not expected to return anything.
For example, here is a code snippet to always set message content sent with Interaction:reply
/Interaction:replyDeferred
even if the user doesn't set it:
table.insert(discordia_interactions.resolver.message_wrappers, function(message)
if not message.content then
message.content = "Beep Boop!"
end
end)
Note: you may also use the map portion of the table, but other extensions may override that.
Called on Interaction:reply(message)
/Interaction:replyDeferred(message)
just before sending the message request.
Callback params:
-
message
- The Raw Message Object.
Called on Interaction.autocomplete(choices)
.
Callback params:
-
choices
- Autocomplete structure.
Called on Interaction.modal(modal)
.
Callback params:
-
modal
- Modal Components Structure.
you will receive user-provided modal
, the resolver is expected to return a Text Input Components response.