Skip to content

Commit

Permalink
interaction: always try to use cache before checking partial
Browse files Browse the repository at this point in the history
  • Loading branch information
Bilal2453 committed Dec 2, 2024
1 parent e1b14d8 commit 12161a3
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 10 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ that `Guild.memberCount` is never `nil`, then you can simply trust that and neve

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, Guild is for example only getting the guild ID and supported features.
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.

Pre 2.0.0 versions tried to keep that oauth with the user by selling its soul to the devil and transparently request partial objects from the API gateway to get full ones, breaking one of the most important design philosophies of Discordia but keeping the user away from the complexity Discord introduced with partial objects.
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 those contexts *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.
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).
Expand Down Expand Up @@ -96,7 +96,7 @@ client:run("Bot TOKEN")

## Developers Notes

While it is not hard to merge this 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 doing this.
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

Expand Down
12 changes: 6 additions & 6 deletions libs/containers/Interaction.lua
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ end

---@protected
function Interaction:_load(data)
Snowflake._load(self, data)
return self:_loadMore(data)
Snowflake._load(self, data)
return self:_loadMore(data)
end

---@protected
Expand All @@ -92,7 +92,7 @@ end

---@protected
function Interaction:_loadGuild(data)
if not data.guild_id or not data.guild then
if not data.guild_id then
return
end
-- retrieve guild from cache if possible
Expand All @@ -101,7 +101,7 @@ function Interaction:_loadGuild(data)
return
end
-- use the partial object
if not self._guild then
if data.guild then
local guild = data.guild
-- required fields for initialization
guild.stickers = guild.stickers or {}
Expand Down Expand Up @@ -349,8 +349,8 @@ end
function Interaction:autocomplete(choices)
assert(self._type == intrType.applicationCommandAutocomplete, "APPLICATION_COMMAND_AUTOCOMPLETE is only supported by application-based commands!")
choices = resolver.autocomplete(choices) ---@diagnostic disable-line: cast-local-type
assert(choices, 'bad argument #1 to autocomplete (expected table, got ' .. type(choices) .. ')')
assert(#choices <= 25, 'choices must not exceed 25')
assert(choices, "bad argument #1 to autocomplete (expected table, got " .. type(choices) .. ')')
assert(#choices <= 25, "choices must not exceed 25")
local data, err = self.parent._api:createInteractionResponse(self.id, self._token, {
type = callbackType.applicationCommandAutocompleteResult,
data = {
Expand Down

0 comments on commit 12161a3

Please sign in to comment.