Skip to content

0.7.0

Compare
Choose a tag to compare
@jchristgit jchristgit released this 15 May 18:54
· 401 commits to master since this release
v0.7.0
337229d

Welcome to nostrum 0.7.0, codenamed "launch preparations".

nostrum_0_7

This release brings you support for automod and forum channels, helps you with
navigating through Discord's numbering schemes with the new modules under
Nostrum.Constants, allows you to retrieve audit log entries over the gateway,
and much more. For the full list of features and bugfixes, see below.

This release contains breaking changes in regards to member caching. If you
want the short version, scroll down to the "Breaking changes" section. This
part will document the changes and their reasoning.

Two main breaking changes have been performed, that are almost guaranteed to
cause breakage on your bot:

  • Members are no longer stored on the guild struct, and by extension, the guild
    cache. The new Nostrum.Cache.MemberCache handles caching guild members, and
    has functions that allow you to easily retrieve members for a guild.
  • Users are no longer stored on the member struct. The MemberCache contains a
    convenience function, Nostrum.Cache.MemberCache.get_with_users/1, that will
    perform a :qlc join between the member and user cache.

For the join function to work, the callback c:qlc_handle/0 has been added to
both Nostrum.Cache.MemberCache and Nostrum.Cache.UserCache. It is expected
that more functionality will be built on top of :qlc in the future,
especially as nostrum approaches its 1.0 release, so it's heavily recommended
to add this callback for any custom consumers. The Erlang documentation
explains how to implement a QLC
table
for
any custom caches you may have.

Why were these changes done? Nostrum previously struggled when working with
large guilds. With the ETS-based guild cache, updating a member would mean
fetching the entire guild object from the cache, for ETS, this means making a
full copy of the entire struct. While probably unproblematic for most usecases,
running Nostrum with request_guild_members: true on large guilds would cause
memory usage to skyrocket for a brief period at the start while Nostrum
struggled to gobble all of the users into the cache. Unfortunately, fixing this
was not possible without breaking the API. The :user field was removed as the
members change will already require changes on your side, and nostrum
previously did not update users on members properly, causing stale data. We
want the caches to work independently from each other, so this seemed the
proper solution. If you want to have some rough idea of how to change it, see
this commit on
bolt
.

Due to the new separation and removal of duplicated user data, nostrum is now
lighter on memory. The "Breaking changes" section below contains a complete
listing of these changes. If you use a third-party command library such as
:nosedrum, you will likely need to upgrade those as well.

Migration guide

For the breaking changes mentioned above, the following should serve as a
guideline to the full list of breaking changes in the section below:

  • When retrieving a member from a guild, instead of using
    GuildCache.get(guild_id) or friends and then looking it up from there, use
    MemberCache.get(guild_id, user_id).
  • When searching guild members, instead of using Enum.find(guild.members, ...), use MemberCache.get(guild.id) |> Enum.find. The new cache functions
    are implemented as streams and are very light on memory.
  • If you absolutely need the user object of a member (and not just the ID), use
    UserCache.get(member.user_id) to retrieve it.
  • If you want the full rocket-engine power for searching members, use Erlang's
    :qlc and MemberCache.qlc_handle(). Note that the current ETS cache is
    optimized for lookup by user and guild ID. You can also use this for the
    UserCache.

If you had some previous functionality in your bot that is problematic to
implement with these new changes, please open an
issue
.

