295 lines
12 KiB
C#
295 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Telegram.Bot;
|
|
using Telegram.Bot.Args;
|
|
using Telegram.Bot.Types;
|
|
using Telegram.Bot.Types.Enums;
|
|
using Telegram.Bot.Types.ReplyMarkups;
|
|
using Newtonsoft.Json;
|
|
using Telegram.Bot.Exceptions;
|
|
|
|
namespace TelegramRemindMe
|
|
{
|
|
public static class ReminderBot
|
|
{
|
|
private static List<ChatEntry> _chats = new List<ChatEntry>();
|
|
|
|
private static readonly TelegramBotClient Bot =
|
|
new TelegramBotClient("bot token here");
|
|
|
|
public static void Main()
|
|
{
|
|
Bot.OnMessage += BotOnMessageReceived;
|
|
Bot.OnMessageEdited += BotOnMessageReceived;
|
|
Bot.OnCallbackQuery += BotOnCallbackQueryReceived;
|
|
//Bot.OnInlineQuery += BotOnInlineQueryReceived;
|
|
//Bot.OnInlineResultChosen += BotOnChosenInlineResultReceived;
|
|
Bot.OnReceiveError += BotOnReceiveError;
|
|
if(!System.IO.File.Exists("config.json"))
|
|
SaveToJson(_chats);
|
|
_chats = ReadJson();
|
|
var me = Bot.GetMeAsync().Result;
|
|
|
|
Console.Title = me.Username;
|
|
|
|
Bot.StartReceiving();
|
|
Console.WriteLine($"Start listening for @{me.Username}");
|
|
Console.ReadLine();
|
|
Bot.StopReceiving();
|
|
}
|
|
|
|
private static async void BotOnMessageReceived(object sender, MessageEventArgs messageEventArgs)
|
|
{
|
|
var message = messageEventArgs.Message;
|
|
|
|
if (message == null || message.Type != MessageType.Text) return;
|
|
|
|
if (_chats.Find(e => e.ChatId == messageEventArgs.Message.Chat.Id) == null)
|
|
_chats.Add(new ChatEntry(messageEventArgs.Message.Chat.Id));
|
|
|
|
var currentChat = _chats.Find(e => e.ChatId == messageEventArgs.Message.Chat.Id);
|
|
|
|
if (message.Text.Equals("/cancel"))
|
|
{
|
|
SendOverview(currentChat, "Action canceled.");
|
|
return;
|
|
}
|
|
|
|
switch (currentChat.status)
|
|
{
|
|
case ChatStatusEnum.WaitingTaskTitle:
|
|
currentChat._tasklist.Add(new TaskEntry(message.Text));
|
|
//await Bot.SendChatActionAsync(message.Chat.Id, ChatAction.Typing);
|
|
SendOverview(currentChat, "Task added successfully!");
|
|
return;
|
|
case ChatStatusEnum.WaitingTaskComplete:
|
|
try
|
|
{
|
|
var completedItem = int.Parse(message.Text);
|
|
if (completedItem < 1 || completedItem > currentChat._tasklist.Count(p => !p.Completed))
|
|
throw new ArgumentOutOfRangeException();
|
|
|
|
currentChat._tasklist.FindAll(p => !p.Completed)[completedItem - 1].Completed = true;
|
|
SendOverview(currentChat, "Task has been set as completed.");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
SendOverview(currentChat, $"🛑 Invalid input! [{e.Message}]");
|
|
}
|
|
|
|
return;
|
|
case ChatStatusEnum.Idle:
|
|
break;
|
|
}
|
|
|
|
switch (message.Text.Split(' ').First())
|
|
{
|
|
default:
|
|
SendOverview(currentChat);
|
|
break;
|
|
|
|
case "/echo":
|
|
await Bot.SendChatActionAsync(message.Chat.Id, ChatAction.RecordVideoNote);
|
|
await Task.Delay(500);
|
|
await Bot.SendChatActionAsync(message.Chat.Id, ChatAction.UploadDocument);
|
|
await Task.Delay(500);
|
|
await Bot.SendChatActionAsync(message.Chat.Id, ChatAction.RecordAudio);
|
|
await Task.Delay(500);
|
|
await Bot.SendChatActionAsync(message.Chat.Id, ChatAction.Typing);
|
|
await Task.Delay(500);
|
|
await Bot.SendTextMessageAsync(
|
|
message.Chat.Id,
|
|
"MEOW, you woke me up!" + message.Text.Substring(5));
|
|
break;
|
|
}
|
|
}
|
|
|
|
private static async void BotOnCallbackQueryReceived(object sender,
|
|
CallbackQueryEventArgs callbackQueryEventArgs)
|
|
{
|
|
Console.WriteLine(
|
|
$"Received action request from @{callbackQueryEventArgs.CallbackQuery.Message.Chat.Username}: {callbackQueryEventArgs.CallbackQuery.Data}");
|
|
|
|
if (_chats.Find(e => e.ChatId == callbackQueryEventArgs.CallbackQuery.Message.Chat.Id) == null)
|
|
_chats.Add(new ChatEntry(callbackQueryEventArgs.CallbackQuery.Message.Chat.Id));
|
|
|
|
var currentChat = _chats.Find(e => e.ChatId == callbackQueryEventArgs.CallbackQuery.Message.Chat.Id);
|
|
|
|
switch (callbackQueryEventArgs.CallbackQuery.Data)
|
|
{
|
|
case "Add a new task":
|
|
currentChat.IsWorkingMessage = true;
|
|
//TODO: fix
|
|
try
|
|
{
|
|
currentChat.WorkingMsg = Bot.EditMessageTextAsync(
|
|
new ChatId(currentChat.ChatId), callbackQueryEventArgs.CallbackQuery.Message.MessageId,
|
|
"How should your new task be called?"
|
|
).Result.MessageId;
|
|
}
|
|
catch (ApiRequestException)
|
|
{}
|
|
currentChat.status = ChatStatusEnum.WaitingTaskTitle;
|
|
break;
|
|
case "Set a task as completed":
|
|
var sb = new StringBuilder();
|
|
var i = 0;
|
|
foreach (var entry in currentChat._tasklist.Where(p => !p.Completed))
|
|
{
|
|
sb.AppendLine($"{++i}) {entry.Title}");
|
|
}
|
|
|
|
sb.AppendLine();
|
|
sb.AppendLine("Send me the number of the task you want to complete.");
|
|
|
|
currentChat.IsWorkingMessage = true;
|
|
try
|
|
{
|
|
currentChat.WorkingMsg = Bot.EditMessageTextAsync(currentChat.ChatId,
|
|
callbackQueryEventArgs.CallbackQuery.Message.MessageId, sb.ToString()).Result.MessageId;
|
|
}
|
|
catch (ApiRequestException)
|
|
{}
|
|
|
|
currentChat.status = ChatStatusEnum.WaitingTaskComplete;
|
|
break;
|
|
case "Show all tasks":
|
|
currentChat.AllTasksShown = true;
|
|
currentChat.IsWorkingMessage = true;
|
|
currentChat.WorkingMsg = callbackQueryEventArgs.CallbackQuery.Message.MessageId;
|
|
SendOverview(currentChat);
|
|
currentChat.WorkingMsg = callbackQueryEventArgs.CallbackQuery.Message.MessageId;
|
|
await Bot.AnswerCallbackQueryAsync(callbackQueryEventArgs.CallbackQuery.Id, "Showing all tasks");
|
|
break;
|
|
case "Hide completed tasks":
|
|
currentChat.AllTasksShown = false;
|
|
currentChat.IsWorkingMessage = true;
|
|
currentChat.WorkingMsg = callbackQueryEventArgs.CallbackQuery.Message.MessageId;
|
|
SendOverview(currentChat);
|
|
await Bot.AnswerCallbackQueryAsync(callbackQueryEventArgs.CallbackQuery.Id,
|
|
"Showing only uncompleted tasks");
|
|
break;
|
|
default:
|
|
Console.WriteLine("Wat (Unknown callback action)");
|
|
await Bot.AnswerCallbackQueryAsync(
|
|
callbackQueryEventArgs.CallbackQuery.Id,
|
|
"Wat");
|
|
break;
|
|
}
|
|
}
|
|
|
|
private static async void SendOverview(ChatEntry chat, string prefixLine = "")
|
|
{
|
|
SaveToJson(_chats);
|
|
var actionKeyboard = new InlineKeyboardMarkup(new[]
|
|
{
|
|
new[]
|
|
{
|
|
InlineKeyboardButton.WithCallbackData("Add a new task"),
|
|
InlineKeyboardButton.WithCallbackData("Set a task as completed"),
|
|
},
|
|
new[]
|
|
{
|
|
InlineKeyboardButton.WithCallbackData(
|
|
chat.AllTasksShown ? "Hide completed tasks" : "Show all tasks")
|
|
}
|
|
});
|
|
|
|
//await Bot.SendChatActionAsync(chat.ChatId, ChatAction.Typing);
|
|
|
|
//TODO: why is this firing when workingmsg already deleted?
|
|
try
|
|
{
|
|
if (chat.IsWorkingMessage)
|
|
await Bot.DeleteMessageAsync(chat.ChatId, chat.WorkingMsg);
|
|
}
|
|
catch (ApiRequestException){}
|
|
|
|
chat.IsWorkingMessage = false;
|
|
chat.status = ChatStatusEnum.Idle;
|
|
|
|
var sb = new StringBuilder();
|
|
sb.AppendLine("Your tasks:");
|
|
|
|
if (chat.AllTasksShown)
|
|
{
|
|
foreach (var task in chat._tasklist)
|
|
{
|
|
sb.Append(task.Completed ? "✅ " : "🔶 ");
|
|
sb.AppendLine(task.Title);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var task in chat._tasklist.Where(p => !p.Completed))
|
|
{
|
|
sb.Append("🔶 ");
|
|
sb.AppendLine(task.Title);
|
|
}
|
|
}
|
|
|
|
sb.AppendLine();
|
|
sb.AppendLine("What do you want me to do?");
|
|
|
|
if (prefixLine != "")
|
|
{
|
|
var msgid = Bot.SendTextMessageAsync(
|
|
chat.ChatId,
|
|
prefixLine)
|
|
.Result.MessageId;
|
|
|
|
//await Bot.SendChatActionAsync(chat.ChatId, ChatAction.Typing);
|
|
//await Task.Delay(1500);
|
|
await Bot.EditMessageTextAsync(chat.ChatId, msgid, sb.ToString(), replyMarkup: actionKeyboard);
|
|
}
|
|
else
|
|
{
|
|
//await Bot.SendChatActionAsync(chat.ChatId, ChatAction.Typing);
|
|
await Bot.SendTextMessageAsync(chat.ChatId, sb.ToString(), replyMarkup: actionKeyboard);
|
|
}
|
|
}
|
|
|
|
private static void BotOnReceiveError(object sender, ReceiveErrorEventArgs receiveErrorEventArgs)
|
|
{
|
|
Console.WriteLine("Received error: {0} — {1}",
|
|
receiveErrorEventArgs.ApiRequestException.ErrorCode,
|
|
receiveErrorEventArgs.ApiRequestException.Message);
|
|
}
|
|
|
|
private static void SaveToJson(List<ChatEntry> chats)
|
|
{
|
|
var str = JsonConvert.SerializeObject(chats);
|
|
while (true)
|
|
{
|
|
try
|
|
{
|
|
System.IO.File.WriteAllText("config.json", str);
|
|
break;
|
|
}
|
|
catch
|
|
{
|
|
Console.WriteLine("Unable to write to config.json, retrying...");
|
|
}
|
|
}
|
|
}
|
|
|
|
private static List<ChatEntry> ReadJson()
|
|
{
|
|
while (true)
|
|
{
|
|
try
|
|
{
|
|
var str = System.IO.File.ReadAllText("config.json");
|
|
return JsonConvert.DeserializeObject<List<ChatEntry>>(str);
|
|
}
|
|
catch
|
|
{
|
|
Console.WriteLine("Unable to read from config.json, retrying...");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |