twilight-model on the latest commit (f58b540 as of writing) deserialises these two distinct events:
Joining a new guild
A previously unavailable guild becoming available
as the same object, namely GuildCreate::Available(Guild { unavailable: false, .. }). This behaviour should be undesirable, as information was lost about which event it was.
Steps to reproduce
Copy the minimal bot setup as stated in the twilight-gateway example here. Pin twilight-http, twilight-gateway and twilight-model to revision f58b540.
Prepare a bot account. Before running the bot, add it to some guild with some ID ID1.
Run the bot via running DISCORD_TOKEN="..." cargo run, replacing ... with the bot's token.
Wait until "Bot is ready" appears in the log. Then, add the bot to another guild with some ID ID2.
Expected Behaviour
Upon the same time as "Bot is ready" appears in the log, the guild of ID ID1 should become available, appearing in the logs as an event of a guild becoming available. This is a documented behaviour as scenario 1. Then, as the bot is added to another guild of ID ID2, it should appear in the logs as an event of joining a guild. These two events are distinct so the logs should reflect that.
Actual Behaviour
The logs are as shown:
YYYY-MM-DDTHH:MM:SS.FFFFF0Z INFO rust_playground: Bot is ready
YYYY-MM-DDTHH:MM:SS.FFFFF1Z INFO rust_playground: Available guild.unavailable=false guild.id=Id<GuildMarker>(ID1)
YYYY-MM-DDTHH:MM:SS.FFFFF2Z INFO rust_playground: Available guild.unavailable=false guild.id=Id<GuildMarker>(ID2)
(Time information is redacted, but time FFFFF0 and FFFFF1 should be negligibly near each other, and FFFFF2 should be different than the other two timestamps.)
Due to how twilight deserialises these two distinct events, they both show up in the logs as the exact same thing as shown by the logs above, losing the information about whether which was originally sent.
Additional Information
Although not documented, it can be verified that the Discord Gateway differentiate these two events as the following:
Upon receiving GuildCreate, if the unavailable field is sent, then the guild became available.
If the field is not sent, then the current user joined a new guild.
And this is exactly how Hikari, a python Discord API library, handle this: It separates the event into GuildJoin and GuildAvailable, and upon ShardReady, the unavailable guilds become available with GuildAvailable, and guild joins register as GuildJoin, correctly differentiating the two.
Here's the python code which was used to verify:
There was a discussion on this Twilight Discord guild a long time ago, but it seems like the thread has been abandoned, so I am bringing this up again (as I was the original poster). As far as I remembered, there was a discussion about how Hikari simply drops events with unavailable field present and is true in GuildCreate (as seen here) and how that was not the preferred way to handle events in Twilight, which I thought was a fair point. However, Twilight can both remain this crucial differentiation and still keep every information about the event as it was received, without dropping any events, as well.
I've seen and tried both #2330 and #2361, which seems related. Pinning to their individual revisions, neither of them addresses this issue.
Summary
twilight-model
on the latest commit (f58b540
as of writing) deserialises these two distinct events:as the same object, namely
GuildCreate::Available(Guild { unavailable: false, .. })
. This behaviour should be undesirable, as information was lost about which event it was.Steps to reproduce
twilight-gateway
example here. Pintwilight-http
,twilight-gateway
andtwilight-model
to revisionf58b540
.ID1
.DISCORD_TOKEN="..." cargo run
, replacing...
with the bot's token.ID2
.Expected Behaviour
Upon the same time as "Bot is ready" appears in the log, the guild of ID
ID1
should become available, appearing in the logs as an event of a guild becoming available. This is a documented behaviour as scenario 1. Then, as the bot is added to another guild of IDID2
, it should appear in the logs as an event of joining a guild. These two events are distinct so the logs should reflect that.Actual Behaviour
The logs are as shown:
(Time information is redacted, but time
FFFFF0
andFFFFF1
should be negligibly near each other, andFFFFF2
should be different than the other two timestamps.)Due to how twilight deserialises these two distinct events, they both show up in the logs as the exact same thing as shown by the logs above, losing the information about whether which was originally sent.
Additional Information
Although not documented, it can be verified that the Discord Gateway differentiate these two events as the following:
GuildCreate
, if theunavailable
field is sent, then the guild became available.And this is exactly how Hikari, a python Discord API library, handle this: It separates the event into
GuildJoin
andGuildAvailable
, and uponShardReady
, the unavailable guilds become available withGuildAvailable
, and guild joins register asGuildJoin
, correctly differentiating the two. Here's the python code which was used to verify:There was a discussion on this Twilight Discord guild a long time ago, but it seems like the thread has been abandoned, so I am bringing this up again (as I was the original poster). As far as I remembered, there was a discussion about how Hikari simply drops events with
unavailable
field present and istrue
inGuildCreate
(as seen here) and how that was not the preferred way to handle events in Twilight, which I thought was a fair point. However, Twilight can both remain this crucial differentiation and still keep every information about the event as it was received, without dropping any events, as well.I've seen and tried both #2330 and #2361, which seems related. Pinning to their individual revisions, neither of them addresses this issue.