- Fixed bug in Guild:setOwner
- Fixed nickname not being cleared from member objects
- Minor optimization in
printf
- Added token check to socket reconnection
- Fixed bug when setting client nickname via Member
- Added default JSON table for non-JSON HTTP responses
- Added checks for invalid client options
- Restored fixed creationix/coro dependency versions
- Extensions added:
string.randomfor generating random stringstring.split2for splitting strings by pattern [@FiniteReality]
- Implemented automatic gateway sharding
- Multiple shards are automatically spawned on startup according to the Discord-recommended amount
- Added a
shardReadyevent that fires as each shard finishes loading with a shard ID as its argument - Shard ID is also now an argument for the
resumedandheartbeatevents Client.shardCountandGuild.shardIdare accessible properties
- Overhauled token parsing and login handling:
- Tokens can now optionally be prefixed with
Bot - Tokens are validated before establishing a gateway connection; invalid tokens are rejected with an error
- Attempts to connect or reconnect to the gateway are no longer pcall'd
- To simplify
READYhandling, failed loading of guild chunk or sync payloads will result inreadynever firing instead of timing out - Added support for compressed gateway payloads (enabled by default)
- Replaced
gateway.cachewithgateway.json
- Tokens can now optionally be prefixed with
- Member conveniences:
- Added
User.mutualGuildsiterator - Added
Member.colorproperty - Added
Member:hasRoleandMember:hasRolesmethods - Added
Member:addRoleandMember:removeRolemethods - Added member cache accessors to
GuildVoiceChannelclass - Improved
User:getMembershipby reducing unnecessary HTTP requests
- Added
- Other changes:
- Optimized classes to be more memory efficient
- Minor optimizations in
TextChannel:sendMessage - Minor HTTP request optimizations
- Removed member check from
PRESENCE_UPDATEhandler - Fixed functions not explicitly returning
nilin some cases - Added default audio library names which can allow for automatic loading of libopus.so and libsodium.so on POSIX systems or opus.dll and sodium.dll on Windows. (Call
loadOpusorloadSodiumwithout arguments to use the defaults) - Fixed a missing parameter in the sodium decrypt function (not currently used by Discordia)
- Event handler optimizations
- If an uncached guild, channel, member, or role is encountered on their respective
UPDATEorDELETEevents, an object is now created and cached from the event payload instead of throwing a warning. - Events that parse a text channel ID are now more performant; the channel is found by using an channel map instead of by iterating over guilds.
- If an uncached guild, channel, member, or role is encountered on their respective
- Token parsing on login was improved
- Tokens are no longer prepended with
BotonREADY. Tokens are tested against a REST endpoint (/users/@me), and are prepended withBotonly if necessary. - If an invalid token is provided, the library will throw an error instead of entering a connect/disconnect loop.
- Tokens are no longer prepended with
- Opus encoder fix
- The encode method now expects an explicitly defined PCM length instead of one implicitly defined from the input table.
- This should fix a segmentation fault issue which apparently was a result of passing a size that is too small.
- Fixed an oversight where the positional return value of
string.unpackwas passed to the opus encoder for FFmpeg streams.
- Message enhancements
- Deprecated
TextChannel:sendMessage(content, mentions, tts)format TextChannel:sendMessage(content)is now the suggested format, wherecontentis a string or table. Table properties are:content: raw content stringmentions: mentionable object or table of mentionable objectstts: boolean indicating whether the message is TTSnonce: unique message identifierfile: relative or absolute path to file for attachmentfilename: custom name to use for attachment (not required)embed: table of message embed data
- File attachments made possible by multipart/form-data implementation [@PurgePJ]
- Added
nonceandoldContentproperties toMessageclass - Added
attachments,embeds,attachment, andembedproperties toMessageclass. All are exposed as raw Lua tables with original Discord formatting. - Added
reactionAddUncachedandreactionRemoveUncachedevents for when reactions are added/removed to messages that are uncached. A raw data table is passed as the only argument.
- Deprecated
- Added support for larger avatars and animated Nitro avatars
User:getAvatar(size)can be used for custom sizesgiffiles are automatically returned if the avatar is animatedpngis still used for static avatars
- Other changes:
- Removed unnecessary fields from
PATCH /users/@merequest - Added
isPlaying,isPaused, andplayTimeproperties toVoiceConnectionclass
- Removed unnecessary fields from
- Added package metadata to main
discordiamodule - Reduced timeout on voice channel join from 10 to 5 seconds
- Fixed an overflow when writing the maximum least-significant byte to a buffer
- Fixed an issue that caused a crash after failing to join a voice channel
- Added a Clock utility class (not used by the library)
- Voice optimizations
- Fixed issue where PermissionOverwrite tostring value was not properly formatted
- Voice tweaks
- Moved encryption mode to constants module
- pcall'd FFmpeg handle closings to avoid rare nil error
- Some minor optimizations
- Implemented voice-send features
- Streaming of PCM data from strings, tables, generators, or an FFmpeg process is now possible
- Implemented
VoiceManager,VoiceConnection,VoiceSocket,AudioStream, andFFmpegPipeclasses - Implemented a re-written version of Luvit's
Bufferclass - Implemented
libopusandlibsodiumbindings via LuaJIT FFI VOICE_SERVER_UPDATEis now handledMember.voiceChannelis now an accessible and mutable propertyGuild.connectionandGuildVoiceChannel.connectionis now an accessible property- Added
GuildVoiceChanneljoinandleavemethods - Added
creationix/coro-spawndependency - Other
- Added optional patterns to string pad extensions
- Added
pauseandresumemethods forStopwatch - Outgoing gateway payloads are now coroutine-wrapped
- Fixed gateway reconnection bug
- Implemented emoji features
- Added Emoji and Reaction classes
- Added message reaction methods
addReaction,removeReaction,clearReactions,getReactionUsers,getReactions
- Added handling of message reaction and emoji events
reactionAdd,reactionRemove,emojisUpdate
- Emoji are formally cached per guild
- Reactions are stored per message, but are not formally cached
- Fixed issue where PermissionOverwrites for members were not named
- Added more standard library extensions:
table.slice,string.startswith,string.endswith,string.levenshtein
-
General
- All mentions of server or Server were changed to guild or Guild to maintain consistency with internal Discord nomenclature
- Methods that use the REST API and that previously returned nothing now return a boolean to indicate whether the call was successful
- Discord-compliant ratelimiting has been implemented
- User handling has been changed slightly:
Userobjects are now cached once perClientinstead of per everyPrivateChannelandGuild- The
Memberclass now wraps theUserclass instead of extending it - To get a user's
Memberobject, useUser:getMembership(guild) - A member's
Userobject is accessed viaMember.user - Message authors, channel recipients, and invite inviters are always
Userobjects - Guild owners and members are always
Memberobjects
utilswas removed from the maindiscordiamodule and has been replaced by individual utility classesWarningandErrorclasses were removed in favor of events- Gateway disconnects, nil values on events, and HTTP errors are now handled more gracefully
- All modules relevant to the
Clientclass were refactored and moved with it into aclientfolder:Clientnow extends a custom version of Luvit's built-inEmitter- Client instances are initialized using
discordia.Client()instead ofdiscordia.Client:new() - A table of options can be passed to the client initializer. Currently supported options are:
routeDelay: minimum time to wait between requests per-route (default: 300 ms)globalDelay: minimum time to wait between requests globally after a global 429 (default: 10 ms)messageLimit: limit to the number of cached messages per channel (default: 100)largeThreshold: limit to how many members are initially fetched per-guild on start-up (default: 100)fetchMembers: whether to fetch all members for all guilds (default: false)autoReconnect: whether to attempt to reconnect after an unexpected gateway disconnection (default: true)
- Client instances are initialized using
endpointswas changed toAPIeventswas changed toEventHandlerWebSocketwas changed toSocket
- Discord objects are now stored in custom
Cacheobjects instead of pure Lua tables - Many iterators were added to help with accessing cached objects or methods that used to return a table
- The entire class system was overhauled
- Internally used properties and methods are now prefixed with an underscore to indicate their protected status
- Getter and setter properties and methods have been added.
- For every public property that can be accessed/mutated, there is an associated get/set method
-- these lines examples are equivalent local name = guild.name local name = guild:getName()
-- these lines examples are equivalent guild.name = "foo" guild:setName("foo")
- Objects that have caches have a variety of get and find methods for accessing those caches. For example:
guild:getRoles()orguild.roles- returns an iterator for all roles in the guildguild:getRoleCount()orguild.roleCount- returns the number of roles cachedguild:getRole(id)- returns the role with the given Snowflake IDguild:getRole(key, value)- returns the first found role matching a key, value pairguild:getRoles(key, value)- returns an iterator for all roles matching the key, value pairguild:findRole(predicate)- returns the first found role that makes the predicate trueguild:findRoles(predicate)- returns an iterator for all roles that makes the predicate true
-- pre-1.0 code for _, role in pairs(guild.roles) do print(role) end
-- 1.0 code ... for role in guild.roles do print(role) end for role in guild:getRoles() do print(role) end
-
Events
- Event handling was made more reliable by using the new
Cacheobjects - Attempts to access uncached objects are now caught, and warnings are printed to the console
- Guild sync was implemented for non-bot accounts
serverCreatewas renamed/split intoguildCreate,guildAvailable, andguildCreateUnavailableserverDeletewas renamed/split intoguildDeleteandguildUnavailablemessageAcknowledgeandmembersChunkwere removedmemberBanandmemberUnbanwere renamed touserBananduserUnbanand now provide aUserobject instead of aMemberobjectvoiceJoinandVoiceLeavewere renamed/split intoVoiceChannel[Join|Leave]andvoice[Connected|Disconnect]typingStartnow has a timestamp as a third argumentmessageUpdateUncachedandmessageDeleteUncachedevents were added for uncached message eventswarninganderrorevents were addedheartbeatevent was added with event sequence and roundtrip latency arguments
- Event handling was made more reliable by using the new
-
New Classes
API- Adds a layer of abstraction between Discord's REST API and Discordia's object oriented APIContainer- Base object used to store Discord objectsCache- Data structure used to store and accessContainerobjectsEmitter- A simplified re-write of Luvit's built-in event emitterMutex- Extension ofDequethat is used by theAPIclass to throttle HTTP requestsOrderedCache- Extension ofCachethat maintains the order of objects as a doubly-linked listStopwatch- Used to measure elapsed time with nanosecond precisionPermissionOverwrite- Extension ofSnowflakethat maintains per-channel permissions
-
For other API changes, please consult the Discordia wiki.
- Fixed issue where presences were applied to offline members on guild creation
- Fixed issue where roles where not properly being applied by Member:setRoles method
- Fixed issue where mentioned object would be nil
- Fixed issue with UTC time parsing
- Updated secure-socket dependency to version 0.1.4
- Member:setRoles now accepts a table of roles instead of IDs
- Tweaked internal Member updating
- Mentions are now ignored in private/direct messages
- Fixed issue where private message author was always the channel recipient
- Fixed erroneous private message parenting for User:sendMessage
- Partial restoration of class overhaul for critical fix
- Reverted class overhaul due to complicated bugs
- Added API client class (not yet exposed)
- Updated class constructor
- Reduced memory footprint by 30 to 40%
- Added isInstanceOf utility function
- Equality operator now correctly considers type
- Fixes an issue where Server == defaultChannel or defaultRole was true
- Fixed regression due to Message.channelId removal
- Added User object fallback for member[Ban/Unban]
- Added local datetime to Error/Warning output
- Fixed critical issue where client would not recognize a resumed connection
- Added "0x" to Color:toHex() output
- Added Permissions:toHex() method
- Fixed issue where server owner was nil
- Server.joinedAt is now a Unix timestamp
- utils.dateToTime and resulting timestamps now support milliseconds
- Fixed critical issue with lit package metadata
- Added Member:kick() overload method
- table.reverse now reverses a table in place
- Reorganized directories
- Implemented basic Permissions handling
- Added abstract Channel superclass for TextChannel and ServerChannel
- Expanded Role features
- Member.roles is now parsed into a table of Role objects
- User.name is now the User's display name: Either User.username by default, or User.nickname if one exists
- Other Chanegs
- Added custom delimiter to string.split
- Overhauled WebSocket reconnection process
- Changed mentions iterator from ipairs to pairs
- Default argument for TextChannel:getMessageHistory changed from 50 to 1
- Removed redundant channelId from Message class
- Bug Fixes
- Fixed issue when trying to access nil invites or bans tables
- Fixed issue where handleWebSocketDisconnect was improperly called
- Minor refactoring of token caching
- Overhauled WebSocket keep alive process
- Fixed issue where Server.defaultRole was nil
- Fixed UTC issue with dateToTime utility
- Added utility for converting UTC datetime string to Unix timestamp
- Message timestamps and Message joinedAt is now a Unix timestamp
- messageUpdate is no longer fired for non-existing messages
- Fixed @everyone mention crash
- Critical: Removed code that accesses Server.memberCount
- TextChannel improvements
- Added adjustable limit to getMessageHistory()
- Reimplemented broadcastTyping() from an old version
- Implemented bulkDelete()
- Removed memberCount from Server class
- Added utility for converting snowflake ID to creation time and date
- Added string.totable
- Color class changes:
- RGB values are now rounded
- Added add, sub, mul, and div operators
- Added error codes to HTTP warnings and errors
- Client:setNickname now uses proper endpoint
- Fixed issue where nickname would not update
- Fixed issue where deleting private channels crashed library
- Added table.randompair and table.randomipair
- Added standard library extensions (printf, string, table, and math)
- Implemented nickname support
- Added Client:setNickname and Member:setNickname methods
- Added Member.nickname attribute
- getMemberByName now also searches nickname (may change in the future)
- Implemented role color support
- Added Color class with RGB, hex, and dec support
- Role.color and Role:setColor() now utilize Color class
- Implemented mentions support
- Parsed message mentions into objects within Message.mentions table
- Added Message:mentions[Member|Role|Channel] methods
- Added getMentionString methods for User, Role, and ServerTextChannel
- Added object array to sendMessage/createMessage method
- Other changes
- Moved classes out of /classes/utils folder into /classes
- VoiceState and Invite no longer inherit from Base, since they do not have Snowflake IDs
- Bug fixes
- Fixed issue where role would not properly update
- Fixed issue where member status was nil
- Fixed issue where server owner was nil
- Fixed issue where Member.gameName would be nil
- Removed logout POST until otherwise required
- Added timeout for WebSocket reconnections
- Improved rate limit handling
- ServerChannel:createInvite() now returns an Invite object
- Privatized update methods with leading underscore
- getMessageHistory now returns a table of objects
- Added User.bot parameter (boolean)
- Fixed issue where voiceLeave event would not fire
- Reworked logout and termination handling:
- Client:logout() now also clears the stored token
- Added Client:stop() method
- Added Client:disconnectWebsocket() and WebSocket:disconnect() helpers
- Renamed startWebsocketReceiver to startWebsocketHandler
- Added condition for an expected WS disconnection, which should be only after logout() is called.
- Added 'expected' argument to disconnect event.
- Added User.name alias for User.username
- Added HTTP 502 handling
- Caught exceptions no longer terminate the program
- Added convenient Server attributes defaultRole, defaultChannel, and me
- Added disconnect event
- Fixed missing presenceUpdate arguments
- Increased max messages to 500 per channel
- Fixed issue where offline member status was nil
- Fixed issue where nil gateways or tokens could potentially be cached as empty files
- Fixed issue where ready was not properly delayed
- Reworked login process
- loginWithEmail accepts email and password for regular accounts only
- loginWithToken accepts a token for any account
- Client:run() calls the appropriate login method
- Bot is prepended to the token according to the READY data
- Added User:sendMessage() method
- Implemented support for bot accounts
- Client:run() now accepts email and password or token
- Renamed Client:login(email, pass) to Client:userLogin(email, pass)
- Added Client:botLogin(token)
- Initially unavailable servers are now accounted for
- Implemented channel editing
- Added general edit method for ServerChannel
- Added setName method for ServerChannel
- Added setTopic method for ServerTextChannel
- Added setBitrate method for ServerVoiceChannel
- Critical: Fixed package path issue
- Overhauled class system
- Implemented exception handling
- New Error and Warning classes
- HTTP 400 is raised
- HTTP 403 is warned
- HTTP 429 is handled and warned
- Unhandled HTTP errors are raised
- Unhandled WebSocket events are warned
- Unhandled WebSocket payloads are warned
- Implemented Invite handling
- Added statusUpdate WebSocket method and corresponding client methods setStatusIdle, setStatusOnline, and setGameGame
- Implemented WebSocket reconnecting
- First 'stable' release to coincide with official API documentation release
- Code overhauled for optimizations and bug fixes
- Event callbacks no longer block the main loop
- Added Member class, which extends a now simplified User class
- Implemented gateway caching
- Added 'raw' event
- Added setOwner, setAfkTimeout, setAfkChannel Server methods
- Established project name: Discordia
- Added reply example script
- Changed luvit/secure-socket version to 1.1.2
- Request data is now camelified
- Moved websocket handlers to their own Client methods
- Added op# shortcut WebSocket methods
- Role events no longer emit Server object, use role.server instead
- General Git version control employed instead of GitHub direct editing
- Implemented custom class module with multiple inheritance
- Added base Base class for Discord classes
- Added peek methods to Deque class
- Converted lone Channel class to multiple classes:
- ServerChannel and TextChannel inherit from Base
- PrivateChannel inherits from TextChannel
- ServerTextChannel inherits from TextChannel and ServerChannel
- ServerVoiceChannel inherit from ServerChannel
- Fixed token caching, which now uses an MD5 hash
- Implemented token caching
- Conformed user agent to API standard
- Message deques and maximum scrollback implemented
- Added member chunking
- 'discord' now includes utils (in addition to Client)
- Added string split and number clamp helpers to utils
- Added event handling for guildRoleCreate, guildRoleDelete, and guildRoleUpdate
- Added channel position and general role mutators
- Message updates now account for 'embeds only'
- Added getServers and getMessages User methods
- Added event handling for guildCreate, guildDelete, guildUpdate
- Added event handling for guildBanAdd and guildBanRemove
- Added event handling for guildMemberAdd, guildMemberRemove, and guildMemberUpdate
- Added getAvatarUrl method for user class
- Pasted MIT license info into package.lua
- Created PrivateChannel class
- Moved several methods from Client class to respective Discord classes
- Added event handling for typingStart, messageDelete, messageUpdate, and MessageAck
- Added event handling for channelUpdate, channelDelete, and channelCreate
- Added methods to update class instances
- Switched from multiple User classes to one main class for all types
- Added event handling for messageCreate and voiceStateUpdate
- get[Role|Channel|Server]By[Name|Id] now use cached data
- Expanded Message class
- Finished the majority of REST methods
- Started the majority of expected class definitions
- Added websocket support
- Added event handling for the ready event