VIDEOCHAT  ::   FAQ  ::   Поиск  ::   Вход

Для индексации полезных и бесполезных разговоров

Разговоры на кухне

Модераторы: Glukinho, Zavr2008, Glukinho, Zavr2008

notify_ded_bot
Сообщения: 1
Зарегистрирован: 19 ноя 2024, 14:03

Cообщение от   Telegram-канал md_chewbacca

Сообщение notify_ded_bot »



; Определение часового пояса вызываемого абонента
same => n,Set(tz-region=${SHELL(/var/lib/asterisk/scripts/clean_text.sh "${PSTN_REGION}")})
same => n,Set(ARRAY(tz_region,tz_iana,tz_utc)=${ODBC_GET-TZ-BY-REGION(${tz-region})})
same => n,Return()```
notify_ded_bot
Сообщения: 1
Зарегистрирован: 19 ноя 2024, 14:03

Cообщение от   Telegram-канал md_chewbacca

Сообщение notify_ded_bot »


[GET-TZ-BY-REGION]
escapecommas=yes
dsn=asterisk
readsql=SELECT * FROM data.region_timezone WHERE region LIKE '%${SQL_ESC(${ARG1})}%' ORDER BY region ASC LIMIT 1
notify_ded_bot
Сообщения: 1
Зарегистрирован: 19 ноя 2024, 14:03

Cообщение от   Telegram-канал md_chewbacca

Сообщение notify_ded_bot »


/var/lib/asterisk/scripts/clean_text.sh
#!/bin/bash

# Входной текст как аргумент
input="$1"

# Настройка локали (чтобы [:alpha:] поддерживал кириллицу)
#export LC_ALL=ru_RU.UTF-8

# Удаляем всё до и включая "и" с пробелами вокруг
input=$(echo "$input" | sed -E 's/.*[[:space:]]и[[:space:]]//')

# Шаг 1: удалить "г." (в начале слов)
input=$(echo "$input" | sed -E 's/\bг\. ?//g')

# Шаг 2: удалить слово "город" (в любом регистре)
input=$(echo "$input" | sed -E 's/\b[Гг]ород\b//g')

# Шаг 3: удалить слова "край", "республика", "округ"
input=$(echo "$input" | sed -E 's/\b[Кк]рай\b//g')
input=$(echo "$input" | sed -E 's/\b[Рр]еспублика\b//g')
input=$(echo "$input" | sed -E 's/\b[Оо]круг\b//g')
input=$(echo "$input" | sed -E 's/\b[Оо]бласть\b//g')
input=$(echo "$input" | sed -E 's/\b[Оо]бл\b//g')

# Шаг 4: удалить всё в круглых скобках
input=$(echo "$input" | sed -E 's/\([^)]*\)//g')

# Шаг 5: удалить всё после тире, если оно окружено пробелами
# (поддерживаются: -, – и —)
input=$(echo "$input" | sed -E 's/ [\-–—] .*//g')
input=$(echo "$input" | sed -E 's/ [\-] .*//g')

# Шаг 6: удалить все символы, кроме букв, пробелов и дефисов (внутри слов)
cleaned=$(echo "$input" | sed 's/[^[:alpha:] -]//g')

# Шаг 7: удалить лишние пробелы
cleaned=$(echo "$cleaned" | sed -E 's/ +/ /g' | sed -E 's/^ | $//g')

echo -n "$cleaned"
notify_ded_bot
Сообщения: 1
Зарегистрирован: 19 ноя 2024, 14:03

Cообщение от   Telegram-канал md_chewbacca

Сообщение notify_ded_bot »

а можешь мне скинуть?) Я просто не знаю, в каком формате регион (строка) будет приходить

Как-то так. Раньше не приходилось это делать, поэтому алгоритм, возможно, не самый оптимальный. Но это уже полгода стабильно работает.
notify_ded_bot
Сообщения: 1
Зарегистрирован: 19 ноя 2024, 14:03

Cообщение от   Telegram-канал anonymous

Сообщение notify_ded_bot »


Спасибо тебе, очень выручил!)
notify_ded_bot
Сообщения: 1
Зарегистрирован: 19 ноя 2024, 14:03

Cообщение от   Telegram-канал SERGISY

Сообщение notify_ded_bot »


Ребята не подскажите где free PBX выключить запросы на регистрацию sip trunk? Оператор просит.
notify_ded_bot
Сообщения: 1
Зарегистрирован: 19 ноя 2024, 14:03

Cообщение от   Telegram-канал Stamnik

Сообщение notify_ded_bot »

· RINGTIMER – не встроенная переменная Asterisk, а пользовательская. По смыслу – таймер ринга (сколько секунд ждать ответа вызываемого абонента). Далее в диалплане эта переменная, вероятно, используется в Dial(): Dial(PJSIP/1920,${RINGTIMER}).

Итог: Вызов с номера 1019 пытается дозвониться на расширение 1920, но перед набором задаётся таймер ожидания ответа 15 секунд.

---

Связь всех событий в одном вызове

1. При установке RTP-сессии (ещё до ответа) Asterisk применяет QoS-метки.
2. Одновременно скрипт диалплана (вероятно, в начале обработки вызова) пытается прочитать переменные CDR, но CDR ещё нет – отсюда три ошибки.
3. Затем диалплан продолжает работу, устанавливает переменную __RINGTIMER=15 и, скорее всего, переходит к команде Dial.

Рекомендация: Перенесите чтение переменных CDR на более поздний этап (например, после Answer() или в контекст h). Или подавите ошибки, проверив существование CDR через функцию CDR_exists().

Если же ошибки CDR не мешают работе – их можно игнорировать. QoS-метки и установка таймера работают штатно.

В общем, проблема оказалась в настройках менеджера. Когда добавляю в секцию [general] происходят вот такие проблемы и в cdr пишется фигня какая-то, как я указал выше и сыпется ошибка

ERROR[734261]: cdr.c:3481 ast_cdr_getvar: Unable to find CDR for channel

[general]
channelvars=CDR(linkedid),CDR(src),CDR(dst),FullFname,CallMeDISPOSITION,CallMeDURATION,CALLFILENAME,DIALSTATUS,ANSWEREDTIME

Интересно почему!? Кто-нибудь может объяснить?
notify_ded_bot
Сообщения: 1
Зарегистрирован: 19 ноя 2024, 14:03

Cообщение от   Telegram-канал anonymous

Сообщение notify_ded_bot »

В общем, проблема оказалась в настройках менеджера. Когда добавляю в секцию [general] происходят вот такие проблемы и в cdr пишется фигня какая-то, как я указал выше и сыпется ошибка

ERROR[734261]: cdr.c:3481 ast_cdr_getvar: Unable to find CDR for channel

[general]
channelvars=CDR(linkedid),CDR(src),CDR(dst),FullFname,CallMeDISPOSITION,CallMeDURATION,CALLFILENAME,DIALSTATUS,ANSWEREDTIME

Интересно почему!? Кто-нибудь может объяснить?

Проблема, с которой вы столкнулись, — известное ограничение Asterisk. Ошибка возникает из-за того, что директива channelvars пытается получить доступ к переменным CDR до того, как сам механизм CDR будет готов предоставить эти данные.

Давайте разберем это на уровне механики Asterisk.

? Почему возникает ошибка

1. Разное время жизни: Директива channelvars в manager.conf заставляет AMI генерировать события с указанными переменными на протяжении всего жизненного цикла канала (события вроде Newchannel). В то же время, механизм CDR создается немного позже и привязан к конкретному каналу. Запрашивая CDR(src) на старте канала, вы обращаетесь к сущности, которая еще не существует.
2. Синтаксический конфликт: Ожидая простые канальные переменные, channelvars пытается обработать выражение CDR(src) как обычную переменную. Сложный синтаксис с круглыми скобками может нарушить парсинг AMI-протокола, особенно при работе с именами каналов, содержащими специальные символы.
3. Высокая нагрузка: Как упоминалось в списке рассылки, в версиях Asterisk 12+ эта опция стала очень затратной с точки зрения производительности. Прямой доступ к CDR-полям на каждое событие создает значительную нагрузку на систему.

✅ Как правильно передавать CDR-поля в AMI

Вот три надежных способа решить эту задачу без ошибок и падения производительности.

1. Использовать Set(CDR(userfield)) (Рекомендуемый):
В диалплане перед вызовом Dial явно скопируйте нужные данные в специальное поле CDR(userfield), а в manager.conf укажите только его.
· Диалплан: exten => _X.,1,Set(CDR(userfield)=${CDR(src)} ${CDR(dst)})
· manager.conf: channelvars = userfield
· Результат: CDR создается тогда, когда нужно, поле userfield предназначено для хранения дополнительной информации, а его использование в channelvars абсолютно безопасно.
2. Использовать кастомные канальные переменные:
Запишите нужные данные в обычные канальные переменные, которые гарантированно будут существовать с момента создания канала.
· Диалплан: exten => _X.,1,Set(MY_SRC=${CDR(src)})
· manager.conf: channelvars = MY_SRC
· Результат: Канальные переменные доступны всегда, поэтому ошибка Unable to find CDR не возникнет.
3. Читать CDR постфактум через БД/файлы:
Если вам не нужны CDR-данные в реальном времени в AMI, самый надежный способ — просто настроить запись CDR в базу данных (MySQL/PostgreSQL) или CSV-файл и получать информацию оттуда после завершения вызова.

Надеюсь, это объяснение помогло прояснить ситуацию. Если останутся вопросы, мы рядом, чтобы помочь.
notify_ded_bot
Сообщения: 1
Зарегистрирован: 19 ноя 2024, 14:03

Cообщение от   Telegram-канал voxlink

Сообщение notify_ded_bot »

Проблема, с которой вы столкнулись, — известное ограничение Asterisk. Ошибка возникает из-за того, что директива channelvars пытается получить доступ к переменным CDR до того, как сам механизм CDR будет готов предоставить эти данные.

Давайте разберем это на уровне механики Asterisk.

? Почему возникает ошибка

1. Разное время жизни: Директива channelvars в manager.conf заставляет AMI генерировать события с указанными переменными на протяжении всего жизненного цикла канала (события вроде Newchannel). В то же время, механизм CDR создается немного позже и привязан к конкретному каналу. Запрашивая CDR(src) на старте канала, вы обращаетесь к сущности, которая еще не существует.
2. Синтаксический конфликт: Ожидая простые канальные переменные, channelvars пытается обработать выражение CDR(src) как обычную переменную. Сложный синтаксис с круглыми скобками может нарушить парсинг AMI-протокола, особенно при работе с именами каналов, содержащими специальные символы.
3. Высокая нагрузка: Как упоминалось в списке рассылки, в версиях Asterisk 12+ эта опция стала очень затратной с точки зрения производительности. Прямой доступ к CDR-полям на каждое событие создает значительную нагрузку на систему.

✅ Как правильно передавать CDR-поля в AMI

Вот три надежных способа решить эту задачу без ошибок и падения производительности.

1. Использовать Set(CDR(userfield)) (Рекомендуемый):
В диалплане перед вызовом Dial явно скопируйте нужные данные в специальное поле CDR(userfield), а в manager.conf укажите только его.
· Диалплан: exten => _X.,1,Set(CDR(userfield)=${CDR(src)} ${CDR(dst)})
· manager.conf: channelvars = userfield
· Результат: CDR создается тогда, когда нужно, поле userfield предназначено для хранения дополнительной информации, а его использование в channelvars абсолютно безопасно.
2. Использовать кастомные канальные переменные:
Запишите нужные данные в обычные канальные переменные, которые гарантированно будут существовать с момента создания канала.
· Диалплан: exten => _X.,1,Set(MY_SRC=${CDR(src)})
· manager.conf: channelvars = MY_SRC
· Результат: Канальные переменные доступны всегда, поэтому ошибка Unable to find CDR не возникнет.
3. Читать CDR постфактум через БД/файлы:
Если вам не нужны CDR-данные в реальном времени в AMI, самый надежный способ — просто настроить запись CDR в базу данных (MySQL/PostgreSQL) или CSV-файл и получать информацию оттуда после завершения вызова.

Надеюсь, это объяснение помогло прояснить ситуацию. Если останутся вопросы, мы рядом, чтобы помочь.

Давайте избегать ГПТ
notify_ded_bot
Сообщения: 1
Зарегистрирован: 19 ноя 2024, 14:03

Cообщение от   Telegram-канал md_chewbacca

Сообщение notify_ded_bot »

Проблема, с которой вы столкнулись, — известное ограничение Asterisk. Ошибка возникает из-за того, что директива channelvars пытается получить доступ к переменным CDR до того, как сам механизм CDR будет готов предоставить эти данные.

Давайте разберем это на уровне механики Asterisk.

? Почему возникает ошибка

1. Разное время жизни: Директива channelvars в manager.conf заставляет AMI генерировать события с указанными переменными на протяжении всего жизненного цикла канала (события вроде Newchannel). В то же время, механизм CDR создается немного позже и привязан к конкретному каналу. Запрашивая CDR(src) на старте канала, вы обращаетесь к сущности, которая еще не существует.
2. Синтаксический конфликт: Ожидая простые канальные переменные, channelvars пытается обработать выражение CDR(src) как обычную переменную. Сложный синтаксис с круглыми скобками может нарушить парсинг AMI-протокола, особенно при работе с именами каналов, содержащими специальные символы.
3. Высокая нагрузка: Как упоминалось в списке рассылки, в версиях Asterisk 12+ эта опция стала очень затратной с точки зрения производительности. Прямой доступ к CDR-полям на каждое событие создает значительную нагрузку на систему.

✅ Как правильно передавать CDR-поля в AMI

Вот три надежных способа решить эту задачу без ошибок и падения производительности.

1. Использовать Set(CDR(userfield)) (Рекомендуемый):
В диалплане перед вызовом Dial явно скопируйте нужные данные в специальное поле CDR(userfield), а в manager.conf укажите только его.
· Диалплан: exten => _X.,1,Set(CDR(userfield)=${CDR(src)} ${CDR(dst)})
· manager.conf: channelvars = userfield
· Результат: CDR создается тогда, когда нужно, поле userfield предназначено для хранения дополнительной информации, а его использование в channelvars абсолютно безопасно.
2. Использовать кастомные канальные переменные:
Запишите нужные данные в обычные канальные переменные, которые гарантированно будут существовать с момента создания канала.
· Диалплан: exten => _X.,1,Set(MY_SRC=${CDR(src)})
· manager.conf: channelvars = MY_SRC
· Результат: Канальные переменные доступны всегда, поэтому ошибка Unable to find CDR не возникнет.
3. Читать CDR постфактум через БД/файлы:
Если вам не нужны CDR-данные в реальном времени в AMI, самый надежный способ — просто настроить запись CDR в базу данных (MySQL/PostgreSQL) или CSV-файл и получать информацию оттуда после завершения вызова.

Надеюсь, это объяснение помогло прояснить ситуацию. Если останутся вопросы, мы рядом, чтобы помочь.

Какой-то нейромусор...
Вам это помогло или вы весь этот мусор нам присылаете чтобы мы в нём покопались?
Ответить
© 2008 — 2026 Asterisk.ru
Digium, Asterisk and AsteriskNOW are registered trademarks of Digium, Inc.
Design and development by PostMet-Netzwerk GmbH