Connect with us


Build a Discord Bot with Rust and Serenity



By Joe Previte

Discord is on the rise in developer communities. And, as we all know, developers love building on top of platforms they use. It’s fun!

Today, I’m going to show you how to build your own Discord bot using Rust and serenity.

Building the App

Before building the app, I’ll cover how it will work and the prerequisites for following along. After that, I’ll jump in and go through each step before setting it up to run locally on your machine. Finally, I’ll show how to test it out in your own Discord server.

How will it work?

Imagine I’m creating a bot for a developer community Discord server. I’m going to build a Discord bot which supports a single command !help, which will return a message explaining:

free widgets for website
  • What channel to post in for technical help
  • Where to find the code of conduct
  • How to get in touch with admins of the server

This could be helpful for new people who need help for various scenarios. Think of it being analogous to the –help flag commonly used by CLIs.


In order to start writing this Rust application, there are a few requirements:

  • Rust installed locally
  • IDE setup for Rust development
  • Discord account

Install Rust

I already have Rust installed locally. If you don’t, you can install it locally using:

 shell curl --proto '=https' --tlsv1.2 -sSf | sh 

Afterwards, run rustup –version to verify that it worked. If it did, you should see something printed to your terminal.

IDE for Rust Development

I’m going to be using VS Code and the rust-analyzer extension. You can find support for other IDEs under the Tools on the rust-lang website.

Discord Account

I already have an account, but if you don’t, you can sign up for free.

Set up Code

Since this is a new project, I’m going to create a new project with cargo. For simplicity, I’ll name the project discord-help-bot.

free widgets for website
 shell cargo new discord-help-bot 

Add Dependencies

This project requires two external dependencies:

  • tokio – “A runtime for writing reliable, asynchronous and slim applications with the Rust programming language”
  • serenity – “a Rust library for the Discord API”

I’ll add both to the Cargo.toml file:

 toml [dependencies] tokio = { version = "0.2", features = ["macros"] } serenity = { default-features = false, features = ["client", "gateway", "model", "rustls_backend"], version = "0.9.0-rc.1"} 

Note: you’ll notice this is a release candidate (rc). When you go through this, check to make sure you’re using the latest version of serenity.

tokio allows the program to run asynchronously and serenity allows you to interact with the Discord API. With both of these dependencies, I can start adding logic to the program.

Add Logic to

Since this is a small program, I will only need to add code to the file. I’ll add the code and then afterwards I’ll walk through how it works.

 rust use std::env; use serenity::{ async_trait, model::{channel::Message, gateway::Ready}, prelude::*, }; const HELP_MESSAGE: &str = " Hello there, Human! You have summoned me. Let's see about getting you what you need. ? Need technical help? => Post in the <#CHANNEL_ID> channel and other humans will assist you. ? Looking for the Code of Conduct? => Here it is: <> ? Something wrong? => You can flag an admin with @admin I hope that resolves your issue! -- Helpbot "; const HELP_COMMAND: &str = "!help"; struct Handler; #[async_trait] impl EventHandler for Handler { async fn message(&self, ctx: Context, msg: Message) { if msg.content == HELP_COMMAND { if let Err(why) = msg.channel_id.say(&ctx.http, HELP_MESSAGE).await { println!("Error sending message: {:?}", why); } } } async fn ready(&self, _: Context, ready: Ready) { println!("{} is connected!",; } } #[tokio::main] async fn main() { let token = env::var("DISCORD_TOKEN") .expect("Expected a token in the environment"); let mut client = Client::new(&token) .event_handler(Handler) .await .expect("Err creating client"); if let Err(why) = client.start().await { println!("Client error: {:?}", why); } } 

Code Walkthrough

I’m going to walk through the code in four chunks. In the first chunk, I’ll look at the following:

free widgets for website
 rust use std::env; use serenity::{ async_trait, model::{channel::Message, gateway::Ready}, prelude::*, }; 

These are the use declarations. They make it easier for developers because they “shorten the path required to refer to a module item.” Here, there are two blocks. The first refers to the env module from the standard library, which we later use to access the DISCORD_TOKEN environment variable.

See also  New report slams Facebook, Instagram and Twitter as 'safe space for racists'

The next block refers to the modules I use provided by serenity. The first is async_trait which I use on the Handler to tell the compiler the type and methods Handler should support. After that are two structs, Message and Ready. The first is used inside the function signature of message to indicate the type for the third parameter msg. As you can guess, this is for the shape of the message when we receive it from the Discord server. The other struct is Ready and is used in the function signature of the ready function for our Handler. The last line here is the prelude which says, “include the basic things out of the box for the user.”

In the second chunk, I’ll discuss the following piece of code:

 rust const HELP_MESSAGE: &str = " Hello there, Human! You have summoned me. Let's see about getting you what you need. ? Need technical help? => Post in the <#CHANNEL_ID> channel and other humans will assist you. ? Looking for the Code of Conduct? => Here it is: <> ? Something wrong? => You can flag an admin with @admin I hope that resolves your issue! -- Helpbot "; const HELP_COMMAND: &str = "!help"; 

I declare both HELP_MESSAGE and HELP_COMMAND using the const keyword because they stay constant throughout the lifetime of the program and don’t change. With const, you must explicitly annotate the type. We use the &str because these are string slices.

In the third chunk, I’ll look at the following:

free widgets for website
 rust struct Handler; #[async_trait] impl EventHandler for Handler { async fn message(&self, ctx: Context, msg: Message) { if msg.content == HELP_COMMAND { if let Err(why) = msg.channel_id.say(&ctx.http, HELP_MESSAGE).await { println!("Error sending message: {:?}", why); } } } async fn ready(&self, _: Context, ready: Ready) { println!("{} is connected!",; } } 

In this part of the program, I declare struct Handler. This doesn’t do much because all it does is declare the struct without any fields. In the next block, we use the #[async_trait] macro to tell the compiler that the struct below implements that trait like allowing us to use the async keyword with our functions and the .await method.

After that, the impl EventHandler for Handler tells the compiler, “My struct called Handler is going to look like an EventHandler.” Inside the struct are two functions: message and ready. The message function is where the main logic of our program happens. It takes in a message, checks the content to see if it matches the HELP_COMMAND and it does, it sends the HELP_MESSAGE to that channel using the same channel id. If there’s an error, it prints it.

See also  Connecting a web app to your PyTorch model using Amazon SageMaker

The ready function logs a statement letting us know the handler for our Discord bot is ready using the bot’s name.

Last, the final chunk I have to walk through is:

 rust #[tokio::main] async fn main() { let token = env::var("DISCORD_TOKEN") .expect("Expected a token in the environment"); let mut client = Client::new(&token) .event_handler(Handler) .await .expect("Err creating client"); if let Err(why) = client.start().await { println!("Client error: {:?}", why); } } 

The first thing I see is the #[tokio::main] macro which is used because this is an asynchronous application. The next is the main function which is called when the program runs. The first thing it does is get the DISCORD_TOKEN environment variable. Then, it creates a new Serenity Client using the token for us to talk to the Discord API. Last, the program starts the client and handles the error if it has issues starting up.

free widgets for website

And that’s all the logic for the program! Onto the next step.

Create a Discord Server

In order to test this out, I’ll need my own Discord Server. To create one, follow these steps:

  • Open the Discord application
  • On the left side, click the plus icon “Add a Server”
  • Click “Create a server”
  • Once you’ve filled everything out, click “Create”

Create Channel and Get Channel ID

Since I’m starting from scratch, I’ll need to create a new channel. I can do this by clicking the plus icon on the left next to “TEXT CHANNELS”. I’ll call mine “help”.

I need to get the channel ID. Discord makes it easy to expose this in the UI if you toggle on Developer Mode. To get here, go to Preferences > Appearance > Developer Mode.

To see the channel ID, right click on the channel and select “copy ID”.

free widgets for website

Returning to the application, replace the “CHANNEL_ID” placeholder text with yours. After words, it should look something like `<#750828544917110936>`. Make sure you have the angled brackets and the “#” symbol.

Add a Role

I’ll also need to add a role. To do this, follow these steps:

  • In the top left, click on the server dropdown menu
  • Select “Server Settings”
  • Go to Roles on the left
  • Click the plus next to Roles in the middle
  • Type in the role name – I’m using the name “admin”
  • Click “Save changes”

