Skip to content

Releases: Kraigie/nostrum

0.8.0

01 Jun 07:36
v0.8.0
b6a91ff
Compare
Choose a tag to compare

Welcome to nostrum 0.8.0, codenamed "ignition on".

0_8_0_release

This release introduces full support for distributed caching and state, and
simplifies the existing cache behaviours by using a single shared interface for
reading the cache using Erlang's QLC module. Simply put, instead of having to
implement callbacks for every combination of functions that nostrum exposes (and
will expose) to the cache, a pluggable cache only needs to implement the
c:query_handle/0 callback. To fulfill this move, a few smaller breaking
changes have been performed. It is expected that these will be the last bigger
breaking changes done before the proper 1.0 release (at which point we will
follow semantic versioning).

Note that cache distribution was not the only missing piece to allow
distributing nostrum across multiple nodes (albeit the largest one). Gateway
event handling must be updated to prevent duplicate gateway connections,
proper distribution of shards over nodes must be implemented, and some other
improvements in regards to gateway connections with many shards must be
implemented, including support for persistent resume seq tokens.

Breaking changes

  • The current family of functions to read from the MemberCache have been
    replaced.
    • Functions affected:
      • MemberCache.get/1 -> MemberCache.fold/3-4
      • MemberCache.get_with_users/1 -> MemberCache.fold_with_users/3-4
      • MemberCache.by_user/1 -> MemberCache.fold_by_user/3-4
    • These changes were performed to support caches that need to perform some
      form of resource acquisition and release: ETS needs to call safe_fixtable
      for safe traversal and Mnesia needs to wrap calls in :mnesia.activity.
  • The following error returns have been renamed to a more generic version:
    • :channel_not_found -> :not_found
    • :presence_not_found -> :not_found
    • :id_not_found -> :not_found
    • :id_not_found_on_guild_lookup -> :not_found
    • :channel_not_found -> :not_found
  • The ChannelCache will no longer look up channels in the GuildCache if they
    were not found in the channel cache itself. A convenience function to fetch a
    channel from a guild (they are stored together) can be introduced to
    GuildCache if needed.
  • PresenceCache.get(user_id, guild_id) is now PresenceCache.get(guild_id, user_id), the same for PresenceCache.get!/2.
    • The reason behind this is that all "nested" caches use this form already,
      and having the arguments reversed may be confusing.

Deprecations

The following functions have been deprecated and will be removed in either
nostrum 0.9 or 1.0:

  • GuildCache.all/0
  • GuildCache.select_by/1
  • GuildCache.select/2

Features

  • Heavily improved support for querying the cache, via Erlang's QLC. This allows
    you to express strong queries in native Erlang list comprehension syntax
    without having to enumerate the entire cache by yourself, with the added bonus
    that it can automatically, at compile time, optimize your query to use indices
    and other improved traversal mechanisms on the backend you're using. For
    instance, the Mnesia member cache places an index on the guild_id field:
    queries involving this field are automatically optimized at compile time to
    utilize the index to provide for fast lookups. As an example, the following
    query is used in nosedrum as part of the member converter:
    find_by(RequestedGuildId, Name, Discriminator, MemberCache, UserCache) ->
      qlc:q([Member || {{GuildId, MemberId}, Member} <- MemberCache:query_handle(),
                       GuildId =:= RequestedGuildId,
                       {UserId, User} <- UserCache:query_handle(),
                       MemberId =:= UserId,
                       map_get(username, User)  =:= Name,
                       map_get(discriminator, User) =:= Discriminator]).
  • Support specifying a shard range to start.
    • Previously, you could either start a set number of shards, or tell nostrum
      to use the amount that Discord asked you to use.
    • A new third option is introduced, which expects a tuple in the form
      {lowest, highest, total}, where nostrum will start lowest..highest
      shards and inform Discord you have total shards in total.
    • This is useful for bots that have outgrown a single server and need to split
      their shards across multiple servers. However, see the changes below as
      well.
  • Distributed caching.
    • All Nostrum.Cache modules now have an Mnesia-based cache adapter that
      allows you to replicate and distribute the data across hosts, with the full
      power of Mnesia.
    • Larger bots can fragment their cache tables into smaller replicated cache
      tables and can thus distribute their bot without having to implement their
      own distributed caching system.
  • Distributed state.
    • As with distributed caching, Nostrum's internal state now also ships with
      Mnesia-based distributed adapters.
  • Do not require pluggable caches to implement multiple supervisor callbacks.
    Implementing child_spec is sufficient.