Breaking changes

  • Introduce the new Nostrum.Cache.MemberCache
    • Nostrum ships an ETS-based member cache and uses it by default
  • Remove the :members field from Nostrum.Struct.Guild
    • These are now stored separately in Nostrum.Cache.MemberCache
    • Use Nostrum.Cache.MemberCache.get(guild_id) to retrieve guild members
    • The following Nostrum.Cache.GuildCache callbacks have been removed:
      • c:member_add/2
      • c:member_remove/2
      • c:member_update/2
      • c:member_chunk/2
    • The following Nostrum.Cache.GuildCache callbacks have been added:
      • c:member_count_up/1
      • c:member_count_down/1
  • Added the following callbacks to Nostrum.Cache.UserCache
    • c:qlc_handle/1
  • Remove the :user field from Nostrum.Struct.Guild.Member
    • The :user_id field can be used to find the matching user
  • Replace GenStage with :pg
    • Code with use Nostrum.Consumer can remain unchanged
    • Events are now distributed to all subscribers instead of round-robin fashion
      • This means that setups that deployed multiple replicas of their consumer
        per scheduler or similar must be updated to only start a single
        consumer
      • Nostrum.Consumer will automatically handle events in spawned processes
        for parallelism
    • See Nostrum.ConsumerGroup for detailed information
  • The :joined_at member field is now a unix timestamp instead of a raw string
    • See t:Nostrum.Struct.Guild.Member.joined_at/0
    • If this field was unset, it will continue to be nil

Functionality

  • Added a dedicated member cache
    • See Nostrum.Cache.MemberCache
    • More details can be found in the breaking changes above
  • Added support for AutoMod (The Major)
    • Update and receive events for Discord's Great Spam Wall.
    • The following functions have been added:
      • Nostrum.Api.get_guild_auto_moderation_rules/1
      • Nostrum.Api.get_guild_auto_moderation_rule/2
      • Nostrum.Api.create_guild_auto_moderation_rule/2
      • Nostrum.Api.modify_guild_auto_moderation_rule/3
      • Nostrum.Api.delete_guild_auto_moderation_rule/2
    • The following events can now be received in your consumer:
      • t:Nostrum.Consumer.auto_moderation_rule_create/0
      • t:Nostrum.Consumer.auto_moderation_rule_delete/0
      • t:Nostrum.Consumer.auto_moderation_rule_update/0
      • t:Nostrum.Consumer.auto_moderation_rule_execute/0
    • The following event structs have been added:
      • Nostrum.Struct.Event.AutoModerationRuleExecute
    • The following shard intents have been added:
      • :auto_moderation_configuration
      • :auto_moderation_execution
    • The following structs have been added:
      • Nostrum.Struct.AutoModerationRule
      • Nostrum.Struct.AutoModerationRule.Action
      • Nostrum.Struct.AutoModerationRule.ActionMetadata
      • Nostrum.Struct.AutoModerationRule.TriggerMetadata
  • Added support for forum channels (The Major)
    • Build your own forum and keep it tidy.
    • The following functions have been added:
      • Nostrum.Api.start_thread_in_forum_channel/2-3
    • The following changes were performed on Nostrum.Struct.Channel:
      • The :type may now be 15 to represent a forum channel
      • The following types and associated fields were added:
        • t:Nostrum.Struct.Channel.default_thread_rate_limit_per_user/0
        • t:Nostrum.Struct.Channel.forum_tag/0
        • t:Nostrum.Struct.Channel.applied_tags/0
        • t:Nostrum.Struct.Channel.default_reaction_emoji/0
      • The :thread_metadata field has been extended by the following fields:
        • :invitable
        • :create_timestamp
      • The type t:Nostrum.Struct.Channel.guild_forum_channel/0 has been added
  • Added constants for Discord's arbitrary numbers (Jiří Vrba)
    • The following modules have been added:
      • Nostrum.Constants.ApplicationCommandOptionType
      • Nostrum.Constants.ApplicationCommandPermissionType
      • Nostrum.Constants.ApplicationCommandType
      • Nostrum.Constants.ButtonStyle
      • Nostrum.Constants.ChannelType
      • Nostrum.Constants.ComponentType
      • Nostrum.Constants.InteractionCallbackType
      • Nostrum.Constants.InteractionType
      • Nostrum.Constants.TextInputStyle
      • Nostrum.Constants.WebhookType
  • Added the audit log entry gateway event (Leastrio)
    • The following struct has been added:
      • Nostrum.Struct.Guild.AuditLogEntry
    • The following consumer event has been added:
      • t:Nostrum.Consumer.guild_audit_log_entry_create/0
  • Added support for retrieving webhook messages (Awlex)
    • See Nostrum.Api.get_webhook_message/2
  • Added support for role icons (Joe Sweeney)
    • See t:Nostrum.Struct.Guild.Role.icon/0
  • Add attachments to interaction data (Jakob Bowyer)
    • See t:Nostrum.Struct.ApplicationCommandInteractionDataResolved.attachments/0
  • Added support for retrieving the original interaction response (Awlex)
    • See Nostrum.Api.get_original_interaction_response/1
  • Add param support for emoji API calls (Brandt Hill)
    • See Nostrum.Api.get_reactions/3-4
  • Added support for role icon emojis (Joe Sweeney)
    • See t:Nostrum.Struct.Guild.Role.unicode_emoji/0
  • Support inline event awaiting
    • See Nostrum.ConsumerGroup for details
  • Implement gateway websocket message flow control
    • This prevents overwhelming the shard process with messages before we can
      process them
  • Log READY event at INFO log level as well
    • Previously, only IDENTIFYING was logged, which could lead to believe that
      the bot is stuck in startup