To make yourself that role, right click on your Discord handle either in a message on the right sidebar, select Roles > admin.

Now that I have the role set up, someone can actually use the @admin to get my attention.

Create Discord Application

In order to create a Discord bot, I first need to create a Discord application. Follow these steps to do this:

After this is done, I can move on to the next step to create a bot.

free widgets for website

Create Discord Bot and Install on Discord Server

The next step is to create a Discord Bot. Think of this as the profile for the bot. To create one, do the following:

  • On the left sidebar, click “Bot”
  • Click “Add Bot”
  • Feel free to change the name and the icon here
  • After you’re done, click “OAuth2” on the left sidebar
  • Under scopes, select “bot”
  • Scroll down to permissions and select “Send Messages” and “Read Message History”
  • Scroll up and click “copy” to copy the generated OAuth url
  • Paste it in a new tab in your browser
  • It will ask you which server you want to add it to. Note: you can only add bots to servers where you have the “Manage Server” permissions. Since we created our own, we do. Add it to the server you created earlier.
  • Click “Continue”
  • Confirm that you want to allow the bot to send messages and click “Authorize”
See also  What Is a Data Center?

Great! Now the Discord bot is created.

Before I leave the Discord Developer Portal, I need one last thing: the Discord Bot auth token. To see it, follow these steps:

  • Click “Bot” on the left sidebar again
  • Next to the bot icon, look for the token
  • Click “copy”

I’m going to save this now because I’ll need it later when I run the application locally. Also, a friendly reminder to not commit this to git. You don’t want your auth token to get in the wrong hands!

Build Code

I am ready to build my project for testing locally. To this, I can run:

 shell cargo build 

If the compiler is happy with my code, it will output my code under /target/debug/ and contain an executable using the name key in the Cargo.toml. In my case, this is discord-help-bot.

Run Locally

It’s time to run the executable locally and see if my bot starts up as expected. I will run the command:

free widgets for website
 shell DISCORD_TOKEN=<use your token here> ./target/debug/discord-help-bot 

I’ll replace “<use your token here>” with my token from earlier. This makes the token available as an environment variable to the application.

If it worked, you should see a message printed to the terminal saying “BotName is connected!” where “BotName” shows the name of your bot according to what you named it.

Test Bot on Discord Server

The moment I’ve been waiting for – testing my bot on my Discord server. With the bot still running from the previous step, I will open my Discord server where the bot is installed and send the message “!help” in the #general channel. And it works! I see the help message I wrote earlier posted to the channel almost immediately by my bot.

Woohoo! Mission accomplished.


Congratulations on making it through this project with me! I had a lot of fun and hope you did as well. I built a basic Discord bot with Rust and tested it on my Discord server by running it locally.

free widgets for website

If you’d like to see a full-working version of this, you can check it out here on GitHub. If you want to make this better, I encourage you to open a pull request! You can ask questions there in an issue or open an issue if you find a bug. All contributions are welcome!

Next Steps

If you’d like to continue hacking on this project further, here are a few ideas:

  • Print a message to the console along with the username of the person who interacted with the bot
  • Add an avatar/icon to the bot
  • Add a second command to the bot
  • Deploy the bot

Let me know if you do this or something similar. We’d love to see what you build.

Resources for Learning More Rust

Looking for more ways to develop your Rust skills? Here are a few recommendations for continuing your learning:

Thanks for reading. Happy coding!

Special thanks to the maintainers of Serenity for the project examples and Will Harris’ article “How to Add a Bot to Discord” both of which made writing this tutorial possible.

free widgets for website

To learn more about Facebook Open Source, visit our open source site, subscribe on Youtube, or follow us on Twitter and Facebook.

Facebook Developers

Continue Reading
Advertisement free widgets for website


Now people can share directly to Instagram Reels from some of their favorite apps





More people are creating, sharing and watching Reels than ever before. We’ve seen the creator community dive deeply into video content – and use it to connect with their communities. We’re running a limited alpha test that lets creators share video content directly from select integrated apps to Instagram Reels. Now, creators won’t be interrupted in their workflow, making it easier for them share share and express themselves on Reels.