Fixes

  • Requeue requests that ran into a "retry later" up to 50 times.
    • This is enough to prevent any legitimate requests from being dropped, whilst
      still guarding against somebody going haywire on the ratelimiter.
  • Prevent a crash when retry_after was 0.

Documentation

  • Create documentation on how to use nostrum in a multi-node cluster.
  • Restructure the Pages tab to be more inline with which features you want to
    use.
  • Move pluggable cache modules down on the API reference list to not take up
    space from the regular cache APIs.
    • As this feature won't be needed by most bots, we don't need it to clutter up
      space for everybody.
  • Embed the consumer example into the Nostrum.Consumer moduledoc.
  • Add an "Internal modules" section on the API documentation for modules that
    are highly unlikely to be used by the regular user, but are still documented
    for completeness.

Internal changes

  • Add caching benchmarks.
  • Add propaganda assets to the VCS tree.

0.8.0-beta1

29 May 17:24
v0.8.0-beta1
7a9c858
Compare
Choose a tag to compare
0.8.0-beta1 Pre-release
Pre-release

nostrum 0.8.0-beta1

Welcome to nostrum 0.8.0, codenamed "ignition on".

This release introduces full support for distributed caching and state, and
simplifies the existing cache behaviours by using a single shared interface for
reading the cache using Erlang's QLC module. Simply put, instead of having to
implement callbacks for every combination of functions that nostrum exposes (and
will expose) to the cache, a pluggable cache only needs to implement the
c:query_handle/0 callback. To fulfill this move, a few smaller breaking
changes have been performed. It is expected that these will be the last bigger
breaking changes done before the proper 1.0 release (at which point we will
follow semantic versioning).

Note that cache distribution was not the only missing piece to allow
distributing nostrum across multiple nodes (albeit the largest one). Gateway
event handling must be updated to prevent duplicate gateway connections,
proper distribution of shards over nodes must be implemented, and some other
improvements in regards to gateway connections with many shards must be
implemented, including support for persistent resume seq tokens.

Breaking changes

  • The current family of functions to read from the MemberCache have been
    replaced.
    • Functions affected:
      • MemberCache.get/1 -> MemberCache.fold/3-4
      • MemberCache.get_with_users/1 -> MemberCache.fold_with_users/3-4
      • MemberCache.by_user/1 -> MemberCache.fold_by_user/3-4
    • These changes were performed to support caches that need to perform some
      form of resource acquisition and release: ETS needs to call safe_fixtable
      for safe traversal and Mnesia needs to wrap calls in :mnesia.activity.
  • The following error returns have been renamed to a more generic version:
    • :channel_not_found -> :not_found
    • :presence_not_found -> :not_found
    • :id_not_found -> :not_found
    • :id_not_found_on_guild_lookup -> :not_found
    • :channel_not_found -> :not_found
  • The ChannelCache will no longer look up channels in the GuildCache if they
    were not found in the channel cache itself. A convenience function to fetch a
    channel from a guild (they are stored together) can be introduced to
    GuildCache if needed.
  • PresenceCache.get(user_id, guild_id) is now PresenceCache.get(guild_id, user_id), the same for PresenceCache.get!/2.
    • The reason behind this is that all "nested" caches use this form already,
      and having the arguments reversed may be confusing.

Deprecations

The following functions have been deprecated and will be removed in either
nostrum 0.9 or 1.0:

  • GuildCache.all/0
  • GuildCache.select_by/1
  • GuildCache.select/2