Changes

  • Sleep out ratelimiter buckets on the client instead of spawning tasks
  • Make allowed mentions a proper type
    • See t:Nostrum.Api.allowed_mentions/0
  • Add a few more unused atoms to prevent casting warnings
  • Simplify the Nostrum.Cache.ChannelCache behaviour
    • Implement get/1 with a message directly in the dispatcher
    • Implement bangified get!/1 directly in the dispatcher
    • Deprecate c:lookup/1 and its dispatch function

Bugfixes

  • Accept voice RTP packets without header (Ushitora Anqou)
  • Fix voice session not closing error (Brandt Hill)
  • Handle unknown voice session close & reorganize voice code (Brandt Hill)
  • Fix button component status (Awlex)
  • Fix crash when trying to connect to voice when session pid isn't alive
    (Brandt Hill)
  • Correct typecasting in list_guild_threads/1 (Zach Daniel)
  • Fix throwing up for undocumented voice gateway events (Brandt Hill)
  • Stop crashing on receiving API responses after timeout
  • Prevent crashing the guild cache without the guilds intent

Documentation

  • Emphasize message content intent warning in README (Matthew Villwock)
  • Document new constants for Discord's arbitrary numbers (Jiří Vrba)
  • Improve grammar for application command documentation (Roy Li)
  • Fix broken syntax highlighting in some examples
  • Correct documentation for allowed mentions in webhook messages
  • Document attachment editing quirk in API v10
  • Clarify that the ChannelCache is only for off-guild channels
  • Document that the README is for the master branch
    • Link both release and development documentations
  • Build master branch documentation on Erlang/OTP 25 and Elixir 1.14
  • Improve sidebar sections

Internal changes

  • Refactor voice session close (Brandt Hill)
  • Silence warnings from youtube-dl (aukuste)
  • Replace blocking voice port close call with cast (Brandt Hill)
  • Refactor voice session restart on invalid session (Brandt Hill)
  • Use DynamicSupervisor for voice sessions (Brandt Hill)
  • Cleanly separate the doc build and source file folders
  • Update :gun to the official stable 2.0 release
    • Yes, really.
    • Thanks to bdanklin for publishing :remedy_gun and :remedy_cowlib
      allowing us to make releases with :gun before.
  • Add Erlang/OTP 25 and Elixir 1.14 to our test matrix
  • Remove the unused Nostrum.Cache.Mapping.ShardPidNum module
  • Lint on the latest and greatest Elixir and OTP only
  • Simplify await_up logic
  • Run dialyzer in CI
  • Fix deprecation warning associated with use Bitwise