public async void ListenerCallback(IAsyncResult result) { HttpListener listener = (HttpListener)result.AsyncState; if (!listener.IsListening) { string err_msg = "!listener.IsListening"; Log.Debug(TAG, err_msg); logsDB.AddLogRow(LogStatusesEnum.Error, err_msg, TAG); return; } // Call EndGetContext to complete the asynchronous operation. HttpListenerContext context = listener.EndGetContext(result); HttpListenerRequest request = context.Request; string remote_ip_address = request.RemoteEndPoint.Address.ToString(); string s_request = $"ListenerCallback() - request: {request.Url} from > {remote_ip_address}"; Log.Debug(TAG, s_request); logsDB.AddLogRow(LogStatusesEnum.Info, s_request, TAG); // Obtain a response object. HttpListenerResponse response = context.Response; Android.Net.Uri uri = Android.Net.Uri.Parse(request.Url.ToString()); string pt = uri.GetQueryParameter("pt"); string dir = uri.GetQueryParameter("dir"); string mdid = uri.GetQueryParameter("mdid"); string v = uri.GetQueryParameter("v"); string value = uri.GetQueryParameter("value"); string st = uri.GetQueryParameter("st"); string m = uri.GetQueryParameter("m"); string click = uri.GetQueryParameter("click"); string cnt = uri.GetQueryParameter("cnt"); HardwareModel hardware; string hw_name = string.Empty; lock (DatabaseContext.DbLocker) { using (DatabaseContext db = new DatabaseContext(gs.DatabasePathBase)) { hardware = db.Hardwares.FirstOrDefault(x => x.Address == remote_ip_address); } } hw_name = hardware?.Name ?? string.Empty; if (string.IsNullOrEmpty(hw_name)) { hw_name = remote_ip_address; } else { hw_name += $" ({remote_ip_address})"; } string bot_message = $"Сообщение от устройства \"{hw_name}\": {Environment.NewLine}"; if (!string.IsNullOrWhiteSpace(pt)) { if (Regex.IsMatch(pt, @"^\d+$")) { PortModel portHardware = null; int pt_num_int = -1; pt_num_int = int.Parse(pt); if (pt_num_int > -1 && hardware != null) { lock (DatabaseContext.DbLocker) { using (DatabaseContext db = new DatabaseContext(gs.DatabasePathBase)) { portHardware = db.Ports.FirstOrDefault(x => x.HardwareId == hardware.Id && x.PortNumb == pt_num_int); } } if (portHardware != null) { Log.Debug(TAG, "Поиск триггера"); List <ScriptModel> scripts_triggers = null; lock (DatabaseContext.DbLocker) { using (DatabaseContext db = new DatabaseContext(gs.DatabasePathBase)) { scripts_triggers = db.Scripts.Where(x => x.TriggerPortId == portHardware.Id).Include(x => x.Commands).ToList(); } } if (scripts_triggers != null && scripts_triggers.Count > 0) { Log.Debug(TAG, $"Нaйдено триггеров: {scripts_triggers.Count}"); foreach (ScriptModel trigger_script in scripts_triggers) { string url_request_port_state = $"http://{hardware.Address}/{hardware.Password}/?pt={pt}&cmd=get"; Log.Debug(TAG, $"Зпрос состояния порта: {url_request_port_state}"); HttpWebRequest request_port_state = new HttpWebRequest(new Uri(url_request_port_state)) { Timeout = 5000 }; try { using (HttpWebResponse response_port_state = (HttpWebResponse)request_port_state.GetResponse()) { if (response_port_state.StatusCode == HttpStatusCode.OK) { string responseFromServer = string.Empty; using (Stream dataStream = response_port_state.GetResponseStream()) using (StreamReader reader = new StreamReader(dataStream)) { responseFromServer = reader.ReadToEnd(); } if (string.IsNullOrEmpty(responseFromServer)) { //"Пустой ответ устройства."; continue; } else if (responseFromServer.ToLower() == "unauthorized") { //"Пароль, указаный в настройкх устройства не подошёл."; continue; } else { Log.Debug(TAG, $"Cостояние порта: {responseFromServer}"); if ((trigger_script.TriggerPortState == true && !responseFromServer.ToLower().StartsWith("on/")) || (trigger_script.TriggerPortState == false && responseFromServer.ToLower().StartsWith("off/"))) { continue; } } } else { //$"Ошибка выполнения запроса. StatusCode:\"{response.StatusCode}\"; StatusDescription:\"{response.StatusDescription}\""; continue; } } } catch (Exception ex) { //$"Сбой обработки команды:{ex.Message}"; continue; } TaskModel task; lock (DatabaseContext.DbLocker) { using (DatabaseContext db = new DatabaseContext(gs.DatabasePathBase)) { task = new TaskModel() { Name = "http trigger", TaskInitiatorType = TaskInitiatorsTypes.Trigger, TaskInitiatorId = hardware.Id, ScriptId = trigger_script.Id }; db.Tasks.Add(task); db.SaveChanges(); } } BackgroundWorker bw = new BackgroundWorker(); bw.DoWork += new DoWorkEventHandler(aForegroundService.RunScriptAction); bw.ProgressChanged += (object sender, ProgressChangedEventArgs e) => { }; bw.RunWorkerCompleted += (object sender, RunWorkerCompletedEventArgs e) => { }; bw.RunWorkerAsync(task); } } } } if (!string.IsNullOrWhiteSpace(pt) && string.IsNullOrWhiteSpace(portHardware?.Name)) { pt = $"Порт: P{pt}; "; } else { pt = $"Порт: \"{portHardware.Name}\" (P{pt}); "; } } else { pt = $"Порт: {pt}; "; } bot_message += $"{pt}"; } if (!string.IsNullOrWhiteSpace(m)) { m = (m == "1" ? "Освобождние после длительного удержания" : $"Длительное удержание") + "; "; bot_message += $"{m}"; } if (!string.IsNullOrWhiteSpace(click)) { click = (click == "1" ? "обычный клик" : "двойной клик") + "; "; bot_message += $"{click}"; } if (!string.IsNullOrWhiteSpace(dir)) { if (dir == "0")//падение значения { dir = "Значение опустилось ниже порога; "; } else if (dir == "1")//повышение знчения { dir = "Значение превышает пороговое; "; } else { dir = $"ошибка определения вектора 'dir':{dir}; "; } bot_message += $"{dir}"; } if (!string.IsNullOrWhiteSpace(mdid)) { mdid = $"mdid=\"{mdid}\"; "; bot_message += $"{mdid}"; } if (!string.IsNullOrWhiteSpace(st)) { st = $"st=\"{st}\"; "; bot_message += $"{st}"; } if (!string.IsNullOrWhiteSpace(v)) { v = $"v=\"{v}\"; "; bot_message += $"{v}"; } if (!string.IsNullOrWhiteSpace(value)) { value = $"value=\"{value}\"; "; bot_message += $"{value}"; } string token = Preferences.Get(Constants.TELEGRAM_TOKEN, string.Empty); if (!string.IsNullOrWhiteSpace(token)) { TelegramClientCore telegramClient = new TelegramClientCore(token); if (telegramClient?.Me != null) { List <UserModel> users; lock (DatabaseContext.DbLocker) { using (DatabaseContext db = new DatabaseContext(gs.DatabasePathBase)) { users = db.Users.Where(x => x.AlarmSubscriber).ToList(); } } List <TelegramUserModel> t_users; foreach (UserModel user in users) { lock (DatabaseContext.DbLocker) { using (DatabaseContext db = new DatabaseContext(gs.DatabasePathBase)) { t_users = db.TelegramUsers.Where(xx => xx.LinkedUserId == user.Id).ToList(); } } foreach (TelegramUserModel telegramUser in t_users) { await telegramClient.sendMessage(telegramUser.TelegramId.ToString(), bot_message.Trim()); } } } } string log_msg = $"incoming http request (from > {remote_ip_address}): {request.Url.Query}"; //log_msg = "telegramClient?.Me == null"; //Log.Info(TAG, log_msg); //using (LogsContext log = new LogsContext()) //{ // log.AddLogRow(LogStatusesEnum.Info, log_msg, TAG); //} // Construct a response. string responseString = "Hello world!"; byte[] buffer = Encoding.UTF8.GetBytes(responseString); // Get a response stream and write the response to it. response.ContentLength64 = buffer.Length; System.IO.Stream output = response.OutputStream; await output.WriteAsync(buffer, 0, buffer.Length); // You must close the output stream. output.Close(); result = httpServer.BeginGetContext(new AsyncCallback(ListenerCallback), httpServer); }
/// <summary> /// Сканировать входящий Telegram.Update /// </summary> public void UpdateNew(Update u) { IncUpdate = u; UpdateNew(); Log.WriteLine((IsAdminSender ? "Administrator" : "User") + FullNameSender, IsAdminSender ? LogStatusEnum.Notice : LogStatusEnum.Norma); if (ChatType == ChatTypes.Group || ChatType == ChatTypes.Supergroup) { Regex rex = new Regex(@"^/\w[\w\d_]+@" + telegram_client.Me.username + "$", RegexOptions.IgnoreCase); if (CompositionTypes.Exists(x => x == TelegramDataTypes.Text) && rex.IsMatch(IncUpdate.message.text)) { telegram_client.sendMessage(IncUpdate.message.chat.id.ToString(), "Для общения с ботом напишите ему напрямую @" + telegram_client.Me.username, null, false, false, IncUpdate.message.chat.id); return; } if (ScanSpamMatches.Count > 0) { NotifyAdmins(MatchesReport); if (AutoDelete && !IsAdminSender && ScanSpamMatches.Exists(x => x.LevelMatch == LevelMatches.Block)) { telegram_client.deleteMessage(u.message.chat.id.ToString(), u.message.message_id); } } } if (!string.IsNullOrEmpty(WebhookAddress) && !string.IsNullOrEmpty(hmac_key) && !string.IsNullOrEmpty(hmac_secret)) { string postData = glob_tools.SerialiseJSON(this); string responsebody; // HttpWebRequest request; Stream requestStream; request = (HttpWebRequest)WebRequest.Create(WebhookAddress); request.ContentType = "application/json"; request.Method = "POST"; HmacHttpWebRequest hmacHttp = new HmacHttpWebRequest(hmac_key, hmac_secret); request = hmacHttp.SignRequest(request); requestStream = request.GetRequestStream(); byte[] byteArray = Encoding.UTF8.GetBytes(postData); request.ContentLength = byteArray.Length; requestStream.Write(byteArray, 0, byteArray.Length); requestStream.Close(); try { using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { if (!hmacHttp.VerifyResponse(response)) { Log.WriteLine("Ответ API Webhook не подписан или подписан не действительной поджписью", LogStatusEnum.Alarm); return; } Log.WriteLine("HMAC API Webhook подпись проверена", LogStatusEnum.Happi); using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8, true)) { if (response.StatusCode == HttpStatusCode.OK) { responsebody = reader.ReadToEnd(); if (string.IsNullOrEmpty(responsebody)) { Log.WriteLine("API HMAC JSON - вернул пустой ответ", LogStatusEnum.Alarm); } else { try { ResultHmacResponseClass resultHmac = (ResultHmacResponseClass)glob_tools.DeSerialiseJSON(typeof(ResultHmacResponseClass), responsebody); Log.Write("API HMAC JSON - прочитан "); Log.WriteLine(resultHmac.status.ToString("g"), resultHmac.status == StatusResult.Ok ? LogStatusEnum.Happi : LogStatusEnum.Alarm); } catch (Exception e) { Log.WriteLine("API HMAC JSON - ошибка. " + e.Message, LogStatusEnum.Alarm); } } } else { Log.WriteLine("API HTTP-CODE: " + response.StatusCode.ToString("g") + ". HTTP-DESC: " + response.StatusDescription + ".", LogStatusEnum.Alarm); } } } } catch (Exception e) { Log.WriteLine("API HMAC JSON - HTTP-ошибка. " + e.Message, LogStatusEnum.Alarm); } } }