Публикации

Настройка GSM GoIP-32 + asterisk + Bitrix24, входящая и исходящая связь. Часть вторая

Часть вторая. Настройка Битрикса и Asterisk

Данный цикл заметок рассчитан на то что у вас уже установлен и преднастроен сервер Asterisk(в качестве вэбморды для удобства будем использовать freepbx), и GSM шлюз. В текущем примере рассматривается шлюз GoIP-32, для других версиях шлюза инструкция так же актуальна, но имеются небольшие различия в интерфейсе управления

Настройка Bitrix24
Идём в раздел Телефония -> Подключение -> Подключить свою АТС -> Интеграция с АТС через SIP-коннектор -> Подключить «Офисную АТС» для старых версий битрикса. Либо
Телефония -> Офисная SIP АТС -> Подключить «Офисную АТС» для новых версий битрикса. Сами настройки одинаковы для любых версий Bitrix24.
Шаг первый: Заполняем поля формы, поле логин для удобства ставим таким же как Authentication ID для этого маршрута на шлюзе. Пароль придумываем и записываем на бумажку) пригодится позже, и жмём сохранить. Открывшееся окно пока не закрываем!
Создание подключения

Создание транков Asterisk
Открываем freepbx и идём в Connectivity -> Trunks или Подключения -> Транки если у вас русский язык панели. Далее создаём транк SIP(chan-sip)

Для начала создадим транк связывающий asterisk c битриксом. Для удобства такие транки рекомендую называть начиная с CRM, наример CRM001, в поле исходящий CallerID указываем номер, который задали на порте (например 9501). Перелючаемся на вкладку sip Settings или sip общие настройки, если русский язык панели.
Вкладка Outgoing\Исходящий
Trunk Name\Название транка — просто копируем из вкладки Общие\General, для удобства
PEER Details\опции для PEER — Заполняем согласно выданным настройкам битриксом на предыдущем шаге:
fromdomain=Домен телефонии
host=Адрес сервера телефонии битрикс
secret=Адрес сервера телефонии битрикс
username=sip*Логин
fromuser=sip*Логин
disallow=all
allow=ulaw&alaw
dtmfmode=rfc2833
type=friend
insecute=port,invite
conext=contex-internal
nat=yes
qualify=yes
Пример получившегося транка
Жмём Submit\Сохранить и после Apply Settings в верхнем углу окна.

Если всё сделали правильно, то в инфо астериска (Reports -> Asterisk Info -> Chain_sip info или Отчёты — Информация об Asterisk -> Информация Chain_sip ) отобразится наш транк как зарегистрированный в разделе Chain_sip Peers\Chain_sip объектов.
Зарегистрированный peer

Данная запись является черновиком и постепенно по мере появления свободного времени пополняется!!!!

Настройка GSM GoIP-32 + asterisk + Bitrix24, входящая и исходящая связь. Часть первая

Часть первая. Настройка GSM-шлюза GoIP-32

Данный цикл заметок рассчитан на то что у вас уже установлен и преднастроен сервер Asterisk(в качестве вэбморды для удобства будем использовать freepbx), и GSM шлюз. В текущем примере рассматривается шлюз GoIP-32, для других версиях шлюза инструкция так же актуальна, но имеются небольшие различия в интерфейсе управления

Базовые настройки
Идём на вкладку Configurations -> Basic VoIP, и выполняем базовые настройки линий.

Config Mode — Ставим Config by Line, настраиваем каждую линию по отдельности. Позволит повесить на каждую отдельную симку свой источник в Битриксе.
Authentication ID — Имя пользователя Asterisk, которого создадим позже, необходимо для разруливания маршрутов Asterislk
Password — Пароль от этого пользователя
Routing Prefix — Префикс маршрута, так же необходим для маршрутизации
SIP Proxy — Адрес прокси sip, можно не задавать, можно поставить адрес ip asterisk. Или если используете прокси для телефонии, то поставить его адрес.
SIP Registrar Server — Адрес sip регистрации, ip asterisk сервера.
Re-register Period (s) — Период перерегистрации пользователя на сервере asterisk, можно оставить по — умолчанию, можно изменить на свой. Минимальный период — 30 секунд, рекомендуется устанавливать не более 120 секунд.
Phone Number — Внутренний телефонный номер, так же будет использоваться для маршрутизации, для удобства ставим одинаковым с Authentication ID
Нажимаем Save Changes

Настраиваем другие линии аналогичным способом.

Страница базовых настроек

Расширенные настройки
Идём на вкладку Configurations -> Advanced VoIP и выполняем общие настройки для связи с asterisk.

