I'm writing a discord bot in C# with Discord.NET API.
I was wondering if I could get a few pointers on how to make my bot post a message in a channel every 6 hours.
Details required by stack overflow:
I have the commands set up. I followed a tutorial and found some code to get this far. I know I have to use a timer, but I'm not sure how to hook it into the discord .NET api.
Thank you.
Here's the code I have so far.
Program.cs https://pastebin.com/rMjY8MAE
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using SQLitePCL;
namespace PrayerBot
{
class Program
{
static void Main(string[] args) => new Program().RunBot().GetAwaiter().GetResult();
// Creating the necessary variables
public static DiscordSocketClient _client;
private CommandService _commands;
private IServiceProvider _services;
private BotConfig config;
// Runbot task
public async Task RunBot()
{
_client = new DiscordSocketClient(); // Define _client
_commands = new CommandService(); // Define _commands
_services = new ServiceCollection() // Define _services
.AddSingleton(_client)
.AddSingleton(_commands)
.BuildServiceProvider();
config = JsonConvert.DeserializeObject<BotConfig>(File.ReadAllText("config.json"));
string botToken = config.token; // Make a string for the token
_client.Log += Log; // Logging
await RegisterCommandsAsync(); // Call registercommands
await _client.LoginAsync(TokenType.Bot, botToken); // Log into the bot user
await _client.StartAsync(); // Start the bot user
await _client.SetGameAsync(config.game); // Set the game the bot is playing
await Task.Delay(-1); // Delay for -1 to keep the console window opened
}
private async Task RegisterCommandsAsync()
{
_client.MessageReceived += HandleCommandAsync; // Messagerecieved
await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), null); // Add module to _commands
}
private Task Log(LogMessage arg) // Logging
{
Console.WriteLine(arg); // Print the log to Console
return Task.CompletedTask; // Return with completedtask
}
private async Task HandleCommandAsync(SocketMessage arg)
{
string messageLower = arg.Content.ToLower(); // Convert the message to a Lower
var message = arg as SocketUserMessage; // Create a variable with the message as SocketUserMessage
if (message is null || message.Author.IsBot) return; // Checks if the message is empty or sent by a bot
int argumentPos = 0; // Sets the argpos to 0 (the start of the message)
if (message.HasStringPrefix(config.prefix, ref argumentPos) || message.HasMentionPrefix(_client.CurrentUser, ref argumentPos)) // If the message has the prefix at the start or starts with someone mentioning the bot
{
var context = new SocketCommandContext(_client, message); // Create a variable called context
var result = await _commands.ExecuteAsync(context, argumentPos, _services); // Create a veriable called result
if (!result.IsSuccess) // If the result is unsuccessful
{
Console.WriteLine(result.ErrorReason); // Print the error to console
await message.Channel.SendMessageAsync(result.ErrorReason); // Print the error to the channel where the error was caused (e.g "Unknown Command")
}
}
}
}
class BotConfig
{
public string token { get; set; }
public string prefix { get; set; }
public string game { get; set; }
}
}
Commands.cs https://pastebin.com/1EK3M1Fi
using Discord.Commands;
using Microsoft.Data.Sqlite;
using System;
using System.Threading.Tasks;
namespace PrayerBot
{
public class Commands : ModuleBase<SocketCommandContext>
{
[Command("ping")]
private async Task Ping()
{
await ReplyAsync("Pong! 🏓 **" + Program._client.Latency + "ms**");
}
[Command("help")]
private async Task Help()
{
string returnStr = "Worley Byrd Help\n";
returnStr += "~addprayer prayer - this adds a prayer\n";
returnStr += "~viewprayers - view prayers that haven't been answered\n";
returnStr += "~answerprayer id# - mark prayer# as answered\n";
await ReplyAsync(returnStr);
}
void setKeyValue(string name, string value)
{
string keyQuery = $"select value from keys where name='{name}'";
string strValue = "";
using (var connection = new SqliteConnection("Data Source=prayers.s3db"))
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = keyQuery;
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
strValue = reader.GetString(0);
}
}
}
if (String.IsNullOrEmpty(strValue))
{
//insert
string insertQuery = $"insert into keys(name,value) values('{name}','{value}')";
using (var connection = new SqliteConnection("Data Source=prayers.s3db"))
{
connection.Open();
var cmd = connection.CreateCommand();
cmd.CommandText = insertQuery;
cmd.ExecuteNonQuery();
}
}
else
{
//update
string updateQuery = $"update keys set value='{value}' where name='{name}'";
using (var connection = new SqliteConnection("Data Source=prayers.s3db"))
{
connection.Open();
var cmd = connection.CreateCommand();
cmd.CommandText = updateQuery;
cmd.ExecuteNonQuery();
}
}
}
[Command("serverinfo")]
public async Task Serverinfo()
{
await Context.Channel.SendMessageAsync($"This Discord server's name is {Context.Guild}");
}
[Command("posttochannel")]
[Summary("Which channel to post prayers to")]
public Task SetPostToChannel([Remainder][Summary("Set to this channel")] string channel)
{
string serverName = $"{Context.Guild}";
setKeyValue($"posttochannel.{serverName}", channel);
return ReplyAsync("Post Channel set to " + channel);
}
[Command("addprayer")]
[Summary("Add's a prayer to the prayer DB")]
public Task AddPrayerAsync([Remainder][Summary("The prayer to add")] string prayer)
{
string insertPrayer = string.Format("insert into prayers(prayer) values('{0}')", prayer);
using (var connection = new SqliteConnection("Data Source=prayers.s3db"))
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = insertPrayer;
command.ExecuteNonQuery();
}
return ReplyAsync("Prayer added!");
}
[Command("viewprayers")]
[Summary("Add's a prayer to the prayer DB")]
public Task ListPrayersAsync()
{
string selectPrayers = string.Format("select * from prayers where answered=0");
string resultString = "";
using (var connection = new SqliteConnection("Data Source=prayers.s3db"))
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = selectPrayers;
using (var reader = command.ExecuteReader())
{
while(reader.Read())
{
var id = reader.GetString(0);
var prayer = reader.GetString(1);
resultString += String.Format("Prayer {0}: {1}\n", id, prayer);
}
}
}
return ReplyAsync(resultString);
}
[Command("answerprayer")]
[Summary("Add's a prayer to the prayer DB")]
public Task AnswerPrayerAsync([Remainder][Summary("This prayer has been answered")] string id)
{
string updatePrayer = string.Format("update prayers set answered=1 where id=" + id);
using (var connection = new SqliteConnection("Data Source=prayers.s3db"))
{
connection.Open();
var command = connection.CreateCommand();
command.CommandText = updatePrayer;
command.ExecuteNonQuery();
}
return ReplyAsync(String.Format("Prayer {0} has been answered\n",id));
}
}
}
You need to use a simple timer in your code:
myTimer = new System.Timers.Timer(6 * 60 * 60 * 1000); //calculate six hours in milliseconds
myTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
myTimer.Start();
private static void OnTimedEvent(object sender, ElapsedEventArgs e)
{
YourMethod();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.