Coder Social home page Coder Social logo

eternalliquet / microservice-bots Goto Github PK

View Code? Open in Web Editor NEW
0.0 3.0 0.0 40 KB

An experiment to see if it's feasible to turn all of my bots into microservice based bots that forward processed Discord events to Azure Event Grid

License: GNU General Public License v3.0

C# 100.00%
bots microservice-bots discordnet discord-bot

microservice-bots's Introduction

Microservice Bots

A library that turns Discord.NET messages into JSON serializable objects that can be sent to queues and converted back to Discord.NET messages.

If you found this library particularly useful or helpful please consider supporting me:
Buy Me a Coffee at ko-fi.com

Usage Example

Gateway Application:

Note: You would use Discord.NET here to log your bot in and listen to events, for more information on getting this set up, please refer to the documentation here

    [Name("Test Commands")]
    public class TestModule : ModuleBase
    {
        //I am only using SQS as an example here. You can use any queue you want, from Azure to AWS to Kafka. Depends on which one you want to set up. 
        private readonly AWSSQSService _AWSSQSService;

        public TestModule(AWSSQSService AWSSQSService)
        {
            _AWSSQSService = AWSSQSService;
        }

        [Command("ping")]
        public Task Ping()
        {
            await _AWSSQSService.PostMessageAsync(JsonConvert.SerializeObject(new DiscordMessage(context.Message, context.Guild.Id))); 
            //Only use this if you NEED to track the guild ID and it's for sure only going to be used in guilds. (I recommend creating a PreCondition that checks if the command is being used in a guild)
            
            await _AWSSQSService.PostMessageAsync(JsonConvert.SerializeObject(new DiscordMessage(context.Message))); 
            //Otherwise, this will work since to send messages, you technically only need the Channel ID
        }
    }

In Your Microservice:

Note: I am using AWS Lambda here but you can use any service you want that lets you host microservices

    public class PingFunction
    {
        private static HttpClient httpClient = new HttpClient();
        
        public PingFunction()
        {

        }
        
        //The method that handles the events that trigger the lambda
        public async Task FunctionHandler(SQSEvent evnt, ILambdaContext context)
        {
            foreach (var message in evnt.Records)
            {
                await ProcessMessageAsync(message, context);
            }
        }
        
        //Messages are processed here
        private async Task ProcessMessageAsync(SQSEvent.SQSMessage message, ILambdaContext context)
        {
            var discordMessage = new DiscordMessage(message.Body); //message.Body comes in as a string, this will deserialize the string back into a JSON object.
            var messageContent = discordMessage.Content; 
            if(messageContent.Contains("!ping")) //This is not super necessary as Discord.NET already handles this check in your Gateway Application. You can have other checks here though. 
            {
                var reply = new DiscordReply(discordMessage, "pong!"); //We create a new reply
                //After this, you can choose any which way to send the data back to the Gateway Application. From, HTTP requests to additional queues. The choice is yours.
                //This example will assume you used an HTTP Post Request
                var content = new StringContent(reply.ToString(), Encoding.UTF8, "application/json");
                await client.PostAsync("examplegatewayapplication.io/api/Discord/reply", content); 
            }
        }
    }

Back In Your Gateway Application:

Note: This assumes that you've used an HTTP request to give the data back to the Gateway Application, but you can use any method you want to achieve this.

    [Route("api/[controller]")]
    [ApiController]
    public class DiscordController : ControllerBase
    {
        private readonly DiscordShardedClient _discordClient;

        public DiscordController(DiscordShardedClient discordClient)
        {
            _discordClient = discordClient;
        }

        // POST: /api/Discord/Reply
        [HttpPost("Reply")]
        public IActionResult Reply([FromBody] DiscordReply message) // Get back data in the form of a DiscordReply object
        {
            try
            {
                var channel = _discordClient.GetChannel(message.ChannelId) as ITextChannel; //Use the discord client to get the channel provided by the DiscordReply object
                await textChannel.SendMessagesAsync(message.Reply); //Use this channel to send our reply. 
            }
            catch (Exception ex)
            {
                //Log your exception here
            }
            return Ok();
        }
    }

Benefits of using a microservices architecture when it comes to Discord Bots

You're probably looking at that example thinking that was a really long winded way to achieve what could be done with a simple

        [Command("ping")]
        public Task Ping()
        {
            await ReplyAsync("pong!");
        }

I guarantee you that there is some benefit to this though.

Reusability

If you have 3-4 different custom bots that all share common commands (i.e an 8ball command or something) then they can all connect to that same microservice and you aren't copy pasting the code for an 8ball command over and over. This also reduces the amount of time it takes to develop complex services (i.e a leveling system or a Twitch Listener) as you can develop it once as a microservice and use it on any bot you have developed previously or will develop in the future with relatively small effort.

Programming Language Flexibility

If you want to write your Gateway Application in C# or Java but want to write your microservice in Javascript or Python, you can do that! The purpose of this library is to turn the Discord.NET message events into something that translates into a basic string that can be passed around from application to application. You would just have to make sure the JSON/strings are in the correct format!

Avoid Gateway Blocking (Library Specific Issues)

If you're familiar with how Discord.NET works then you know that it is ill-advised to have long running commands as that can block Gateway from recieving events and cause some issues with missed commands. This insures that you have a very fire-and-forget style of handling events and commands have very little chance of actually blocking a Gateway Event.

As a side note, if you would like to support the further development of this library:

  • Feel free to fork the repo and PR back any additions
  • Contact me at [email protected] for any suggestions
  • Donate to my Ko-fi here (I do this in my free time so any donation you can give helps me develop more things like this!)

microservice-bots's People

Contributors

eternalliquet avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.