Sometimes you are an indie developer or just creating a prototype, and you can't afford to set up a bucket on S3. For those times, I created this straightforward API to solve the issue of saving images in a database.
You have to set up a bot, and the service will take care of the rest.
To save the images, you must send him a form post with the field file
. The bot will save the photo and send it back as a URL so you can keep it in your database. In this blog post, I will explain what I've done and how you can set up for yourself this fantastic service.
Side note:
Thought that this post is not sponsored by Meteor Cloud. I recommend their service, and they have a free tier where you have a MongoDB instance that can be used to save that URL I mentioned above.
How to use it?
I will start linking the source code repo and ask you to give it a star.
If you want to run locally, you will need to set up a .env
file with some info that the bot requires to work, and that is all. When you run the main
function, it should create a web server where you can send a post
request to it and store your photos dynamically. Again if you want a more detailed version of how to set up and run this service in your cloud infrastructure, you can check the source code repo. In this post, I will focus on how I did it.
How is it done?
As you can see in the source code, this is a Go code, so it is straightforward as it can be.
Creating HTTP server and Bot connection
In this first part of the main
function, we have created the fiber HTTP server, and the creation of the /sendFile
route. When this route is called, passing the file
field, we have the creation of our discord bot using this excellent library called discordgo. We also open the WebSocket to talk to the Discord servers.
func main() {
app := fiber.New()
app.Use(cors.New())
app.Post("/sendFile", func(ctx *fiber.Ctx) error {
dg, err := discordgo.New("Bot " + os.Getenv("BOT_TOKEN"))
if err != nil {
fmt.Println("error creating Discord session,", err)
return fiber.NewError(fiber.StatusBadRequest, "error creating Discord session")
}
err = dg.Open()
if err != nil {
fmt.Println("error opening connection,", err)
return fiber.NewError(fiber.StatusBadRequest, "error opening connection,")
}
Getting the file and the channel
After creating the bot, we need to check if the file can be transformed into a stream. We do size and file type checking.
file, err := ctx.FormFile("file")
if err != nil {
fmt.Println("Error getting file", err.Error())
return fiber.NewError(fiber.StatusBadRequest, "Error getting file")
}
// do the checks and return a file to be sent to discord
osFile, err := media.ToOSFile(ctx, file)
if err != nil {
fmt.Println("Error saving the file", err.Error())
return fiber.NewError(fiber.StatusBadRequest, "Error saving the file")
}
Wrapping up and sending the URL
After doing all the necessary checks, we wrap the data into a struct that will be sent to discord and delivered to the bot. When sending the message is done, we gather the attachment URL and send it back to the user. We disconnect and clean up the server, so it is ready to receive another HTTP call.
data := &discordgo.MessageSend{
Files: []*discordgo.File{
{
Name: file.Filename,
ContentType: file.Header.Get("Content-Type"),
Reader: osFile,
}},
}
msg, err := dg.ChannelMessageSendComplex(os.Getenv("CHANNEL_ID"), data)
if err != nil {
fmt.Println("Error sending the message ", err.Error())
return fiber.NewError(fiber.StatusBadRequest, "Error sending the message")
}
r := new(Return)
r.Url = msg.Attachments[0].URL
// clean up and return
if err := os.Remove(media.Path); err != nil {
fmt.Println("Was not able to remove file", err.Error())
return fiber.NewError(fiber.StatusBadRequest, "Was not able to remove file")
}
defer func(dg *discordgo.Session) {
err := dg.Close()
if err != nil {
fmt.Println(err)
}
}(dg)
return ctx.JSON(r)
log.Fatal(app.Listen(":" + os.Getenv("PORT")))
}
Conclusion
With less than 100 lines, you can set up a bot a discord bot and make it do extraordinary things for you. I hope that this blog post is helpful to you in any way!
If you did like this content, please follow me on GitHub and Twitter for more! Also, liking this post will help me a lot. See you soon!
Top comments (2)
How stable is the discord CDN? How long do things live on the CDN?
pretty stable, for ever