using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Net.Http; using System.Reflection; using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Telegram.Bot; using Telegram.Bot.Args; using Telegram.Bot.Types.ReplyMarkups; namespace ZaoBot { class Program { static ITelegramBotClient botClient; static JsonDocument config; static HttpClient http = new HttpClient(); const string CMD_WEATHER = "Погода"; const string CMD_LEFT_GATE = "Открой левые ворота"; const string CMD_RIGHT_GATE = "Открой правые ворота"; static bool shouldRestart = false; static void Main(string[] args) { CultureInfo.CurrentCulture = CultureInfo.InvariantCulture; config = LoadConfig(); var token = config.RootElement.GetProperty("token").GetString(); while (true) { try { shouldRestart = false; botClient = new TelegramBotClient(token); var me = botClient.GetMeAsync().Result; Console.WriteLine($"Hello, World! I am user {me.Id} and my name is {me.FirstName}."); botClient.OnMessage += OnBotMessage; botClient.StartReceiving(); while (!shouldRestart) { Thread.Sleep(1000); } } catch (Exception e) { // Тут ловим всё, при ошибках просто заново поднимаем бота Console.WriteLine("Exception: " + e.Message); Console.WriteLine(e.StackTrace); Console.WriteLine("Restarting bot"); } } } private static async void OnBotMessage(object sender, MessageEventArgs e) { try { if (e.Message.Text != null) { if (!VerifyUser(e.Message.Chat.Id, e.Message.Chat.Username)) { Console.WriteLine($"Received message {e.Message.Text} from invalid user {e.Message.Chat.Username}"); await botClient.SendTextMessageAsync( chatId: e.Message.Chat, text: "Ваш ID " + e.Message.Chat.Id + " сообщите его администратору" ); return; } Console.WriteLine($"Received a text message in chat {e.Message.Chat.Id}."); var response = ""; if (e.Message.Text == CMD_LEFT_GATE) { response = await OpenLeftGate(); } else if (e.Message.Text == CMD_RIGHT_GATE) { response = await OpenRightGate(); } else if (e.Message.Text == CMD_WEATHER) { response = await ShowWeather(); } else if (e.Message.Text == "") { response = "Превед!"; } else response = "Я не понял :-("; if (e.Message.Text != "") response += "\nЧто дальше?"; else response = "\nЧего изволите?"; var replyKeyboardMarkup = new ReplyKeyboardMarkup( new KeyboardButton[][] { new KeyboardButton[] { CMD_WEATHER }, new KeyboardButton[] { CMD_LEFT_GATE, CMD_RIGHT_GATE }, }, resizeKeyboard: true ); await botClient.SendTextMessageAsync( chatId: e.Message.Chat, text: response, replyMarkup: replyKeyboardMarkup ); } } catch (Exception ex) { Console.WriteLine("Exception: " + ex.Message); Console.WriteLine(ex.StackTrace); Console.WriteLine("Restarting bot"); shouldRestart = true; } } private static async Task ShowWeather() { try { string response = ""; foreach (var element in config.RootElement.GetProperty("items_weather").EnumerateObject()) { var url = config.RootElement.GetProperty("openhab_url").GetString(); url += element.Name; var result = await http.GetAsync(url); var content = await result.Content.ReadAsStringAsync(); response += element.Value + ": " + ParseContent(content) + "\n"; } return response; } catch (Exception e) { return "Fail: " + e.Message; } } private static string ParseContent(string content) { var doc = JsonDocument.Parse(content); float value; if (!float.TryParse(doc.RootElement.GetProperty("state").GetString(), out value)) { return "null"; } try { var stateDescription = doc.RootElement.GetProperty("stateDescription"); var pattern = stateDescription.GetProperty("pattern"); return printf.Printf.sprintf(pattern.GetString(), value); } catch (KeyNotFoundException) { return value.ToString(); } } private static async Task OpenRightGate() { var url = config.RootElement.GetProperty("openhab_url").GetString(); url += config.RootElement.GetProperty("item_right_gate").GetString(); return await Post(url, "ON"); } private static async Task Post(string url, string v) { var content = new ByteArrayContent(Encoding.UTF8.GetBytes(v)); content.Headers.Add("Content-Type", "text/plain"); var result = await http.PostAsync(url, content); if (result.IsSuccessStatusCode) return "OK"; else return "Fail. " + result.ReasonPhrase; } private static async Task OpenLeftGate() { var url = config.RootElement.GetProperty("openhab_url").GetString(); url += config.RootElement.GetProperty("item_left_gate").GetString(); return await Post(url, "ON"); } private static bool VerifyUser(long id, string username) { Console.WriteLine("Verify user " + username + " id " + id); foreach (var element in config.RootElement.GetProperty("valid_users").EnumerateArray()) { if (username == element.GetString()) { return true; } } foreach (var element in config.RootElement.GetProperty("valid_user_ids").EnumerateArray()) { if (id.ToString() == element.GetString()) { return true; } } return false; } private static JsonDocument LoadConfig() { string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var config = Path.Combine(assemblyFolder, "zaobot.json"); string configStr = File.ReadAllText(config); return JsonDocument.Parse(configStr); } } }