Features

  • Heavily improved support for querying the cache, via Erlang's QLC. This allows
    you to express strong queries in native Erlang list comprehension syntax
    without having to enumerate the entire cache by yourself, with the added bonus
    that it can automatically, at compile time, optimize your query to use indices
    and other improved traversal mechanisms on the backend you're using. For
    instance, the Mnesia member cache places an index on the guild_id field:
    queries involving this field are automatically optimized at compile time to
    utilize the index to provide for fast lookups. As an example, the following
    query is used in nosedrum as part of the member converter:
    find_by(RequestedGuildId, Name, Discriminator, MemberCache, UserCache) ->
      qlc:q([Member || {{GuildId, MemberId}, Member} <- MemberCache:query_handle(),
                       GuildId =:= RequestedGuildId,
                       {UserId, User} <- UserCache:query_handle(),
                       MemberId =:= UserId,
                       map_get(username, User)  =:= Name,
                       map_get(discriminator, User) =:= Discriminator]).
  • Support specifying a shard range to start.
    • Previously, you could either start a set number of shards, or tell nostrum
      to use the amount that Discord asked you to use.
    • A new third option is introduced, which expects a tuple in the form
      {lowest, highest, total}, where nostrum will start lowest..highest
      shards and inform Discord you have total shards in total.
    • This is useful for bots that have outgrown a single server and need to split
      their shards across multiple servers. However, see the changes below as
      well.
  • Distributed caching.
    • All Nostrum.Cache modules now have an Mnesia-based cache adapter that
      allows you to replicate and distribute the data across hosts, with the full
      power of Mnesia.
    • Larger bots can fragment their cache tables into smaller replicated cache
      tables and can thus distribute their bot without having to implement their
      own distributed caching system.
  • Distributed state.
    • As with distributed caching, Nostrum's internal state now also ships with
      Mnesia-based distributed adapters.
  • Do not require pluggable caches to implement multiple supervisor callbacks.
    Implementing child_spec is sufficient.

Fixes

  • Requeue requests that ran into a "retry later" up to 50 times.
    • This is enough to prevent any legitimate requests from being dropped, whilst
      still guarding against somebody going haywire on the ratelimiter.
  • Prevent a crash when retry_after was 0.

Documentation

  • Create documentation on how to use nostrum in a multi-node cluster.
  • Restructure the Pages tab to be more inline with which features you want to
    use.
  • Move pluggable cache modules down on the API reference list to not take up
    space from the regular cache APIs.
    • As this feature won't be needed by most bots, we don't need it to clutter up
      space for everybody.
  • Embed the consumer example into the Nostrum.Consumer moduledoc.
  • Add an "Internal modules" section on the API documentation for modules that
    are highly unlikely to be used by the regular user, but are still documented
    for completeness.

Internal changes

  • Add caching benchmarks.
  • Add propaganda assets to the VCS tree.

0.8.0-alpha1

27 May 09:50
v0.8.0-alpha1
08dc94f
Compare
Choose a tag to compare
0.8.0-alpha1 Pre-release
Pre-release

nostrum 0.8.0-alpha1

Welcome to nostrum 0.8.0, codenamed "ignition on".

This release introduces full support for distributed caching and state, and
simplifies the existing cache behaviours by using a single shared interface for
reading the cache using Erlang's QLC module. Simply put, instead of having to
implement callbacks for every combination of functions that nostrum exposes (and
will expose) to the cache, a pluggable cache only needs to implement the
c:query_handle/0 callback. To fulfill this move, a few smaller breaking
changes have been performed. It is expected that these will be the last bigger
breaking changes done before the proper 1.0 release (at which point we will
follow semantic versioning).

Note that cache distribution was not the only missing piece to allow
distributing nostrum across multiple nodes (albeit the largest one). Gateway
event handling must be updated to prevent duplicate gateway connections,
proper distribution of shards over nodes must be implemented, and some other
improvements in regards to gateway connections with many shards must be
implemented, including support for persistent resume seq tokens.