“With the shift to video happening across almost all online platforms, our innovative tools and services empower creativity and fuel the creator economy and we are proud to be able to offer a powerful editing tool like Videoleap that allows seamless content creation, while partnering with companies like Meta to make sharing content that much easier.”- Zeev Farbman, CEO and co-founder of Lightricks.

Starting this month, creators can share short videos directly to Instagram Reels from some of their favorite apps, including Videoleap, Reface, Smule, VivaVideo, SNOW, B612, VITA and Zoomerang, with more coming soon. These apps and others also allow direct sharing to Facebook , which is available for any business with a registered Facebook App to use.

We hope to expand this test to more partners in 2023. If you’re interested in being a part of that beta program, please fill out this form and we will keep track of your submission. We do not currently have information to share about general availability of this integration.

Learn more here about sharing Stories and Reels to Facebook and Instagram and start building today.

free widgets for website


Q. What is the difference between the Instagram Content Publishing API and Instagram Sharing to Reels?

See also  Facebook is shook, asks for removal of FTC Chair Khan from antitrust cases against it

A: Sharing to Reels is different from the Instagram Content Publishing API, which allows Instagram Business accounts to schedule and publish posts to Instagram from third-party platforms. Sharing to Reels is specifically for mobile apps to display a ‘Share to Reels’ widget. The target audience for the Share to Reels widget is consumers, whereas the Content Publishing API is targeted towards businesses, including third-party publishing platforms such as Hootsuite and Sprout Social that consolidate sharing to social media platforms within their third-party app.

Q: Why is Instagram partnering with other apps?

A: Creators already use a variety of apps to create and edit videos before uploading them to Instagram Reels – now we’re making that experience faster and easier. We are currently doing a small test of an integration with mobile apps that creators know and love, with more coming soon.

Q: How can I share my video from another app to Reels on Instagram?

free widgets for website

A: How it works (Make sure to update the mobile app you’re using to see the new Share to Reels option):

  • Create and edit your video in one of our partner apps
  • Once your video is ready, tap share and then tap the Instagram Reels icon
  • You will enter the Instagram Camera, where you can customize your reel with audio, effects, Voiceover and stickers. Record any additional clips or swipe up to add an additional clip from your camera roll.
  • Tap ‘Next’ to add a caption, hashtag, location, tag others or use the paid partnerships label.
  • Tap ‘Share’. Your reel will be visible where you share reels today, depending on your privacy settings.
See also  Connecting a web app to your PyTorch model using Amazon SageMaker

Q: How were partners selected?

A. We are currently working with a small group of developers that focus on video creation and editing as early partners. We’ll continue to expand to apps with other types of creation experiences.

Q: When will other developers be able to access Sharing to Reels on Instagram?

A: We do not currently have a date for general availability, but are planning to expand further in 2023.

Q: Can you share to Facebook Reels from other apps?

free widgets for website

A: Yes, Facebook offers the ability for developers to integrate with Sharing to Reels. For more information on third-party sharing opportunities, check out our entire suite of sharing offerings .

First seen at

Continue Reading


What to know about Presto SQL query engine and PrestoCon





The open source Presto SQL query engine is used by a diverse set of companies to navigate increasingly large data workflows. These companies are using Presto in support of e-commerce, cloud, security and other areas. Not only do many companies use Presto, but individuals from those companies are also active contributors to the Presto open source community.

In support of that community, Presto holds meetups around the world and has an annual conference, PrestoCon, where experts and contributors gather to exchange knowledge. This year’s PrestoCon, hosted by the Linux Foundation, takes place December 7-8 in Mountain View, CA. This blog post will explore some foundational elements of Presto and what to expect at this year’s PrestoCon.

What is Presto?

Presto is a distributed SQL query engine for data platform teams. Presto users can perform interactive queries on data where it lives using ANSI SQL across federated and diverse sources. Query engines allow data scientists and analysts to focus on building dashboards and utilizing BI tools so that data engineers can focus on storage and management, all while communicating through a unified connection layer.

In short, the scientist does not have to consider how or where data is stored, and the engineer does not have to optimize for every use case for the data sources they manage. You can learn more about Presto in a recent ELI5 video below.

Caption: Watch the video by clicking on the image above.

free widgets for website

Presto was developed to solve the problem of petabyte-scale, multi-source data queries taking hours or days to return. These resources and time constraints make real-time analysis impossible. Presto can return results from those same queries in less than a second in most cases, allowing for interactive data exploration.

