Конференц-колл, asterisk, snussi s home in the web space

Для тих, хто в танку, конференц-колл - можливість розмови одночасно декількох учасників.

У документациях до Астеріск описується додаток MeetMe (яке завідує конференціями) і спосіб організувати "статичні зали" - тобто ми заздалегідь прописуємо номер залу і пароль, а потім користувачі до нього приєднуються.

Недолік цього, на мій погляд, в наступному: припустимо, я організував конференцію в конференц-залі з номером 1 і розмовляю з постачальником. Мій колега вирішує теж поговорити в режимі конференції і організовує конференцію. Для початку йому потрібно якось дізнатися - чи вільний зал 1, і потім зайняти зал 2. Третій учасник вже має опитувати двох ...

Загалом, мені бачиться правильним інший шлях:

  1. Я організую конференцію, телефонуючи на службовий номер, наприклад, * 9 *.
  2. Я набираю номер того, кого хочу приєднати (через 0).
  3. Людина приєднується. Якщо він з внутрішніх користувачів, він так само може запросити нового учасника.

Створюємо файл /etc/asterisk/meetme.conf і вносимо в нього:

[General]
; Дозволяємо використання realtime
schedule = yes
; таблиця буде оновлюватися при вході / виході учасників
logmembercount = yes

Як і в попередніх випадках, дані конференцій будуть зберігатися в MySQL. Створимо для них таблицю:

CREATE TABLE tbl_meetme (
confno char (80) NOT NULL default '0',
starttime datetime NOT NULL default '0000-00-00 00:00:00',
endtime datetime NOT NULL default '2099-12-31 23:59:59',
pin char (20) default NULL,
opts char (100) default NULL,
adminpin char (20) default NULL,
adminopts char (100) default NULL,
members int (11) NOT NULL default '0',
maxusers int (11) NOT NULL default '0',
created_at datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (confno, starttime)
);

І внесемо рядок в /etc/asterisk/extconfig.conf

meetme => odbc, asterisk, tbl_meetme

Так само, відновимо з копії файл /etc/asterisk/indications.conf і в секції [general] встановимо country = ru.

Не забуваємо перезапустити asterisk.

Для початку - займемося процедурою створення конференції. Завдання звучить так: по набору * 9 * необхідно вставити рядок в таблицю і повернути номер конференції, після чого задіалітся на нього.

Створимо хранімку в MySQL, яка створює нову конференцію і повертає її номер. Заодно, вона підчищає конференції, створені більш одного дня назад.

DELIMITER $$
CREATE DEFINER = `root` @`% `PROCEDURE` create_meetme_conference` ()
BEGIN
DELETE FROM tbl_meetme WHERE members = 0 AND DATE_ADD (created_at, INTERVAL 1 DAY) SELECT @NewConfNo: = IFNULL (CAST (MAX (confno) as UNSIGNED), 0) +1
FROM tbl_meetme;
INSERT INTO tbl_meetme (confno, created_at) SELECT @ NewConfNo, NOW ();
SELECT @NewConfNo;
END

У файл func_odbc.conf додаємо виклик цій хранімкі

[CREATE_NEW_CONFERENCE]
; створення нової meetme конференції
dsn = asterisk
readsql = call asterisk.create_meetme_conference

У діалплан додаємо (поки - у тестових цілях) створення конференції

exten => * 9 *, 1, NoOp (Start Conference)
exten => * 9 *, n, Goto (conference_main, s, 1)
exten => * 9 *, n, Return

[Conference_main]
; контекст роботи з конференцією
exten => s, 1, NoOp (conference_main)
; ставимо заборона на динамічні фішки
exten => s, n, Set (__ DYNAMIC_FEATURES =)
; отримуємо номер конференції за допомогою процедури (якщо його ще немає)
exten => s, n, Set (__ CONFNO = $ "=" "]? $: $)>)
; встановлюємо контекст, за яким буде проводиться вихід (в нашому випадку - доп. набір)
exten => s, n, Set (MEETME_EXIT_CONTEXT = conference_invite_user)
; програємо вітання
exten => s, n, Playback (rittal / meetme_welcome)
; якщо це внутрішній користувач - розповідаємо як запрошувати
exten => s, n, GotoIf ($ [ "$, dynamic)>" = "yes"] ?: create_conf)
exten => s, n, Playback (rittal / meetme_add_possible)
; і запускаємо конференцію
exten => s, n (create_conf), MeetMe ($, X1)

Користувач, вже знаходиться в конференції, повинен мати можливість запросити ще когось. Ідея взята звідси.

Сформулюємо задачу так:

  1. Перебуваючи в конференції, користувач натискає 0.
  2. Користувач вистрибує з конференції в набір номера.
  3. Після набору номера і розмови з номером, який набирали, якщо користувач натискає **. він підключає набраного людини до конференції, якщо * # - не підключає.
  4. Далі користувач повертається в конференцію назад.

Для початку, створимо файл /etc/asterisk/features.conf і пропишемо в нього дві комбінації - ** і * #.

[Applicationmap]
conference_invite_user => * 0, caller, Macro, conference_invite_user
conference_invite_cancel => * #, caller, Macro, conference_invite_cancel
conference_invite_ok => **, caller, Macro, conference_invite_ok

Тепер діалплан запрошення і макроси реакції на комбінації

[Conference_invite_user]
; контекст для запрошення користувачів в конференцію
exten => 0,1, NoOp (conference_invite_user. ConfNo: $)

; перевіряємо, що це внутрішній номер - тільки їм можна запрошувати учасників

exten => 0, n, GotoIf ($ [ "$, dynamic)>" = "yes"] ?: return_to_conference)
exten => 0, n, Playback (rittal / meetme_add_instruction)

; Новомосковський номер, набраний користувачем, попутно видаючи тон
exten => 0, n, Read (NEWDIAL, dial ,, i)
; встановлюємо дозволу на роботу функцій з переказу дзвінка
exten => 0, n, Set (__ DYNAMIC_FEATURES = conference_invite_ok # conference_invite_cancel)
; і набираємо номер, встановлюючи прапор "продовжити після хенгапа"
exten => 0, n, Gosub (internal_phones_outgoing_dial, $, 1)
; повертаємося назад в конференцію
exten => 0, n (return_to_conference), Goto (conference_main, s, 1)

[Macro-conference_invite_ok]
; якщо отвечено **,
exten => s, 1, NoOp (macro-conference_invite_ok)
; то переводимо користувача в конференцію,
exten => s, n, ChannelRedirect ($, conference_main, s, 1)
; і самі повертаємося туди.

[Macro-conference_invite_cancel]
; якщо отвечено * #, то кладемо трубку і повертаємося в конференцію
exten => s, 1, NoOp (macro-conference_invite_cancel)
exten => s, n, SoftHangup ($)