Breaking changes

  • The current family of functions to read from the MemberCache have been
    replaced.
    • Functions affected:
      • MemberCache.get/1 -> MemberCache.fold/3-4
      • MemberCache.get_with_users/1 -> MemberCache.fold_with_users/3-4
      • MemberCache.by_user/1 -> MemberCache.fold_by_user/3-4
    • These changes were performed to support caches that need to perform some
      form of resource acquisition and release: ETS needs to call safe_fixtable
      for safe traversal and Mnesia needs to wrap calls in :mnesia.activity.
  • The following error returns have been renamed to a more generic version:
    • :channel_not_found -> :not_found
    • :presence_not_found -> :not_found
    • :id_not_found -> :not_found
    • :id_not_found_on_guild_lookup -> :not_found
    • :channel_not_found -> :not_found
  • The ChannelCache will no longer look up channels in the GuildCache if they
    were not found in the channel cache itself. A convenience function to fetch a
    channel from a guild (they are stored together) can be introduced to
    GuildCache if needed.
  • PresenceCache.get(user_id, guild_id) is now PresenceCache.get(guild_id, user_id), the same for PresenceCache.get!/2.
    • The reason behind this is that all "nested" caches use this form already,
      and having the arguments reversed may be confusing.

Deprecations

The following functions have been deprecated and will be removed in either
nostrum 0.9 or 1.0:

  • GuildCache.all/0
  • GuildCache.select_by/1
  • GuildCache.select/2

Features

  • Heavily improved support for querying the cache, via Erlang's QLC. This allows
    you to express strong queries in native Erlang list comprehension syntax
    without having to enumerate the entire cache by yourself, with the added bonus
    that it can automatically, at compile time, optimize your query to use indices
    and other improved traversal mechanisms on the backend you're using. For
    instance, the Mnesia member cache places an index on the guild_id field:
    queries involving this field are automatically optimized at compile time to
    utilize the index to provide for fast lookups. As an example, the following
    query is used in nosedrum as part of the member converter:
    find_by(RequestedGuildId, Name, Discriminator, MemberCache, UserCache) ->
      qlc:q([Member || {{GuildId, MemberId}, Member} <- MemberCache:query_handle(),
                       GuildId =:= RequestedGuildId,
                       {UserId, User} <- UserCache:query_handle(),
                       MemberId =:= UserId,
                       map_get(username, User)  =:= Name,
                       map_get(discriminator, User) =:= Discriminator]).
  • Support specifying a shard range to start.
    • Previously, you could either start a set number of shards, or tell nostrum
      to use the amount that Discord asked you to use.
    • A new third option is introduced, which expects a tuple in the form
      {lowest, highest, total}, where nostrum will start lowest..highest
      shards and inform Discord you have total shards in total.
    • This is useful for bots that have outgrown a single server and need to split
      their shards across multiple servers. However, see the changes below as
      well.
  • Distributed caching.
    • All Nostrum.Cache modules now have an Mnesia-based cache adapter that
      allows you to replicate and distribute the data across hosts, with the full
      power of Mnesia.
    • Larger bots can fragment their cache tables into smaller replicated cache
      tables and can thus distribute their bot without having to implement their
      own distributed caching system.
  • Distributed state.
    • As with distributed caching, Nostrum's internal state now also ships with
      Mnesia-based distributed adapters.
  • Do not require pluggable caches to implement multiple supervisor callbacks.
    Implementing child_spec is sufficient.

Fixes

  • Requeue requests that ran into a "retry later" up to 50 times.
    • This is enough to prevent any legitimate requests from being dropped, whilst
      still guarding against somebody going haywire on the ratelimiter.
  • Prevent a crash when retry_after was 0.

Documentation

  • Create documentation on how to use nostrum in a multi-node cluster.
  • Restructure the Pages tab to be more inline with which features you want to
    use.
  • Move pluggable cache modules down on the API reference list to not take up
    space from the regular cache APIs.
    • As this feature won't be needed by most bots, we don't need it to clutter up
      space for everybody.
  • Embed the consumer example into the Nostrum.Consumer moduledoc.
  • Add an "Internal modules" section on the API documentation for modules that
    are highly unlikely to be used by the regular user, but are still documented
    for completeness.

