Страница 1 из 2
Send SMS messages via Huawei LTE modem API (tested with E3372)
Добавлено: 24 янв 2023, 11:37
Sertik
Один похоже наш Чувак написал скрипт передачи SMS через WEB API прошивки Hlink модема Huawey E3372
https://forum.mikrotik.com/viewtopic.php?t=166859
Я проверял, у меня не работает. Надо бы проверить у кого есть такие модемы. В чём проблема, может у меня прошивка старая ...
Код: Выделить всё
:global sendSMS do={
# Send SMS messages via Huawei LTE modem API (tested with E3372)
# global vars:
# lteIP - lte modem ip address (api)
# phone - sms destination phone number
# sms - sms text message
# usage example
# :global sendSMS
# :put [$sendSMS lteIP="192.168.8.1" phone="+35912345678" sms="test sms via lte api"]
#
:local getBetween do={
# "CuriousKiwi - mikrotik forum"
# This is a basic parser, can be used for XML
# It takes three parameters:
# inputString - The main string
# betweenStart - Text AFTER this point will be returned
# betweenEnd - Text BEFORE this point will be returned
:local posStart 0;
:if ([:len $betweenStart] > 0) do={
:set posStart [:find $inputString $betweenStart]
:if ([:len $posStart] = 0) do={
:set posStart 0
} else={
:set posStart ($posStart + [:len $betweenStart])
}
}
:local posEnd 9999;
:if ([:len $betweenEnd] > 0) do={
:set posEnd [:find $inputString $betweenEnd];
:if ([:len $posEnd] = 0) do={ :set posEnd 9999 }
}
:local result [:pick $inputString $posStart $posEnd];
:return $result;
}
# get SessionID and Token via LTE modem API
:local urlSesTokInfo "http://$lteIP/api/webserver/SesTokInfo";
:local api [/tool fetch $urlSesTokInfo output=user as-value];
:local apiData ($api->"data");
# pars SessionID and Token from API session data
:local apiSessionID [$getBetween inputString=$apiData betweenStart="<SesInfo>" betweenEnd="</SesInfo>"];
:local apiToken [$getBetween inputString=$apiData betweenStart="<TokInfo>" betweenEnd="</TokInfo>"];
# header and data config
:local apiHead "Content-Type:application/x-www-form-urlencoded,Cookie: $apiSessionID,__RequestVerificationToken:$apiToken";
:local sendData "<?xml version=\"1.0\" encoding=\"UTF-8\"?><request><Index>-1</Index><Phones><Phone>$phone</Phone></Phones><Sca></Sca><Content>$sms</Content><Length>-1</Length><Reserved>1</Reserved><Date>-1</Date></request>";
# send SMS via LTE modem API with fetch
/tool fetch http-method=post output=user \
http-header-field=$apiHead \
url="http://$lteIP/api/sms/send-sms" \
http-data=$sendData;
}
Re: Send SMS messages via Huawei LTE modem API (tested with E3372)
Добавлено: 25 янв 2023, 12:53
Sertik
Просьба отписаться сюда у кого скрипт заработает.
Re: Send SMS messages via Huawei LTE modem API (tested with E3372)
Добавлено: 28 янв 2023, 21:04
SergeyN
Проверил, работает.
С датой отправки только глюк
Re: Send SMS messages via Huawei LTE modem API (tested with E3372)
Добавлено: 30 янв 2023, 13:34
Sertik
Сергей, спасибо, что ответили.
Какая у Вас версия прошивки модема ? Если можно прямо скрин киньте сюда из Web-интерфйса.
И какая у Вас версия РоутерОС ?
Re: Send SMS messages via Huawei LTE modem API (tested with E3372)
Добавлено: 30 янв 2023, 13:45
Sertik
А это функция для получения SMS:
Код: Выделить всё
:global recvSMS do={
:local getBetween do={
# This is a basic parser, can be used for XML
# It takes three parameters:
# inputString - The main string
# betweenStart - Text AFTER this point will be returned
# betweenEnd - Text BEFORE this point will be returned
:local posStart 0;
:if ([:len $betweenStart] > 0) do={
:set posStart [:find $inputString $betweenStart]
:if ([:len $posStart] = 0) do={
:set posStart 0
} else={
:set posStart ($posStart + [:len $betweenStart])
}
}
:local posEnd 9999;
:if ([:len $betweenEnd] > 0) do={
:set posEnd [:find $inputString $betweenEnd];
:if ([:len $posEnd] = 0) do={ :set posEnd 9999 }
}
:local result [:pick $inputString $posStart $posEnd];
:return $result;
}
# get SessionID and Token via LTE modem API
:local urlSesTokInfo "http://$lteIP/api/webserver/SesTokInfo";
:local api [/tool fetch $urlSesTokInfo output=user as-value];
:local apiData ($api->"data");
:local lteIP "192.168.8.1";
# pars SessionID and Token from API session data
:local apiSessionID [$getBetween inputString=$apiData betweenStart="<SesInfo>" betweenEnd="</SesInfo>"];
:local apiToken [$getBetween inputString=$apiData betweenStart="<TokInfo>" betweenEnd="</TokInfo>"];
# header and data config
:local apiHead "Content-Type:application/x-www-form-urlencoded,Cookie: $apiSessionID,__RequestVerificationToken:$apiToken";
:local recvData "<?xml version=\"1.0\" encoding=\"UTF-8\"?><request><PageIndex>1</PageIndex><ReadCount>20</ReadCount><BoxType>1</BoxType><SortType>0</SortType><Ascending>0</Ascending><UnreadPreferred>0</UnreadPreferred></request>";
# recv SMS via LTE modem API with fetch
/tool fetch http-method=post output=user \
http-header-field=$apiHead \
url="http://$lteIP/api/sms/sms-list" \
http-data=$recvData;
}
:local arrData [ :toarray $recvSMS ];
:local varData ( $arrData->"data" );
:put [ $varData ];
Re: Send SMS messages via Huawei LTE modem API (tested with E3372)
Добавлено: 31 янв 2023, 08:40
SergeyN
Имя устройства: E3372h
Версия АО: CL2E3372HM
Версия ПО: 22.200.09.01.161
Версия веб-интерфейса: 17.100.17.00.143-Mod1.20
RBD53GR-5HacD2HnD
6.49.2 (stable)
Re: Send SMS messages via Huawei LTE modem API (tested with E3372)
Добавлено: 31 янв 2023, 12:07
Sertik
Спасибо, Сергей !
Соответственно Вашим данным, у меня получается версия ПО новее Вашей, а версия WEB-интерфейса более древняя ...
версия AO: CL2e3372HM
версия ПО: 22.333.01.00.00
версия WEB-интерфейса: 17.100.13.112.03 (17.100.13.01.03_Mod1.12)
Видимо надо попробовать проапгрейдить именно WEB-морду.
Re: Send SMS messages via Huawei LTE modem API (tested with E3372)
Добавлено: 09 фев 2023, 15:39
Sertik
Дело пошло. Один добрый человек создал уже много хороших скриптов для работы с CMC модемов Huawey 3372 из РоутерОС.
Вот ссылка
https://forum.mikrotik.com/viewtopic.ph ... 59#p982972
Кстати у меня эти скрипты тоже заработали. Оказалось, что проблема была в установленном пароле WEB-интерфейса моего модема. Снес пароль - всё работает ! Видимо API не расчитано для доступа в защищенном режиме или скрипты не умеют авторизоваться при fetch. Будущее покажет, а пока можно пользоваться готовыми скриптами.
Re: Send SMS messages via Huawei LTE modem API (tested with E3372)
Добавлено: 10 фев 2023, 18:54
Sertik
Положу эту коллекцию скриптов сюда, тут надежнее.
Collection of Huawei API scripts for use with MikroTik
(Tested on a Huawei E3372h-320 & E3372h-153 modems
by pkt & diamuxin
https://forum.mikrotik.com/viewtopic.ph ... 59#p982972
Token Parser Library
(Main Script base)
Код: Выделить всё
# TOKEN PARSER LIBRARY
# v1.0.0 pkt
# :put [($tokenParser->"getTag") source=$xml tag="SessionInfo"]
# ($tokenParser->"getBetween")
# get delimited value
# source - source string
# fromTok - (optional) text AFTER this token (or from source beginning) will be returned
# toTok - (optional) text BEFORE this token (or until source finish) will be returned
# startPos - (optional) start position (default 0 = beginning)
# returns an array with fields data and pos
#
# ($tokenParser->"getTag")
# get value for XML tag
# source - xml string
# tag - tag which value is to be returned
# startPos - (optional, text index) start position (if not specified, it will search from the beginning of the string)
# returns the tag content
#
# ($tokenParser->"getTagDetailed")
# get value and end position for XML tag
# source - xml string
# tag - tag which value is to be returned
# startPos - (optional, text index) start position (if not specified, it will search from the beginning of the string)
# returns an array with fields "data" (tag content) and "pos" (where tag ends)
#
# ($tokenParser->"getTagList")
# get a list with the content of each appearance of tag
# source - xml string
# tag - tag which value is to be returned
# returns an array with tag contents
#
# ($tokenParser->"forEachTag")
# incremental parser that calls the callback with the content of each appearance of tag
# source - xml string
# tag - tag which value is to be returned
# callback - callback (with param content) to be called for each appearance of tag
# callbackArgs - callback will be called passing this value in param args
:global tokenParser ({})
:set ($tokenParser->"getBetween") do={ # get delimited value
# source - source string
# fromTok - (optional) text AFTER this token (or from source beginning) will be returned
# toTok - (optional) text BEFORE this token (or until source finish) will be returned
# startPos - (optional) start position (default 0 = beginning)
# returns an array with fields data and pos
# if fromTok and/or toTok are specified and neither of them appear in source, empty string "" will be returned as data
# based on function getBetween by CuriousKiwi, modified by pkt
:local posStart
if ([:len $startPos] = 0) do={
:set posStart -1
} else={
:set posStart ($startPos-1)
}
:local found true
:local data
:local resultStart
:if ([:len $fromTok] > 0) do={
:set resultStart [:find $source $fromTok $posStart]
:if ([:len $resultStart] = 0) do={ # start token not found
:set found false
:set data ""
}
:set resultStart ($resultStart + [:len $fromTok])
} else={
:set resultStart 0
}
:local resultEnd
:if (found = true && [:len $toTok] > 0) do={
:set resultEnd [:find $source $toTok ($resultStart-1)]
:if ([:len $resultEnd] = 0) do={ # end token not found
:set found false
:set data ""
}
} else={
:set resultEnd [:len $source]
}
:if ($found = true) do={ :set data [:pick $source $resultStart $resultEnd] }
:return { data=$data; pos=$resultEnd }
}
:set ($tokenParser->"getTag") do={ # get value for XML tag
# source - xml string
# tag - tag which value is to be returned
# startPos - (optional, text index) start position (if not specified, it will search from the beginning of the string)
# returns the tag content
:global tokenParser
:return ([($tokenParser->"getBetween") source=$source fromTok=("<$tag>") toTok=("</$tag>") startPos=$startPos]->"data")
}
:set ($tokenParser->"getTagDetailed") do={ # get value and end position for XML tag
# source - xml string
# tag - tag which value is to be returned
# startPos - (optional, text index) start position (if not specified, it will search from the beginning of the string)
# returns an array with fields "data" (tag content) and "pos" (where tag ends)
:global tokenParser
:return [($tokenParser->"getBetween") source=$source fromTok=("<$tag>") toTok=("</$tag>") startPos=$startPos]
}
:set ($tokenParser->"getTagList") do={ # get a list with the content of each appearance of tag
# source - xml string
# tag - tag which value is to be returned
# returns an array with tag contents
:global tokenParser
:local result ({})
:local doneTags false
:local startPos 0
:do {
:local tagContent [($tokenParser->"getTagDetailed") source=$source tag=$tag startPos=$startPos]
:local content ($tagContent->"data")
:if ($content != "") do={
:set ($result->[:len $result]) $content
# advance start pos to search for next tag
:set startPos ($tagContent->"pos")
} else={
:set doneTags true
}
} while=($doneTags = false)
:return $result
}
:set ($tokenParser->"forEachTag") do={ # incremental parser that calls the callback with the content of each appearance of tag
# source - xml string
# tag - tag which value is to be returned
# callback - callback (with param content) to be called for each appearance of tag
# callbackArgs - callback will be called passing this value in param args
:global tokenParser
:local doneTags false
:local startPos 0
:do {
:local tagContent [($tokenParser->"getTagDetailed") source=$source tag=$tag startPos=$startPos]
:local content ($tagContent->"data")
:if ($content != "") do={
[$callback tagContent=$content args=$callbackArgs]
# advance start pos to search for next tag
:set startPos ($tagContent->"pos")
} else={
:set doneTags true
}
} while=($doneTags = false)
}
Function to get a list of SMS messages
Код: Выделить всё
:global recvSMS do={
:local lteIP "192.168.8.1"
:global tokenParser
# get SessionID and Token via LTE modem API
:local urlSesTokInfo "http://$lteIP/api/webserver/SesTokInfo"
:local api [/tool fetch $urlSesTokInfo output=user as-value]
:local apiData ($api->"data")
# parse SessionID and Token from API session data
:local apiSessionID [($tokenParser->"getTag") source=$apiData tag="SesInfo"]
:local apiToken [($tokenParser->"getTag") source=$apiData tag="TokInfo"]
# header and data config
:local apiHead "Content-Type:text/xml,Cookie: $apiSessionID,__RequestVerificationToken:$apiToken"
:local recvData "<?xml version=\"1.0\" encoding=\"UTF-8\"?><request><PageIndex>1</PageIndex><ReadCount>20</ReadCount><BoxType>1</BoxType><SortType>0</SortType><Ascending>0</Ascending><UnreadPreferred>1</UnreadPreferred></request>"
# recv SMS via LTE modem API with fetch
:return [/tool fetch http-method=post http-header-field=$apiHead url="http://$lteIP/api/sms/sms-list" http-data=$recvData output=user as-value]
}
Function to delete SMS messages (Inbox)
Код: Выделить всё
:global delSMS do={
:local lteIP "192.168.8.1"
:global tokenParser
# get SessionID and Token via LTE modem API
:local urlSesTokInfo "http://$lteIP/api/webserver/SesTokInfo"
:local api [/tool fetch $urlSesTokInfo output=user as-value]
:local apiData ($api->"data")
# parse SessionID and Token from API session data
:local apiSessionID [($tokenParser->"getTag") source=$apiData tag="SesInfo"]
:local apiToken [($tokenParser->"getTag") source=$apiData tag="TokInfo"]
# header and data config
:local apiHead "Content-Type:text/xml,Cookie: $apiSessionID,__RequestVerificationToken:$apiToken"
:local delData "<?xml version=\"1.0\" encoding=\"UTF-8\"?><request><Index>$index</Index></request>"
# delete SMS via LTE modem API with fetch
:return [/tool fetch http-method=post http-header-field=$apiHead url="http://$lteIP/api/sms/delete-sms" http-data=$delData output=user as-value]
}
Function to delete SMS messages (Sentbox)
Код: Выделить всё
:global recvSMSsentbox do={
:local lteIP "192.168.8.1"
:global tokenParser
# get SessionID and Token via LTE modem API
:local urlSesTokInfo "http://$lteIP/api/webserver/SesTokInfo"
:local api [/tool fetch $urlSesTokInfo output=user as-value]
:local apiData ($api->"data")
# parse SessionID and Token from API session data
:local apiSessionID [($tokenParser->"getTag") source=$apiData tag="SesInfo"]
:local apiToken [($tokenParser->"getTag") source=$apiData tag="TokInfo"]
# header and data config
:local apiHead "Content-Type:text/xml,Cookie: $apiSessionID,__RequestVerificationToken:$apiToken"
:local recvData "<?xml version=\"1.0\" encoding=\"UTF-8\"?><request><PageIndex>1</PageIndex><ReadCount>20</ReadCount><BoxType>2</BoxType><SortType>0</SortType><Ascending>0</Ascending><UnreadPreferred>1</UnreadPreferred></request>"
# delete SMS via LTE modem API with fetch
:return [/tool fetch http-method=post http-header-field=$apiHead url="http://$lteIP/api/sms/sms-list" http-data=$recvData output=user as-value]
}
:global tokenParser
:global delSMS
:local xmlSmsList ([$recvSMSsentbox]->"data")
:local smsList [($tokenParser->"getTagList") source=$xmlSmsList tag="Message"]
:local smsCount [:tonum [($tokenParser->"getTag") source=$xmlSmsList tag="Count"]]
:if ($smsCount > 0) do={
:delay 5s
:foreach tagContent in=$smsList do={
:local index [($tokenParser->"getTag") source=$tagContent tag="Index"]
[$delSMS index=$index]
}
}
Function to send SMS messages
Код: Выделить всё
:global sendSMS do={
# Example:
# :put [$sendSMS lteIP="192.168.8.1" phone="+34XXXXXXXXX" sms="test sms via lte api"]
:local lteIP "192.168.8.1"
:global tokenParser
# get SessionID and Token via LTE modem API
:local urlSesTokInfo "http://$lteIP/api/webserver/SesTokInfo"
:local api [/tool fetch $urlSesTokInfo output=user as-value]
:local apiData ($api->"data")
# parse SessionID and Token from API session data
:local apiSessionID [($tokenParser->"getTag") source=$apiData tag="SesInfo"]
:local apiToken [($tokenParser->"getTag") source=$apiData tag="TokInfo"]
# header and data config
:local apiHead "Content-Type:text/xml,Cookie: $apiSessionID,__RequestVerificationToken:$apiToken"
:local sendData "<?xml version=\"1.0\" encoding=\"UTF-8\"?><request><Index>-1</Index><Phones><Phone>$phone</Phone></Phones><Sca></Sca><Content>$sms</Content><Length>-1</Length><Reserved>1</Reserved><Date>-1</Date></request>"
# send SMS via LTE modem API with fetch
:return [/tool fetch http-method=post http-header-field=$apiHead url="http://$lteIP/api/sms/send-sms" http-data=$sendData output=user as-value]
}
Script to get a list of SMS messages from Inbox, forward them by email and SMS, then delete them.
Код: Выделить всё
:global tokenParser
:global recvSMS
:global delSMS
:global sendSMS
:local xmlSmsList ([$recvSMS]->"data")
:local smsList [($tokenParser->"getTagList") source=$xmlSmsList tag="Message"]
:local smsCount [:tonum [($tokenParser->"getTag") source=$xmlSmsList tag="Count"]]
:if ($smsCount > 0) do={
:foreach tagContent in=$smsList do={
:local index [($tokenParser->"getTag") source=$tagContent tag="Index"]
:local date [($tokenParser->"getTag") source=$tagContent tag="Date"]
:local phone [($tokenParser->"getTag") source=$tagContent tag="Phone"]
:local content [($tokenParser->"getTag") source=$tagContent tag="Content"]
:local read ([($tokenParser->"getTag") source=$tagContent tag="Smstat"] = 1)
:if ($content != "") do={
:put "$index $read $date $phone $content"
/tool e-mail send to=user@mail.com subject="SMS $phone" body="$index $read $date $phone $content"
:execute [$sendSMS lteIP="192.168.8.1" phone="+34XXXXXXXXX" sms="$phone $content"]
}
}
:delay 5s
:foreach tagContent in=$smsList do={
:local index [($tokenParser->"getTag") source=$tagContent tag="Index"]
[$delSMS index=$index]
}
}
script for keep sms in file (Rextended)
Код: Выделить всё
{
:local SMSfolder "SMS" ; # must already exist, do not count "flash", is added automatically if is needed
:local SMSfileend "backup_sms.txt" ; # only .txt file, the date and the time is added automatically at the start
:local arrMonths {an="01";eb="02";ar="03";pr="04";ay="05";un="06";ul="07";ug="08";ep="09";ct="10";ov="11";ec="12"}
/system clock ; # instead of use local date and time, if can be obtained, the SMS date and time can be used.
:local date [get date]
:local time [get time]
:local SMSfntime "$[:pick $date 7 11]$($arrMonths->[:pick $date 1 3])$[:pick $date 4 6]$[:pick $time 0 2]$[:pick $time 3 5]"
:local SMSfpath "$SMSfolder/$SMSfntime_$SMSfileend"
:local SMSnumber "+18005551234567890"
:local SMSmessage "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
/file
:put $SMSfpath
:if ([:len [find where name="flash" and type="disk"]] = 1) do={:set SMSfpath "flash/$SMSfpath"}
:put $SMSfpath
:if ([:len [find where name=$SMSfpath]] = 0) do={print file=$SMSfpath; :delay 5s; set $SMSfpath contents=""}
:put $SMSfpath
:delay 2s
set $SMSfpath contents="$[get $SMSfpath contents]$SMSnumber $SMSmessage\r\n"
}
Re: Send SMS messages via Huawei LTE modem API (tested with E3372)
Добавлено: 17 дек 2023, 14:26
martiniman
Есть способ отправить SMS на русском? Перекодировать может?