anheledir / honeycomb Goto Github PK
View Code? Open in Web Editor NEWA Discord bot to help artists manage their servers and engage with the community.
Home Page: https://honeycombs.cloud
License: MIT License
A Discord bot to help artists manage their servers and engage with the community.
Home Page: https://honeycombs.cloud
License: MIT License
Let users hide selectable profile information on certain servers.
In Discord, a shard is a separate instance of a bot that connects to a subset of Discord's servers. Discord uses sharding to distribute the load of a bot across multiple connections, allowing it to scale to support a large number of servers and users.
The Discord.NET library provides built-in support for sharding, making it easy to create and manage shards for your bot.
To activate this feature we need to set the ShardCount
property on our DiscordSocketConfig
object to the number of shards we want to use. Discord recommends using a shard count of 1,000 servers per shard, up to a maximum of 10,000 servers.
We then need to replace the currently used DiscordSocketClient
by the DiscordShardedClient
instead.
Also the token ID, total shard count and the individual shard-id should be configurable with environment variables.
It is possible to use sharding in combination with running your bot in multiple instances of Azure App Services. Here's one approach you can take:
Environment.GetEnvironmentVariable
method to get the instance's shard ID from an environment variable.var config = new DiscordSocketConfig
{
Token = "your_bot_token",
ShardId = int.Parse(Environment.GetEnvironmentVariable("SHARD_ID")),
ShardCount = int.Parse(Environment.GetEnvironmentVariable("SHARD_COUNT")),
};
var client = new DiscordShardedClient(config);
File: BaseBotService/Locales/de.ftl
Reference: en.ftl
ID | Attribute | Reference value |
---|---|---|
profile-config | button | Edit My Profile |
profile-config | emoji | 📝 |
profile | activity-calc | Still taking notes, come back in a few days ... |
File: BaseBotService/Locales/de.ftl
Reference: en.ftl
ID | Attribute | Reference value |
---|---|---|
profile | activity-calc | Still taking notes, come back in a few days ... |
An administrator has to configure a server-channel as "vent"-channel.
A user can then use a command to open a modal dialog where he can enter his venting message.
The message will be posted by the bot in the vent-channel anonymously. The message and its author will not be saved, but a hashed version of the author-id will be saved. This hashed ID cannot be used to identify a user. But if a message violates the server-rules, another user can report the message or a moderator can delete it (either directly or after a user reported it).
On deleting the message, the moderator can select the option to block the author of the message. As the user-id is unknown, only the hashed ID will be added to a block-list. Whenever a user wants to use the vent-command again, his user-id will be hashed again and checked if its present in the block-list. If yes, he gets a hidden message about the reason and cannot use the vent-feature.
An administrator can use a command to delete all entries on the block-list older than x days.
Optional features:
!! Important !!
At no point the author of a specific vent-message should be logged and only the hashed user-id must be saved along with the message.
File: BaseBotService/Locales/fr.ftl
Reference: en.ftl
ID | Attribute | Reference value |
---|---|---|
profile | activity-calc | Still taking notes, come back in a few days ... |
Describe the bug
A clear and concise description of what the bug is.
To Reproduce
Steps to reproduce the behavior:
/user config
command, which tries to send a DMExpected behavior
If no DM can be send to the user for missing permissions, it should tell him in a channel-message.
Maybe try a fallback with an ephemeral-message instead. 💡
Move the most common dependencies to the base class.
Implement it by BotModule and UserModule
namespace BaseBotService.Modules;
// TODO: Create a HoneycombModuleBase abstract class
// Move the most common dependencies to the base class.
// Implement it by BotModule and UserModule
File: BaseBotService/Locales/es.ftl
Reference: en.ftl
ID | Attribute | Reference value |
---|---|---|
profile-config | button | Edit My Profile |
profile-config | emoji | 📝 |
Usage of the Microsoft.Extensions.DependencyInjection
library recommended.
CodeFactor found an issue: Complex Method
It's currently on:
BaseBotService\Commands\UserModule.cs:169-249
Show the next 10 upcoming birthdays and add pagination for one year into the future.
Allow moderators to define a "Birthday" role and a certain time-of-day. Those with a birthday get said role on their birthday and at the configured time a notification is send to the server. Customizing of the message not yet necessary, will be done at a later date.
As artist you can connect your ko-fi account and register a webhook for new transactions (one-time and monthly).
Similar to Patreon you can lion server roles to different tiers on ko-fi.
File: BaseBotService/Locales/fr.ftl
Reference: en.ftl
ID | Attribute | Reference value |
---|---|---|
profile-config | button | Edit My Profile |
profile-config | emoji | 📝 |
profile | activity-calc | Still taking notes, come back in a few days ... |
File: BaseBotService/Locales/fr.ftl
Reference: en.ftl
ID | Attribute | Reference value |
---|---|---|
profile-config | button | Edit My Profile |
profile-config | emoji | 📝 |
Objective: Enable server-owners to activate activity tracking for their servers to gather statistics on user activity and engagement, without invading privacy or causing significant overhead.
Data Collection:
Data Aggregation:
Data Retention and Deletion:
Data Presentation:
Permission Management:
Scalability:
The remainder
attribute is missing for the method parameter:
public async Task UserInfoAsync(
[Summary("The (optional) user to get info from")]
+ [Remainder]
SocketUser? user = null)
// Load instances from DI
var _client = ServiceProvider.GetRequiredService<DiscordSocketClient>();
var _environment = ServiceProvider.GetRequiredService<IEnvironmentService>();
// TODO: Rename _clientEvents to _discordEvents
var _clientEvents = ServiceProvider.GetRequiredService<DiscordEvents>();
var _handler = ServiceProvider.GetRequiredService<InteractionService>();
File: BaseBotService/Locales/es.ftl
Reference: en.ftl
ID | Attribute | Reference value |
---|---|---|
profile-config | button | Edit My Profile |
profile-config | emoji | 📝 |
profile | activity-calc | Still taking notes, come back in a few days ... |
For our bot, some useful statistics that we could monitor include:
Message volume: Track the number of messages sent and received by the bot, as well as any errors or exceptions that occur when processing messages.
User engagement: Track the number of active users, the frequency of user interactions, and other engagement metrics to understand how users are interacting with the bot.
Performance metrics: Monitor server response times, latency, and other performance metrics to ensure that the bot is responding quickly and efficiently to user requests.
Error and exception tracking: Log any errors or exceptions that occur in our bot's code, along with contextual data such as the user and server that triggered the error.
By using Application Insights to monitor these metrics, we can gain valuable insights into how users are interacting with our bot, identify performance bottlenecks and errors, and optimize the bot's behavior for the best user experience.
We should utilize the Serilog.Sinks.ApplicationInsights
to send log messages automatically to Application Insights, too.
File: BaseBotService/Locales/fr.ftl
Reference: en.ftl
ID | Attribute | Reference value |
---|---|---|
profile-config | button | Edit My Profile |
profile-config | emoji | 📝 |
profile | activity-calc | Still taking notes, come back in a few days ... |
Current preference is SQLite, as it needs not many resources and should be enough for the bot.
Also, part of this ticket is to make sure, that the database is not overwritten when publishing an updated version via docker! It must be configurable where the database-file should be persisted (e.g. by an environmental variable).
File: BaseBotService/Locales/es.ftl
Reference: en.ftl
ID | Attribute | Reference value |
---|---|---|
profile | activity-calc | Still taking notes, come back in a few days ... |
An artist can create a new slot-based Group-Event: A drawing with a certain theme and multiple possible spots where users can have their OCs placed.
On creation the artist must setup the event:
Eligible users can reserve one slot at a time. They must confirm reading the conditions of participation, then can enter a short note for the selected slot (or choose an OC from their Character-References). If the artist has activated confirmations, the slot is reserved and must get confirmed first (e.g. when waiting for payment). Otherwise or when getting confirmed the state is changed to taken. Other users can only select slots that are neither reserved nor taken.
If the artist decided that the list of participants is public, everyone can see the following list. If it's not public, everyone beside the artist can just see the slot-numbers and their status (open, reserved, taken):
Users can cancel their slot again as long as the end-date of the event isn't reached.
MediatR is an open-source library developed by Jimmy Bogard that simplifies communication between components within a .NET application, following the principles of the Mediator pattern. It is used to promote loose coupling between components, reduce dependencies, and improve overall application maintainability and testability.
The primary use of MediatR is to manage and handle in-process messaging, such as requests and notifications, within an application. It is particularly useful in applications built using the CQRS (Command Query Responsibility Segregation) pattern, where commands and queries are separated for better organization and scalability.
File: BaseBotService/Locales/es.ftl
Reference: en.ftl
ID | Attribute | Reference value |
---|---|---|
profile-config | button | Edit My Profile |
profile-config | emoji | 📝 |
profile | activity-calc | Still taking notes, come back in a few days ... |
Allow artists to get a reminder of upcoming birthdays up to 14 days ahead.
They can add a new commission for a gift by just pressing a button. That commission is automatically set to "Secret" and is hidden on public lists.
Once finished they can choose to publish the drawing on the user's birthday automatically as a present.
Describe the bug
The user can set his birthday with a bot-command, the year being optional.
He can also select if every server he has in common with the bot is allowed to share that info or if he only wants to allow it for specifically selected servers. There should also be a button to allow the user to delete that information again.
The birthday (and age, if the year was set) is visible in the users profile (currenty the user-info command) if he allowed it for the specific server.
New commits von the main
branch should start an automatic deployment to the Azure App-Service.
Create a new solution with projects for the bot, some libraries and the most basic dependencies to login to Discord.
Add the configuration for adding app secrets.
Configure a Docker Build Script to run and deploy the solution as a container.
using BaseBotService.Messages;
using Discord.WebSocket;
namespace BaseBotService.Notifications;
public class ActivityHandler : INotificationHandler<ClientReadyNotification>
{
private readonly DiscordSocketClient _client;
public ActivityHandler(DiscordSocketClient client)
{
_client = client;
}
// TODO: Move this into its own service.
public async Task Handle(ClientReadyNotification notification, CancellationToken cancellationToken)
{
await _client.SetActivityAsync(new Game("the world burn", ActivityType.Watching));
await _client.SetStatusAsync(UserStatus.Online);
}
}
File: BaseBotService/Locales/de.ftl
Reference: en.ftl
ID | Attribute | Reference value |
---|---|---|
profile-config | button | Edit My Profile |
profile-config | emoji | 📝 |
profile | activity-calc | Still taking notes, come back in a few days ... |
using BaseBotService.Attributes;
using Discord;
using Discord.Interactions;
namespace BaseBotService.Modules;
[Group("bot", "The main bot information module of Honeycomb.")]
[EnabledInDm(true)]
public class BotModule : BaseModule
{
[SlashCommand("about", "Returns information like runtime and current version of this Honeycomb bot instance.")]
public async Task InfoCommandAsync()
{
// Create embedded message with bot information
var response = GetEmbedBuilder()
.WithTitle(AssemblyService.Name)
.WithThumbnailUrl(BotUser.GetAvatarUrl())
.WithUrl("https://honeycombs.cloud/") // TODO(i18n): Move URL to localization resource
.WithDescription($"Honeycomb is a Discord bot designed to provide artists with some useful functions to enhance their experience on Discord. With its features, artists can create a portfolio, display random entries from it, manage a commission price list, and keep track of their commission queue. The bot is released under the MIT license on GitHub.")
.WithFields(
new EmbedFieldBuilder()
.WithName("Uptime")
As artist you can connect your bot profile to your Patreon-Account and also link your patreon tiers to roles on the server.
API-Documentation: https://docs.patreon.com/#user-v2
Sample code:
using System;
using System.Collections.Generic;
using System.Net.Http;
using Newtonsoft.Json;
class Program
{
static async System.Threading.Tasks.Task Main(string[] args)
{
// Replace the placeholders with your actual values
string campaignId = "your_campaign_id";
string accessToken = "your_access_token";
// Define the endpoint URL and headers
string endpoint = $"https://www.patreon.com/api/oauth2/v2/campaigns/{campaignId}/members";
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {accessToken}");
// Send the API request
HttpResponseMessage response = await client.GetAsync(endpoint);
// Parse the response JSON to extract the member data
string responseContent = await response.Content.ReadAsStringAsync();
dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent);
List<dynamic> members = jsonResponse.data.ToObject<List<dynamic>>();
// Print the member data
foreach (dynamic member in members)
{
decimal pledgeAmount = member.attributes.currently_entitled_amount_cents / 100.0m;
string discordId = member.attributes.discord_id;
Console.WriteLine($"Discord ID: {discordId}, Pledge Amount: ${pledgeAmount}");
}
}
}
File: BaseBotService/Locales/de.ftl
Reference: en.ftl
ID | Attribute | Reference value |
---|---|---|
profile-config | button | Edit My Profile |
profile-config | emoji | 📝 |
using BaseBotService.Core.Messages;
using Discord.WebSocket;
namespace BaseBotService.Interactions;
public class ActivityHandler : INotificationHandler<ClientReadyNotification>
{
private readonly DiscordSocketClient _client;
public ActivityHandler(DiscordSocketClient client)
{
_client = client;
}
#pragma warning disable S1135
// TODO: Move this into its own service.
public async Task Handle(ClientReadyNotification notification, CancellationToken cancellationToken)
{
await _client.SetActivityAsync(new Game("the world burn", ActivityType.Watching));
await _client.SetStatusAsync(UserStatus.Online);
}
}
namespace BaseBotService.Extensions;
// TODO: Move enum DiscordTimestampFormat to the BaseBotService.Enumerations namespace
public enum DiscordTimestampFormat
{
ShortTime = 0,
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.