Skip to content

A Discordia library extension that enables receiving and responding to Discord's Interactions.

License

Notifications You must be signed in to change notification settings

Bilal2453/discordia-interactions

Repository files navigation

Introduction

Version License

discordia-interactions is an extension library that enables Discordia to receive and respond to Discord Interactions. This is done over the gateway websocket connection that Discordia offers, and aims to be very extensible so other extensions and libraries can build upon without having to worry about compatibility with each other.

This only implements the interactions portion, for App commands such as Message Components or Slash Commands you need to use a second extension library alongside this one, for example discordia-components adds support for Message Components such as buttons and select menus.

Supported responses

  • Text Replies.
  • Deferred Text Replies.
  • Update Replies.
  • Autocomplete Replies.
  • Modal Replies.
  • Premium Required Replies. (deprecated by Discord)
  • Launch Activity Replies.

Installing

You can install this extension with Lit using the following steps:

  1. Install lit if not already installed, see Luvit installation guide and Discordia installation Tutorial.
  2. Open a terminal (PowerShell or CMD on Windows) and preferably cd into your bot's directory (e.x. cd C:\Users\X\Desktop\MyBot then enter).
  3. In the terminal, execute lit install Bilal2453/discordia-interactions. (Note: if you have not set up your PATH, you might have to do ./lit instead of just lit)

Once that is done, you should see Lit print the message done: success, indicating you are now ready to require the extension from your Discordia project.

Due to a bug in Lit, the Lit upstream version of this library won't install, you have to manually clone it.

You may also install the latest main branch by replacing the command in step 3 with:

git clone https://github.com/Bilal2453/discordia-interactions.git ./deps/discordia-interactions`

Documentation

The library is fully documented over at the Wiki, for any questions and support feel free to contact me on our Discordia server, especially if you are writing a library using this!

Building other extensions

This library offers multiple wrapping stages for other libraries to integrate with, allowing you to control the data flow and hook at different stages. For example I built a little Slash command library for the Discordia Wiki bot, and this is how it hooks into discordia-interactions to implement a new slashCommand event. You can hook an interactionCreate event pre-listener, resolve user inputs to Interaction methods with your own resolver, or wrap resolved values.

Deprecation form Discordia

When using a library, you make a contract with that library, it's that what it documents is what it will do. In Discordia for example when the wiki says that Guild.memberCount is never nil, then you can simply trust that and never check whether the property is nil or not, because Discordia guarantees that as part of the contract it made with you.

By using any third-party extension, said contract is automatically broken. (Note: So is modifying the library internally, the same arguments can be made against any method of modifying the library! not just extensions.)

One thing that Discord broke their promises with are Partial Objects. Partial objects are normal objects but with almost none of the required properties that Discordia promises you to always have, for example Guild.memberCount is nil because Discord does not send that on partial objects. It only sends the bare minimum that represents what a thing is, for example a partial Guild only has the guild ID and the supported features array.

discordia-interactions pre 2.0.0 version tried to keep the oauth Discordia makes with the user by selling its soul to the devil and transparently request the full objects from the API gateway instead of using the partial objects Discord sends, breaking one of the most important design philosophies of Discordia (that of never making additional HTTP requests in the background) but keeping away the complexity Discord introduced with partial objects from the end user.

Sadly, when Discord introduced User Installed Apps, this is no more possible to keep, because in that context we cannot request objects from the API, as they are pretty much kept a secret and only the minimum amount of information is provided, as such starting from version 2.0.0, the library breaks this contract and makes a new one with you: Any object obtained by an Interaction is partial and most likely WILL NOT have all of the properties set; if you want the full object request it from the API, or otherwise operate with those objects with caution.

The partial objects more specifically are Guild, Channel and Member. They are cached by Discordia, so iterating the Discordia cache might get you one of them, when the full version is given by Discord (if at all) then cached version is updated with the full one. You may check if a Guild instance is partial by checking Guild._partial (you may only check Guild).

This change sadly adds complexity to the user, but it was absolutely required in order to support User Installed Apps and continue with the development.

Examples

Take a look at the examples directory for the actual examples.

Here is a bit of a usage run down:

local discordia = require("discordia")
require("discordia-interactions") -- Adds the interactionCreate event and applies other patches

local client = discordia.Client()
local intrType = discordia.enums.interactionType

client:on("interactionCreate", function(interaction)
  -- Ephemeral reply to an interaction
  interaction:reply("Hello There! This is ephemeral reply", true)
  -- Send a followup reply
  interaction:reply {
    -- send a file with interactions info
    file = { -- identical to the Discordia field
      "info.txt",
      "Bot received an interaction of the type " .. intrType(interaction.type) .. " from the user " .. interaction.user.name
    },
    -- try to mention the user
    mention = interaction.member or interaction.user,
    -- suppress all mentions
    allowed_mentions = { -- if Discordia's send doesn't handle said field, library'll treat it as raw
      parse = {}
    }
  }
  if interaction.type == intrType.messageComponent then
    -- update the message the component was attached to
    interaction:update {
      embed = {
        title = "Wow! You have actually used the component!",
        color = 0x00ff00,
      }
    }
  end
end)

client:run("Bot TOKEN")

Developers Notes

While it is not hard to merge this extension into Discordia, you are discouraged from doing that. From what I have noticed multiple people are merging this into the Discordia code instead of just using the extensions, and while they might have some reasons to do that, it will make life a lot harder for maintainability, for example when a new discordia-interactions release comes out it will become pretty much a manual job to hand pick the patches to apply, and it creates more incompatibility instead of solving any, this is EXPLICITLY an extension for good reasons, otherwise I could've simply PRed this into Discordia and called it a day, which is a lot easier to me than developing an extension.

License

This project is licensed under the Apache License 2.0, see [LICENSE] for more information. Make sure to include the original copyright notice when copying!

About

A Discordia library extension that enables receiving and responding to Discord's Interactions.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages