Hi everyone,
I would like to pitch DiscordBM to be included in the SSWG incubation process with Sandbox maturity level.
DiscordBM is a new multi-platform Server-Side focused Swift library for interacting with the Discord API, for making bots.
It's been in public development for more than 8 months.
Some Story
DiscordBM was not supposed to become a public package. I was using it in a private project and I knew it would be a big commitment to release it to the public, considering it'll need cleaner public API, a decent amount of docs and support, etc...
What happened was that our beloved Penny bot in Vapor's Discord server was having long-standing problems, so @0xTim and Benny were working on updating her and deploying it on AWS. Though there was a problem with SketchMaster2001's fork of SwiftCord that would result in random disconnections of web-socket connections that are made to the Discord "Gateway".
Long story short, I first tried to get SketchMaster2001's SwiftCord working, but not only I failed, I also found out the library's problems don't end there and it also has some multi-threading problems which did result in a crash, on my MacBook when I was testing.
That was when I decided to publicize DiscordBM.
Motivation
I believe the Swift on Server community will benefit from DiscordBM as a high-quality package to interact with the Discord API.
The library is still in beta, which I see as an opportunity to make any required refinements to the package before a stable release.
Usage
Here's a small showcase that will get a bot started and working. You'll need to acquire a 'Bot Token' and an 'App ID' through the Discord developer portal as mentioned in the README.
For full info, have a look at the README on Github.
/// First, add these 2 as dependencies
import DiscordBM
import AsyncHTTPClient
@main
struct EntryPoint {
static func main() async throws {
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
let bot = BotGatewayManager(
eventLoopGroup: httpClient.eventLoopGroup,
httpClient: httpClient,
token: YOUR_BOT_TOKEN,
appId: Snowflake(YOUR_APP_ID),
presence: .init( /// Set up bot's initial presence
/// Will show up as "Playing Swift"
activities: [.init(name: "Swift", type: .game)],
status: .online,
afk: false
),
/// Add all the intents you want
intents: [.guildMessages, .messageContent]
)
/// Tell the manager to connect to Discord.
await bot.connect()
/// Get an `AsyncStream` of `Gateway.Event`s
let stream = await bot.makeEventsStream()
/// Handle each event in the stream
/// This stream will never end, therefore preventing your executable from exiting
for await event in stream {
switch event.data {
case let .messageCreate(message):
print("NEW MESSAGE!", message)
/// Use `bot.client` to send requests to Discord
let response = try await bot.client.createMessage(
channelId: message.channel_id,
payload: .init(content: "Got a message: '\(message.content)'")
)
/// Easily decode the response to the correct type
let message = try response.decode()
/// You can also use the `GatewayEventHandler` protocol for more convenience
default: break
}
}
}
}