Internal changes

  • Add caching benchmarks.
  • Add propaganda assets to the VCS tree.

0.7.0

15 May 18:54
v0.7.0
337229d
Compare
Choose a tag to compare

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 t...
Read more

0.7.0-rc2

09 May 23:06
v0.7.0-rc2
2b51380
Compare
Choose a tag to compare
0.7.0-rc2 Pre-release
Pre-release

Changes since 0.7.0-rc1:

  • Add MemberCache.get_with_user/2
  • Handle unknown voice session close & reorganize voice code
  • Fix crash when trying to connect to voice when session pid isn't alive

Full release notes follow.


Welcome to nostrum 0.7.0, codenamed "launch preparations".

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 ...
Read more

0.7.0-rc1

07 May 19:14
v0.7.0-rc1
3a4d139
Compare
Choose a tag to compare
0.7.0-rc1 Pre-release
Pre-release

Test release for the upcoming 0.7.0 release. If possible, please test!
Full release notes follow.


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...
Read more

0.6.1

02 Aug 16:52
v0.6.1
ad5f911
Compare
Choose a tag to compare

nostrum 0.6.1

image

Welcome to nostrum 0.6.1, a small bugfix release addressing issues with token validation and typespecs.

Thanks to @Th3-M4jor and @cedeno for their contributions to this release!

Bugfixes

  • Support non-padded base64 user ID in Discord bot tokens
  • Fix dialyzer issues related to webhook functions

0.6.0

01 Jun 21:30
v0.6.0
60541c2
Compare
Choose a tag to compare

nostrum_06_cropped

Welcome to nostrum 0.6.0, bringing you message content intents, API v10, voice
improvements, new permissions, and more!

A huge thanks to @Th3-M4jor, @BrandtHill and @daskycodes for their contributions
to this release!

Breaking changes

  • If your bot relies on message content, you will need to add :message_content
    in your :gateway_intents configuration setting.
  • Voice listening now automatically parses RTP and Opus. You can pass false as
    the third argument to listen/2-3 to reuse the previous behaviour.
  • The :manage_emojis permission was renamed to :manage_emojis_and_stickers

Functionality

  • API v10
    • Added the :message_content intent
    • Added the following permissions:
      • Guild
        • :view_guild_insights
        • :use_application_commands
        • :moderate_members
      • Text
        • :use_external_stickers
      • Voice
        • :stream
        • :request_to_speak
        • :manage_events
        • :use_embedded_activities
  • Interactions
    • Add the :locale and :guild_locale fields
  • Voice
    • Add asynchronous listening to voice packet events via
      Nostrum.Voice.start_listen_async/1
    • Add a ssrc map (see t:Nostrum.Voice.VoiceWSState.ssrc_map/0 and
      Nostrum.Voice.get_ssrc_map/1 for details)
    • Automatic parsing of RTP and Opus (see breaking changes above)
    • Add a function to interleave silence within spaced RTP packets (see
      Nostrum.Voice.pad_opus/1 for details)
    • Track the last played URL for a guild, see Nostrum.Voice.get_current_url/1
    • Add plenty of types
  • Caching
    • Add a NoOp guild cache for effectively disabling the guild cache
  • Garbage collect ratelimiter buckets that have a reset time more than 1 hour
    ago
  • Add Nostrum.Token for verifying Discord Bot tokens
  • Rework message handling with attachments (the multipart-generating code)
  • Allow mime version 1 and 2

Bugfixes

  • Voice
    • Fix a bug with generating ogg pages with incorrect page_segments value
    • Properly skip over RTP header extension
    • Safely close ports on teardown
    • Fix bug where playing new audio immediately after stopping one would
      sometimes result in rogue watchdog timer cancelling new audio
  • Fix ratelimiting of reaction and webhook API endpoints
  • Fix check_token/1 to work with newer token formats
  • Fix Message.to_url/1 breaking on numeric IDs
  • Fix an improper call to Util.cast in the Integration and
    Integration.Application structs
  • Handle unexpected nofin responses in the ratelimiter. Please report these
    cases

