Русский
Русский
English
Статистика
Реклама

Sms-сервис

Конвертация скрипта Bash в код С для отправки СМС через usb модем HUAWEI E3372

17.06.2020 16:18:48 | Автор: admin
Несколько моих проектов отправляют СМС и в последнее время после обновлений сервера, а может и ряда других причин, отправка СМС стала почти невозможной.

Старенький USB модем HUAWEI (марку не буду разглашать) перестал стабильно висеть на одном COM порту и временами переподключался на другие порты, совсем отключался и терял антенну.

Да и ситуация с библиотекой GSMComm была непонятной и болезненной.

GSMComm это пакет для телефонов GSM, в основном для выполнения задач, связанных с SMS.
www.nuget.org/packages/GSMComm последня версия 1.21.1 от 10.10.2015 года.


Поиск по интерент показал, что есть возможность использовать встроенный функционал WEB API новых модемов HUAWEI, более эффективно, чем старый подход с AT командами реализованный в GSMComm.

Выяснилось, что есть прекрасный usb модем HUAWEI E3372, который почти хакерским способом способен отправлять СМС как из скрипта (Curl + Bash), так и из кода (Python, Perl), и, как я предположил, из C#.

Самое печальное, что компания HUAWEI не предоставляет никакой документации как это сделать и все найденные методы имели экспериментальный харктер и зависели от семейства устройств.

В общем, опираясь на найденный материал, не гарантирующий работу кода с момедом, был приобретен HUAWEI E3372.

Не углублясь в эксперименты с Python или Perl я решил попробовать разобраться с вариантами Bash + Curl.

В общем, после нескольких экспериментов был найден работающий код под MS Windows 10 + Git Bash for MS Windows.

Скрипт

curl -b session.txt -c session.txt http://192.168.8.1/html/index.html > /dev/null 2>&1#TOKEN=$(curl -s -b session.txt -c session.txt http://192.168.8.1/html/smsinbox.html)TOKEN=$(echo $TOKEN | cut -d'"' -f 10)echo $TOKEN > token.txtNUMBER=$1MESSAGE=$2LENGTH=${#MESSAGE}TIME=$(date +"%Y-%m-%d %T")TOKEN=$(<token.txt)SMS="<?xml version='1.0' encoding='UTF-8'?><request><Index>-1</Index><Phones><Phone>$NUMBER</Phone></Phones><Sca/><Content>$MESSAGE</Content><Length>$LENGTH</Length><Reserved>1</Reserved><Date>$TIME</Date></request>"echo $SMScurl -v -b session.txt -c session.txt -H "X-Requested-With: XMLHttpRequest" --data "$SMS" http://192.168.8.1/api/sms/send-sms --header "__RequestVerificationToken: $TOKEN" --header "Content-Type:text/xml" --header "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" --header "Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3"


Скрипт удивительным образом работал. И это было уже счастье, так как деньги были потрачены на модем не зря!

Осталось только понять КАК же он работает. Почитав документацию по Curl и Bash (ну по bash я не читал так догадался) прояснилась работа скрипта. Привожу этот же скрипт с моими комментариями.

Скрипт с комментариями

# https://stackoverflow.com/questions/28070500/grab-current-sessions-cookie-with-curl/28070870# Содержимое файла session.txt определяется опцией -b# Сделать GET запрос и получить куки в первый раз и записать их в файлcurl -b session.txt -c session.txt http://192.168.8.1/html/index.html > /dev/null 2>&1# Сделать GET запрос и получить куки во второй раз и записать в файл и сохранить содержимое страницы HTML в переменную TOKEN как строкуTOKEN=$(curl -b session.txt -c session.txt http://192.168.8.1/html/smsinbox.html)# Извлчеь из переменной значение метатега из <meta name="csrf_token" content="b/XNeODpHCthQXEOEjBNkICn2n7e9v4e"/> и перезаписать в ту же переменную TOKENTOKEN=$(echo $TOKEN | cut -d'"' -f 10)# Отобразить на экранеecho "$TOKEN"# сохранить подстроку в файлеecho $TOKEN > token.txt# Получить два параметра командной строки: (1) номер телефона и (2) текст СМСNUMBER=$1MESSAGE=$2# Получить количество символов в текстеLENGTH=${#MESSAGE}# Получить текущее время и отформатировать егоTIME=$(date +"%Y-%m-%d %T")# Загрузить содержимое файла в переменнуюTOKEN=$(<token.txt)# Сфоромировать текст для отправки СМС как XML SMS="<?xml version='1.0' encoding='UTF-8'?><request><Index>-1</Index><Phones><Phone>$NUMBER</Phone></Phones><Sca/><Content>$MESSAGE</Content><Length>$LENGTH</Length><Reserved>1</Reserved><Date>$TIME</Date></request>"# Отобразить переменную с текстом СМС на экране echo $SMS# Сделать POST для отправки СМСcurl -v -b session.txt -c session.txt -H "X-Requested-With: XMLHttpRequest" --data "$SMS" http://192.168.8.1/api/sms/send-sms --header "__RequestVerificationToken: $TOKEN" --header "Content-Type:text/xml"

Скажу честно, что СМС на русском я не смог добиться. Приходит абракадабра. Так что этот вопрос остался открытым и если
у кого-то есть желание закрыть тему отправки СМС на русском милости просим, дерзайте. )))