See also  Facebook Messenger Is Launching a Split Payments Feature for Users to Quickly Share Expenses

Not only is it highly scalable, but it’s also extensible, allowing you to build your own connector for any data source Presto does not already support. At a low level, Presto also supports a wide range of file types for query processing. Presto was open sourced by Meta and later donated to the Linux Foundation in September of 2019.

Here are some Presto resources for those who are new to the community:

What is PrestoCon?

PrestoCon is held annually in the Bay Area and hosted by the Linux Foundation. This year, the event takes place December 7-8 at the Computer History Museum. You can register here. Each year at PrestoCon, you can hear about the latest major evolutions of the platform, how different organizations use Presto and what plans the Technical Steering Committee has for Presto in the coming year.

Presto’s scalability is especially apparent as every year we hear from small startups, as well as industry leaders like Meta and Uber, who are using the Presto platform for different use cases, whether those are small or large. If you’re looking to contribute to open source, PrestoCon is a great opportunity for networking as well as hearing the vision that the Technical Steering Committee has for the project in the coming year.

free widgets for website

Explore what’s happening at PrestoCon 2022:

Where is Presto used?

Since its release in November of 2013, Presto has been used as an integral part of big data pipelines within Meta and other massive-scale companies, including Uber and Twitter.

The most common use case is connecting business intelligence tools to vast data sets within an organization. This enables crucial questions to be answered faster and data-driven decision-making can be more efficient.

How does Presto work?

First, a coordinator takes your statement and parses it into a query. The internal planner generates an optimized plan as a series of stages, which are further separated into tasks. Tasks are then assigned to workers to process in parallel.

Workers then use the relevant connector to pull data from the source.

free widgets for website

The output of each task is returned by the workers, until the stage is complete. The stage’s output is returned by the final worker towards the next stage, where another series of tasks must be executed.

The results of stages are combined, eventually returning the final result of the original statement to the coordinator, which then returns to the client.

How do I get involved?

To start using Presto, go to and click Get Started.

We would love for you to join the Presto Slack channel if you have any questions or need help. Visit the community page on the Presto website to see all the ways you can get involved and find other users and developers interested in Presto.

If you would like to contribute, go to the GitHub repository and read over the Contributors’ Guide.

free widgets for website

Where can I learn more?

To learn more about Presto, check out its website for installation guides, user guides, conference talks and samples.

Make sure you check out previous Presto talks, and attend the annual PrestoCon event if you are able to do so.

To learn more about Meta Open Source, visit our open source site, subscribe to our YouTube channel, or follow us on Twitter, Facebook and LinkedIn.

First seen at

free widgets for website
Continue Reading


How to Interpret Webhook Components in the WhatsApp Business Platform





The ways customers want to connect are changing. The WhatsApp Business Platform gives businesses an integrated way to communicate with customers right where they are. In order to integrate properly when using the Cloud API, hosted by Meta, you’ll need to leverage webhooks so applications have a way to respond to events. Webhooks allow your application to monitor three primary events on WhatsApp so you can react with different functionality depending on your goals.

This article looks at these three components, goes through the information they carry, and provides some use-case scenarios to give you an idea of the possibilities.

Interpreting Different Webhook Components

To send and receive messages on WhatsApp, it’s critical to keep track of statuses and errors to help ensure you’re communicating effectively with your customers, which you can do with webhooks.

With webhooks, the WhatsApp Business Platform monitors events and sends notifications when one occurs. These events are one of three components: messages, statuses, and errors.

Let’s explore each of these and examine examples of how you can use them.

free widgets for website


The messages component is the largest of the three event types and contains two core objects:

  • Contacts — which contain information about the message’s sender.

  • Messages — which provide information about a message’s type and contents.

These two event types allow your application to manage and respond to people that interact with your application. The contacts object contains two pieces of information: name and WhatsApp Id. The contact’s name allows your application to use their name without further lookups. In contrast, the contact’s WhatsApp ID lets you keep track of these contacts or use the contacts/ endpoint to add additional functionality.

For instance, you can verify the customer and start the opt-in process within the customer-initiated conversation, which allows you to message them outside the initial 24-hour response window. It’s important to note that only the text, contacts, and location message types provide contact information.

The message object is where the bulk of the information is stored, including the message contents, type of message, and other relevant information. Depending on the message type, the actual payload of the message component can vary widely. It’s crucial to determine the message type to understand the potential payload. Message types include:

  • Text: a standard text-only message

  • Contact: contains a user’s full contact details

  • Location: address, latitude, and longitude

  • Unknown: unsupported messages from users, which usually contain errors.

  • Ephemeral: disappearing messages

  • Media message types: contain information for the specified media file. These types include:

    • Document

    • Image

    • Audio

    • Video

    • Voice

These different data types can have very different uses, from reviewing images and screenshots from concerned customers to collecting information about where to ship goods and send services. To use these different data types most effectively, you can create applications to handle different forms of communication, with functionalities such as:

free widgets for website
  • Ask your customers to provide a shipping or mailing address. You can use the location-based message feature to capture your users’ location to determine where to send their goods and services.

  • Show customers products and communicate product details through a message. You can use the referred_product field within messages to offer your users specific product details. Using this field develops a more personal, conversational shopping experience and customer interactions.

  • Build support functionality that allows customers to take and send images and videos of product concerns, and submit those for a support case. Once the user has submitted a support ticket, the app can track the case — including steps taken towards resolution and conversations between support teams and the customer through WhatsApp — using a unique case identifier.

These are just some potential features you can build using the interactivity provided by webhooks and the message object. These features extend your current communication channels and provide additional options for customers.


Where the messages component provides your application with insight into events that originate directly from your customers, the statuses component keeps track of the results of messages you send and the conversation history. There are six status components:

  • Sent: the application sent your message and is in transit.
  • Delivered: the user’s device successfully received the message.
  • Read: the user has read your message.
  • Deleted: a user deleted a message that you sent.
  • Warning: a message sent by your application contains an item that isn’t available or doesn’t exist.
  • Failed: a message sent by your application failed to arrive.

Status components also contain information on the recipient ID, the conversation, and the pricing related to the current conversation. Conversations on WhatsApp are a grouping of messages within a 24-hour window that are either user-initiated or business-initiated. Keeping track of these conversations is vital, as a new conversation occurs when you send additional responses after the 24-hour period ends.

Some functionality you may want to add to your application based on status events includes:

  • Ensuring your application has sent generated messages, they arrived, and the recipient potentially read them by using a combination of these status types and timestamps within the status object. This information allows your application to follow up with customers if they didn’t engage.
  • Keep analytical information about your application’s messages, especially regarding business-initiated conversations. For example, if your application uses a WhatsApp customer contact list to send offer messages, the status component helps you understand how many were sent, delivered, read, responded to, or failed to measure your campaign’s success.


Finally, the errors component allows your application to receive any out-of-band errors within WhatsApp that affect your platform. These errors don’t stop your application from compiling or working but are typically caused when your application is misusing specific functionality. The following are some typical errors.

Error Code 368, Temporarily Blocked for Policy Violations

If your application violates WhatsApp Business Messaging or Commerce policy, your account may be temporarily banned. You can monitor this and pause your application while troubleshooting.

Error 506, Duplicate Post

If your workflows unintentionally generate duplicate messages, you can monitor this to find the source.

free widgets for website

Error 131043, Message Expired

Sometimes, messages are not sent during their time to live (TTL) duration. Use this code to know which messages to schedule for resending if needed.

Error handling is a broad, complex subject, and there are many other use cases for which you should be implementing error handling. The errors component helps extend your error handling on the WhatsApp Business Platform for greater consistency.


This article took a high-level look at messages, statuses, and errors returned by webhooks and explored ways you can use these three components to expand your application’s functionality.

Messages provide information on customer interactions, statuses give insight into messages your app sends, and error notices enable you to increase your application’s resilience. Webhooks are critical to ensuring your app interacts with customers seamlessly.

The WhatsApp Business Platform’s webhooks provide your applications with real-time data, enabling you to build better experiences as you interact with customers. Ready to know more? Dive deeper into everything the WhatsApp Business Platform has to offer.

free widgets for website

First seen at

See also  Facebook is shook, asks for removal of FTC Chair Khan from antitrust cases against it
Continue Reading