Documentation

  • Document required :message_content intent if relying on content for e.g.
    commands
  • Update the audio player example to use application commands
  • Correct a few typos in the Api module

v0.5.1

10 Mar 21:22
v0.5.1
e7e6505
Compare
Choose a tag to compare

Introducing nostrum 0.5.1 "I don't pick favourites", named after Craig's
favourite cat! The release brings support for threads, a decoder for incoming
voice data, integration events, modal submit interactions, and a bunch more
goodies!

A huge thanks to @Th3-M4jor, @BrandtHill, @frm and @kianmeng for their
contributions to this release!

If you're using streamlink for voice streaming, you may need to update it to >=
3.0 for this release, in order for the stream URL feature to work properly.

Functionality

  • Threads
    • Added support for threads:
      • Added Nostrum.Api functions for working with threads
      • Add thread events in the consumer
      • Added struct definitions for thread events
  • Voice
    • Use streamlink directly for determining stream URLs
    • Add support for persisting playback across channels
    • Remove dependency to porcelain in favour of native ports
    • Add opus packet decoding, allowing to save received audio as .ogg files
  • Interactions
    • Add support for modal submit interactions and the associated text input type
  • Integrations
    • Expand stub integration events to proper types
    • Document integration events & cast them to event structs
  • Update to API v9

Documentation

  • Fix a bunch of typos

v0.5.0

18 Feb 21:53
v0.5.0
954d697
Compare
Choose a tag to compare

Enter nostrum 0.5: Raw voice, fleshed-out application command support, pluggable
caches, stickers, typed events, scheduled events, did someone say "switch
websocket library again"?

Thanks to @jb3, @Th3-M4jor, @BrandtHill, @bdanklin, @RealVidy, and the many more
people who contributed to the release with pull requests, bug reports, feature
suggestions, or just by being part of the development channel. A full list of
our contributors, minus the mention spam, is at the bottom. Finally, thanks for
the author of this tag for turning what should have been a day project into a
one and a half year long incursion.

Breaking changes

  • The following options for allowed_mentions have been renamed:
    • :user -> :users
    • {:user, list} -> {:users, list}
    • {:role, list} -> {:roles, list}
  • The type value for permission overwrites has changed:
    • "role" -> 0
    • "member" -> 1
  • Binary map keys coming from Discord that appear to be snowflakes will be
    parsed as integers to prevent inconsistencies in e.g. interaction data
    payloads
  • Parse datetimes to datetime objects instead of keeping raw strings
  • Require Elixir 1.11

Deprecations

  • The :file option for Nostrum.Api.execute_webhook/3-4 was renamed to
    :files and expects a list of files instead of a single file. :file will
    keep working for the time being, but you are advised to use :files instead.

