I Made a Discord Bot Just for Logs: A Simple HTTP-Based Messaging Bot
Hello, this is Rcat.
I've been making various things in Python lately, but sometimes they don't work quite right, or I find myself wondering if they're running properly during normal operation...
While building various apps, it's a hassle to check the logs for each one individually...
Oh, I should just output them to a chat app in real-time!
So, let's get started.
Introduction
Terms of Service
Please check the terms of service before using any information or works.
About Comments
Please check the terms of service guidelines before posting a comment.
Overview and Brief Explanation
So, what we are building this time is a Discord bot that posts strings received from an external source as-is.
Although I call it a log-only bot in the title, I believe it has various other uses regardless of that.
Operation Explanation
The specific operation is as follows.
Access a dedicated URL with the channel you want to post to and the text included.
The specified text is posted to the specified channel within Discord.
It's quite simple.
What can you do with this? For example, how about giving various programs running on a server the ability to access this URL as a log output function when something happens?
You can build a system where logs are sent as notifications in real-time if something occurs.
Now, let's look at how to use it.
Specific Usage (GET)
First, I will explain the easiest way to output logs using GET.
Simply put, GET is just a normal access request.
However, you can specify parameters after the URL at this time.
Specifically, you write a "?" at the end of the URL, and then connect keys and values with "=".
Here is an actual example.
I have specified 'logtest' as the channel and 'log' as the log content.
When you access this URL, the state in Discord will be as follows.

The bot I created this time also has a feature to automatically create a channel if it doesn't exist, so preparation is easy.
The specified 'logtest' channel is created, and the message "This is a test log" is posted inside it.

Unless you are trying to control something through the bot, it seems like you could do a lot of things just by having one of these bots set up.
Specific Usage (POST)
Next is POST.
Since there is a length limit for URLs there is a possibility that logs may become too long and cause an error in some cases.
Therefore, it is safer to post if it exceeds 100 characters when posting.
The parameters are the same as for GET, and are sent as a JSON body.
Note that the Discord message character limit is 2000. Please ensure you do not exceed this.
Writing it in Python looks like this.
import requests
url = "http://localhost:25055/log"
data = {
"channel":"posttest",
"log":"POSTのテストメッセージです"
}
requests.post(url, json=data)When you run this, you can confirm that a new channel is created and the log is posted.

BOT Installation
First, please create a Discord bot and add it to your server.
Channels required for output are created automatically so there is no need to prepare them in advance. Conversely, please note that if you do not have such permissions, it will result in an error. It was a hassle for me, so I added it as an administrator.
I have introduced how to create a bot account in the following article, so please refer to it.
The contents of the distributed package are as follows.
Initial creation is done on Windows and operation is on Linux.

This project supports automatic environment setup.
Please use the start batch file prepared for each OS to launch. Everything from environment setup to startup is performed automatically.
Details are explained in the following Python installation method.
If you have not installed Python yet, please take a look at this and install it.
As a preliminary preparation, please write the bot token into the token file at the bottom. You cannot start it without this.
Once you have confirmed that the bot is online, please proceed.
Client-side Installation
Using a Dedicated Client
As explained above, if you can access it yourself, that is fine.
I created a dedicated class for embedding into programs.
The usage is as follows.
First, import and instantiate it.
At the time of instantiation, enter the channel name and the address of the server where the bot is running.
If you have changed the web server port number on the bot side, port configuration is also required.
Then just call the log method of the instance object.
>>>import loggingbot_client as LC
>>>l = LC.LoggingbotClient(Name="RcatTest",Server="192.168.0.4")
>>>l.log("てすとだよ~ん☆")The execution result is here.
A channel is automatically created and the message is posted there.

By the way, the contents of the class are as follows.
Since the Discord bot is asynchronous, it is characterized by being created based on functions using aiohttp so that it can handle such programs.
Therefore, when using it from other bots, you can also use it in the form of "await log_async()".

Also, although I didn't explain it above, you can actually send log text as base64 instead of plain text.
It might be fine with POST, but I have a desire to ensure it can be received normally regardless of what characters are sent.
Logging Return Values with Decorators
In the method above, if you want to output logs, you need to add log output to the function.
However, I have introduced a decorator starting this time. By using this, there is a possibility that you can output logs without changing the function at all.
The following is a sample. What do you think will happen when you run this?

In normal execution order, the test1 function would print "Neko cute" and finish, but this timethere is a decorator called @loggingbot before the function.
A decorator is a feature that allows you to add extra processing before and after a specified function.
This time, you can add a feature that passes the return value after the function finishes directly to the log function introduced earlier, making the bot post it.
Note that due to specifications, it is limited to string types.
In other words, if it is a function that returns a string type, you can add this decorator to output the return value to the log.
If you write the sample above at the end of the module where you defined the class and execute it, the string will also be output to the bot as shown below.

As you can see, a decorator is what allows you to add extra functionality to a function without touching it at all.
For a completely new program, you might consider this log output from the start, but please use it if you want to incorporate it as an additional feature into an existing one.
Spam prevention with history feature (V1.1 update)
For example, suppose you output a log when some kind of problem occurs.
And if the log keeps being output while that problem continues, it would be quite a big deal, right?
So, I designed it to keep a message history and ignore spam within a specific interval.
I have highlighted only the parts changed in this update.
Specifically, I am using the message as a key and storing the posting time in a dictionary.
However, since using the message as-is could result in an extremely long key, I used an MD5 hash this time.
This hash is also used for file checksums, and I thought it was perfect for generating a unique key of a fixed length.

When you actually use it, it won't listen to you at all even if you spam it like this, and it won't be sent until the specified time has passed.

Please note that the initialization arguments have increased due to this update.
By specifying the interval in seconds, it will ignore the same message sent within that time.

Handler for logging library (V1.2 update)
I have made it possible to add this work as a handler to log output using the logging library, which is a standard Python library.
Please check the article below for details.
Distribution Information
Distribution URL
It is distributed at the following URL.
Please use it after agreeing to the terms of service.
Please check below for distribution information.
いいなと思ったら応援しよう!
情報が役に立ったと思えば、僅かでも投げ銭していただけるとありがたいです。