SIP Listening Port Mode — ставим Fixed
Port — ставим порт udp нашего asterisk, по умолчанию 5060
Get Callee Number — Способ получения номера звонящего, для правильной передачи номера, установить By To Header
Call OUT Auth Mode — ставим none, способ авторизации исходящих вызовов, нет необходимости в нашей конфигурации
Bulit-in SIP Proxy — ставим Enabled, Включаем встроенный sip сервер, для регистрации нашего asterisk на шлюзе (необязательно)
Password — пароль для регистрации asterisk'a на шлюзе
DTMF Signaling — Ставим Outband
Outband DTMF type — Тип тонального сигнала для набора номера. Ставим RFC 2833.

Страница с расширенными настройками

Исходящая телефония
Configurations -> Call Out
В этом разделе нам необходимо лишь добавить правило для обрезки Routing Prefix из номера телефонов. Задаётся в формате «Префикс»:"-Префикс". Например 1:-1 для первой лини, 2:-2 для второй и аналогично для остальных

Настройки для исходящих звонков

Входящая телефония
Configurations -> Call In
Здесь так же необходимо провести небольшие настройки.
CID Forward Mode — Use CID as SIP Caller ID, прокидываем номер звонящего в asterisk в заголовках.
Forwarding to VoIP Number — Ставим внутренний Asterisk номер.
Dial Plan — Аналогично Call Out, задаётся в формате «Префикс»:"-Префикс".

Настройки для входящих звонков

В заключение
Как и всегда, данные настройки не являются истиной в последней инстанции, наверняка спецы по телефонии смогут более подробно объяснить по всем параметра. Я же просто делюсь своими кейсами.

MongoDB virtual fields, на пальцах, novice level

Предыстория

По роду работы периодически собираю mvp на изврат-стэках. Одним из таких случаев и стала связка из express+graphql+mongo+react. И настал момент связывания данных.

Начинаем начинать
Что же такое virtual fields и зачем они нужны?

Если кратко — связывать таблицы.

Теперь по-подробнее.
Допустим, есть у вас запись хранящая в себе описание книги:

"bookID": "1",
"name": "Книга 1",
"rented": false
И таких книг у вас, например 200шт.

Так же есть у вас запись «полка», в которой перечислены ID книг, хранящихся на ней:


"shelfID": "1",
"name": "Первая полка",
"booksIDs": ["1","2"]
В какой-то момент, вам становится необходимым получить названия книг, стоящих на первой полке. Вот тут нам и пригодятся «виртуальные» поля mongoDB. Чтобы не городить запросы .find({}) с громоздкой строкой параметров используем поля.

Этап подготовки
При объявлении схемы, необходимо передать ей параметры, без которых виртуальное поле не будет возвращать нам искомое.

var shelfSchema = new schema(ShelfSchema, {
    toObject: {
        virtuals: true
    },
    toJSON: {
        virtuals: true
    }});
Магия
Далее переходим к созданию самого поля. Виртуальные поля должны инициализироваться после объявления схемы, и перед инициализацией модели! За это у нас отвечает метод .virtual() схемы.


shelfSchema.virtual('books',{
    ref: 'Books', //Название модели, по которой будем искать объекты
    localField: 'booksIDs', //Поле "родительского" объекта, в котором перечисление искомых параметров
    foreignField: 'bookID', //"Дочернее" поле. Поле с которым сопоставляется значение "родительского" объекта
    justOne: false //Возвращать только один объект, либо массив объектов
})
Далее как обычно производим стандартную инициализацию моделей.


const Books = mongoose.model('books', bookSchema);
const Shelfs = mongoose.model('shelfs',  shelfSchema );
Теперь при вызове

Shelfs.find({shelfID:'1'}).populate('books')
Мы получим объект:


"shelfID": "1",
"name": "Первая полка",
"booksIDs": ["1","2"],
"books":{
        "bookID": "1",
        "name": "Книга 1",
        "rented": false
    },{
        "bookID": "2",
        "name": "Книга 2",
        "rented": false
    }
Поле book у нас не объявлено в схеме. Так откуда же оно взялось и содержит в себе объекты книг?
вся магия находится в методе .populate(). Оно заставляет mongo отдать объекты согласно параметрам, заданным в .virtual(). Простыми словами в .populate() указывается какое виртуальное поле необходимо вернуть, в нашем случае это 'books', оно согласно .virtual() схеме берёт поле 'booksIDs', и возвращает все объекты из таблицы 'Books', у которых значение 'BookID' совпадает с элементом из списка 'bookIDs'

Довольно простая и удобная в то же время вещь. Возможно про это уже написано 1000 и 1 раз, но информация не бывает лишней. Надеюсь, будет полезно.