Functionality

  • Application commands
    • Allow adding attachments to an interaction response
    • Support for retrieving and editing application command permissions
    • Add support for editing and deleting interaction responses
    • Add application command bulk overwrite support via
      Nostrum.Api.bulk_overwrite_global_application_commands/1-2 and
      Nostrum.Api.bulk_overwrite_guild_application_commands/2-3
    • Add bangified methods for interaction response functions
    • Add structs for building and responding to interactions and working with
      message components:
      • Nostrum.Struct.ApplicationCommand
      • Nostrum.Struct.ApplicationCommandInteractionDataResolved
      • Nostrum.Struct.Component
      • Nostrum.Struct.Component.ActionRow
      • Nostrum.Struct.Component.Button
      • Nostrum.Struct.Component.Option
      • Nostrum.Struct.Component.SelectMenu
      • Nostrum.Struct.Message.Component
    • Update the following structs relevant to building and responding to interactions:
      • Nostrum.Struct.ApplicationCommandInteractionData
      • Nostrum.Struct.ApplicationCommandInteractionDataOption
      • Nostrum.Struct.Interaction
      • Nostrum.Struct.Message
  • Miscellaneous
    • Allow for sending multiple files in a single message
    • Allow retrieval of a guild ban for a single user
    • Add sticker support via sticker attributes and
      Nostrum.Struct.Message.Sticker
    • Add support for specifying an audit log reason in
      Nostrum.Api.modify_guild_member/4
    • Add webhook message editing support via Nostrum.Api.edit_webhook_message/4
    • Add Nostrum.Struct.Guild.Member.top_role/2 for retrieving the topmost role
      of a member
    • Add Nostrum.Struct.Message.to_url/1 for retrieving a message link for a
      message
    • Move to Discord API V8 (both in the REST API and Gateway)
  • Channels
    • Add types for the following channel types:
      • News & store channels
      • Threads (public, private, news)
      • Stage voice channel
  • Documentation updates
    • Overhaul of channel documentation (see Nostrum.Struct.Channel), which
      now gives a great overview for the jungle of Discord's channel types
    • Document Nostrum.Struct.Message.type values
    • Fix all documentation build warnings
    • Move to ex_doc version 0.28
  • Pluggable caching
    • Customize the way nostrum caches objects from Discord
    • By default, nostrum will cache objects in ETS tables
      • For guilds, we previously used GenServers
    • See the "State" documentation page for more details
  • Typed events
    • The following events will now be returned in special structs:
      • CHANNEL_PINS_UPDATE
      • GUILD_BAN_ADD
      • GUILD_BAN_REMOVE
      • GUILD_INTEGRATIONS_UPDATE
      • MESSAGE_REACTION_ADD
      • MESSAGE_REACTION_REMOVE
      • MESSAGE_REACTION_REMOVE_ALL
      • MESSAGE_REACTION_REMOVE_EMOJI
      • READY
      • TYPING_START
      • VOICE_STATE_UPDATE
      • VOICE_SERVER_UPDATE
  • Voice
    • Support for streamlink for livestreaming audio
    • The new VOICE_READY event, fired when the bot is ready for sending audio in
      a voice channel
    • Lots of documentation changes
    • Add support for sending raw voice packets ("Bring Your Own Encoder")
    • New fine-tuning options for voice playback
      • Configure the start position
      • Configure the duration to play
      • Output volume configuration
      • Add support for applying filters to audio
      • Realtime switch (ffmpeg-specific) fine-tuning
    • New fine-tuning options for voice in general
      • Configure the timeout within which the bot must begin generating audio
      • Configure how many opus frames to send at a time while playing audio
      • Configure whether nostrum should automatically connect to voice websockets
        when joining voice channels
    • Remake session on errno 4006
    • Learn more about the changes on the "Voice" documentation page
  • Scheduled events
    • Add API methods for CRUD of scheduled events along with getting users subscribed to an
      event
    • Add the following gateway events:
      • GUILD_SCHEDULED_EVENT_CREATE
      • GUILD_SCHEDULED_EVENT_UPDATE
      • GUILD_SCHEDULED_EVENT_DELETE
      • GUILD_SCHEDULED_EVENT_USER_ADD
      • GUILD_SCHEDULED_EVENT_USER_REMOVE
    • Add the guild_scheduled_events intent

Usability

  • Dialyzer will now catch errors with missing parameters in
    Nostrum.Api.execute_webhook/3-4
  • num_shard: :auto is now used by default

Internals

  • We have switched websocket libraries again!
    • Just kidding. We have switched our HTTP client to :gun, which we already use
      for websocket, which reduced our dependency footprint.
    • If you see a HTTP multipart request containing KraigieNostrumCat_ as the
      boundary, that's us!
  • Dependency updates, ex_doc among others
  • Fail CI fast if one job fails

Contributors

Thanks to these wonderful folks who have contributed to this release:

  • Alex Hincu
  • Andris0
  • Awlexus
  • Bailey Dickens
  • Benjamin Danklin
  • Brandt Hill
  • Craig Dazey
  • Joe Banks
  • Johannes Christ
  • Khionu Sybiern
  • Kraigie
  • Michael Mitchell
  • PixeL
  • RealVidy
  • The Major
  • Vidy
  • panoramix360
  • wkrp