Chan Dongle0 получение SMS USSD (и перенаправление в телеграм)

Задача: пересылать в телеграм входящие СМС и USSD сообщения.

Проблема: не переслается текст СМС в телеграм.

modules.conf chan_dongle грузится.
dongle.conf прописан
В extensions.conf в конец добавляется диалплан
Приложение диалплана php-agi создано и прописано.
php-agi отрабатывает. в телеграм приходит уведомление. но не полностью.
Вижу только номер (или “имя”, если СМС от МЧС\RSCHS).

В чем преткновение:
нет времени получения ($datesms в php-agi подставляется пустой)

не пересылается текст (содержание) SMS. (возможно не передается в php-agi ?)
ни ${SMS} (в одну строку, многострочные СМС могут обрезаться)
ни ${SMS_BASE64} не декодируется в asterisk.

Вопрос: Что я делаю неправильно?

конфигурация мико

extensions.conf

[SIP-TRUNK-030D9F6C-outgoing-custom]
exten => _[0-9*#+]!,1,Set(DIAL_COMMAND=Dongle/dongle0/${number})
	same => n,return
	
; ====
[public-direct-dial] 
; include => none-incoming
include => incomming-sms
include => incomming-ussd
; ====
[incomming-sms]
exten => sms,1,Noop(Incoming SMS from ${CALLERID(number)} ${SMS})
exten => sms,n,Set(sms_multiline=${BASE64_DECODE(${SMS_BASE64})})
exten => sms,n,AGI(DIALPLAN-APP-23513232.php, ${CALLERID(number)} ${sms_multiline})
exten => sms,n,Hangup
; ====
[incomming-ussd]
exten => ussd,1,Noop(Incoming USSD: ${USSD})
exten => ussd,n,AGI(DIALPLAN-APP-F8A0D5B7.php, ${USSD_BASE64})
exten => ussd,n,Hangup
; =====

Тут немножко “каша” из перебора разных вариантов.
На эту строчку

exten => sms,n,Set(sms_multiline=${BASE64_DECODE(${SMS_BASE64})})`

в консоли пишет

[2026-01-24 13:05:46] ERROR[31764][C-0000000d]: pbx_functions.c:608 ast_func_read: Function BASE64_DECODE not registered

DIALPLAN-APP-23513232.php

<?php
require_once 'Globals.php';
use \GuzzleHttp\Client;

const API_KEY = 'aaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbb_cccccccccccc';
const CHAT_ID = 'xxxxxxxxx';

$agi = new MikoPBX\Core\Asterisk\AGI();

$num  = $agi->get_variable('CALLERID(number)', true);
$datesms = date('Y.d.m H:i:s', str_replace('mikopbx-', '', $id));
 
$sms_plain1 = $agi->get_variable('SMS');
$sms_plain2 = $agi->get_variable('$SMS');
$sms_plain3 = $agi->get_variable('${SMS}');

$sms_text = $agi->get_variable('$sms_multiline');
/* $sms_text_dc = base64_decode($sms_text); */

$TEXT = "SMS FROM ". $num ." - ". $datesms ."\n———————————————————\n 1 ". $sms_plain1 ."\n 2 ". $sms_plain2 ."\n 3 ".  $sms_plain3 ."\n ———————————————————\n". $sms_text ."\n———————————————————\n";

$apiURL = 'https://api.telegram.org/bot' . API_KEY . '/';
$client = new Client([
    'base_uri' => $apiURL,
    'timeout' => 1,
    'http_errors' => false,
]);
try {
    $client->post( 'sendMessage', ['query' => ['chat_id' => CHAT_ID, 'text' => $TEXT]] );
}catch (Throwable $e){
}

dongle.conf

[general]
interval=15

[defaults]
context=public-direct-dial
group=0
rxgain=0
txgain=0
autodeletesms=yes
resetdongle=yes
u2diag=-1	
usecallingpres=yes
callingpres=allowed_passed_screen
disablesms=no

language=en	
smsaspdu=yes	
mindtmfgap=45
mindtmfduration=80
mindtmfinterval=200

callwaiting=auto
disable=no
initstate=start
dtmf=relax
; ====
[dongle0]
audio=/dev/ttyUSB1
data=/dev/ttyUSB2
;
exten=79xxxxxxxxx
imei=3xxxxxxxxxxxxxx
imsi=2xxxxxxxxxxxxxx
; ====

Раньше работал скрипт, но комп сдох расссматриваю варианты замены.

конфигурация фрипбикс
#!/bin/bash
#
# Send message to Telegramm
#
# --- place to  /var/lib/asterisk/bin/telegram-push.sh 
if [[ -z "$1" ]];
then
echo ; echo ;
echo -e " Usage: telegram-push [telegramm_chat_ID] [subj] [message]"
echo ; echo ;
exit
fi
#
token='aaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbb_cccccccccccc'
# chat="$1"
chat="xxxxxxxxx"
subj="$2"
message="`echo "$3" | tr '"' '#'`"
/usr/bin/curl -s --header 'Content-Type: application/json' --request 'POST' --data "{\"chat_id\":\"${chat}\",\"text\":\"${subj}\n${message}\"}" "https://api.telegram.org/bot${token}/sendMessage" 
### EOF

вызывался так freepbx/extensions_custom.conf

[incomming-sms]
exten => sms,1,Noop(Incoming SMS from ${CALLERID(num)} ${BASE64_DECODE(${SMS_BASE64})})
exten => sms,n,System(echo '${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} — ${DONGLENAME} — ${CALLERID(num)}: ${BASE64_DECODE(${SMS_BASE64})}')
exten => sms,n,System(/var/lib/asterisk/bin/telegram-push.sh me 'SMS FROM ${CALLERID(num)}' '${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} \n———————————————————\n ${BASE64_DECODE(${SMS_BASE64})} \n———————————————————\n')
exten => sms,n,Hangup
; ====
[incomming-ussd]
exten => ussd,1,Noop(Incoming USSD: ${BASE64_DECODE(${USSD_BASE64})})
exten => ussd,n,System(echo '${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} — ${DONGLENAME}: ${BASE64_DECODE(${USSD_BASE64})}')
exten => ussd,n,System(/var/lib/asterisk/bin/telegram-push.sh me 'USSD IN' '${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} \n———————————————————\n ${CALLERID(num)}:\n———————————————————\n ${BASE64_DECODE(${USSD_BASE64})} \n———————————————————\n')
exten => ussd,n,Hangup
; ====

подсмотрите реализацию тут

мб это поможет. проблемы схожие были

Спасибо, помогло. Идей парсить в php передаваемые аргументы.

Summary

extensions.conf

; =======================
[public-direct-dial] 
include => incomming-sms
include => incomming-ussd

; =======================

[incomming-sms]
exten => sms,1,Noop(Incoming SMS from ${CALLERID(number)} ${SMS})
exten => sms,n,AGI(DIALPLAN-APP-23513232.php, ${CALLERID(number)}, ${SMS_BASE64})
exten => sms,n,Hangup

; =======================

[incomming-ussd]
exten => ussd,1,Noop(Incoming USSD: ${USSD})
exten => ussd,n,AGI(DIALPLAN-APP-F8A0D5B7.php, ${USSD_BASE64})
exten => ussd,n,Hangup

; =======================

DIALPLAN-SMS (DIALPLAN-APP-23513232.php )

<?php
require_once 'Globals.php';
use \GuzzleHttp\Client;

const API_KEY = 'aaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbb_cccccccccccc';
const CHAT_ID = 'xxxxxxxxx';

$agi = new MikoPBX\Core\Asterisk\AGI();
$num  = $agi->get_variable('CALLERID(number)', true);

$sms_text  = base64_decode($argv[2]??"");

$TEXT = "SMS FROM ". $num ." \n———————————————————\n ". $sms_text ."\n———————————————————\n";

$apiURL = 'https://api.telegram.org/bot' . API_KEY . '/';
$client = new Client([
    'base_uri' => $apiURL,
    'timeout' => 1,
    'http_errors' => false,
]);
try {
    $client->post( 'sendMessage', ['query' => ['chat_id' => CHAT_ID, 'text' => $TEXT]] );
}catch (Throwable $e){
}

DIALPLAN-USSD (DIALPLAN-APP-F8A0D5B7.php)

<?php
require_once 'Globals.php';
use \GuzzleHttp\Client;

const API_KEY = 'aaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbb_cccccccccccc';
const CHAT_ID = 'xxxxxxxxx';

$agi = new MikoPBX\Core\Asterisk\AGI();
$ussd_text =  base64_decode($argv[1]??"");

$TEXT = "USSD \n———————————————————\n". $ussd_text ."\n———————————————————\n";

$apiURL = 'https://api.telegram.org/bot' . API_KEY . '/';
$client = new Client([
    'base_uri' => $apiURL,
    'timeout' => 1,
    'http_errors' => false,
]);
try {
    $client->post( 'sendMessage', ['query' => ['chat_id' => CHAT_ID, 'text' => $TEXT]] );
}catch (Throwable $e){
}

Но это выглядит костылем, так как не решает вопросов с

[2026-01-26 09:20:21] ERROR[17531][C-00000001] pbx_functions.c: Function BASE64_DECODE not registered (приходится декодировать в php)

и недоступности переменных из php-agi (не видит даты, не видит ${SMS} и др)

в php-agi любую переменную канала, или на крайний случай обработать аргументы командной стироки.

 $agi->get_variable('SMS, true);

BASE64_DECODE - возможнго у вас просто не подгружен соответствующий модуль в asterisk.

Я просто установил по умолчанию MikoPBX 2024.1.114

Возможно и не подгружен, если его нужно как-то по особому подгружать.

Во freepbx, с которого переезжаю, а ранее в чистом asterisk, в которых всё работало, ничего такого в modules.conf не подгружалось.

Получается, нужно сделать так?

modules.conf

load => func_base64.so
load => chan_dongle.so

см. Кастомизация системных файлов | MikoPBX