Понимание работы скрипта принесло свою пользу и приблизило к написанию кода на C#.

Было понятно, что в нем должно быть также 3 запроса и должны они делать то же самое что и благословенный Curl. Поэтому в коде приведен Curl, а ниже, аналогичный ему C# код.

Код С# для WinForms

private void button1_Click(object sender, EventArgs e){   var ip = "192.168.8.1"; // IP адрес который выдает модем в браузере после установки   var phone = "+70000000000"; // Номер телефона   var msg = "Привет!!! СМС работает!!!";   var result = SendSMS(ip, phone, msg);   if (result)   {       //TODO  Сохранить в БД, например   }   else   {       //TODO  Сохранить в БД, например   }}private bool SendSMS(string ip, string phone, string msg){    try    {        /* curl -b session.txt -c session.txt http://192.168.8.1/html/index.html > /dev/null 2>&1 */        Cookie firstCookie = null;        Cookie secondCookie = null;        string token = string.Empty;        //В первый раз получить куки        var cookieContainer = new CookieContainer();        var uri = new Uri($"http://{ip}/html/index.html");        using (var httpClientHandler = new HttpClientHandler { CookieContainer = cookieContainer })        {            using (var httpClient = new HttpClient(httpClientHandler))            {                httpClient.GetAsync(uri).Wait();                var all = cookieContainer.GetCookies(uri);                firstCookie = all[0];            }        }        /*        TOKEN=$(curl -s -b session.txt -c session.txt http://192.168.8.1/html/smsinbox.html)        TOKEN=$(echo $TOKEN | cut -d'"' -f 10)        echo $TOKEN > token.txt         */    // И спользуя куки из первого запроса получить страницу и извлечь из нее токен        if (firstCookie != null)        {            var cookieContainer2 = new CookieContainer();            cookieContainer2.Add(firstCookie); // Поместить в конейнер куки из первого запроса к сайту            var uri2 = new Uri($"http://{ip}/html/smsinbox.html");            using (var httpClientHandler = new HttpClientHandler            {                CookieContainer = cookieContainer2            })            {                using (var httpClient = new HttpClient(httpClientHandler))                {                    var html = httpClient.GetStringAsync(uri2).Result; // Получить страницу HTML                    var all = cookieContainer2.GetCookies(uri2);                    secondCookie = all[0];                    var doc = new HtmlAgilityPack.HtmlDocument(); // Используем HtmlAgilityPack чтобы преобразовать текст HTML в структурный вид                     doc.LoadHtml(html);                    var items = doc.DocumentNode.SelectNodes("//meta");                    if (items.Count >= 2) // Получить второй по счету meta тег.                    {                        token = items[1].GetAttributeValue("content", ""); // Получить значение метатега. Не спрашивайтепочему второй метатаг с токеном рабочий - не знаю )))                    }                }            }            // Когда в наличии есть куки и токен делаем отправку СМС через запрос POST            if (!string.IsNullOrEmpty(token))            {                var msgLength = msg.Length;                var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); //    TIME=$(date +"%Y-%m-%d %T")                var sms = $"<?xml version='1.0' encoding='UTF-8'?><request><Index>-1</Index><Phones><Phone>{phone}</Phone></Phones><Sca/><Content>{msg}</Content><Length>{msgLength}</Length><Reserved>1</Reserved><Date>{time}</Date></request>";                /*# Сделать POST для отправки СМС                  curl -v -b session.txt -c session.txt -H "X-Requested-With: XMLHttpRequest" --data "$SMS"                     http://192.168.8.1/api/sms/send-sms  --header "__RequestVerificationToken: $TOKEN"  --header "Content-Type:text/xml"                 */                var uri3 = new Uri($"http://{ip}/api/sms/send-sms");                var client = new RestSharp.RestClient { BaseUrl = uri3 }; // Используем RestSharp для запроса (дело вкуса)                var request = new RestSharp.RestRequest(RestSharp.Method.POST);                // Формируем свой заголовой запроса - ничего лишненго все по примеру из Curl    request.AddHeader("__RequestVerificationToken", token);                var ses = secondCookie.ToString();                request.AddCookie("cookie", ses);                request.AddHeader("Content-Type", "text/xml");                request.AddHeader("X-Requested-With", "XMLHttpRequest");                request.AddParameter("text/html", sms, RestSharp.ParameterType.RequestBody);                RestSharp.IRestResponse response = client.Execute(request);                if (response.IsSuccessful)                {                    var xmlDoc = new XmlDocument();                    xmlDoc.LoadXml(response.Content); // <?xml version="1.0" encoding="UTF-8"?><response> OK </response>                    var responseElemenets = xmlDoc.GetElementsByTagName("response");                    var resultOK = responseElemenets[0].InnerXml.ToLower();                    return resultOK == "ok"; // Ну вот и признак того, что СМС отправлено, но без отчета о доставке.                 }            }        }    }    catch (Exception)    {        //TODO в лог ошибку;    }    return false;}


Как только у вас в руках рабочий C# код вы всегда можете его улучшить.

В моем случае он работает как часы и для количества СМС в минуту вполне годится. )))

Надеюсь эта статься принелса пользу и в профессиональном и экономическом смыслах.

Душевно благодарю!
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru