Înțelegerea FreePBX și integrarea acestuia cu Bitrix24 și altele

Bitrix24 este o combinație uriașă care combină CRM, fluxul de lucru, contabilitatea și multe alte lucruri pe care managerilor le plac foarte mult și personalului IT nu prea le plac. Portalul este folosit de o mulțime de companii mici și mijlocii, inclusiv clinici mici, producători și chiar saloane de înfrumusețare. Funcția principală pe care managerii o „adoră” este integrarea telefoniei și CRM, atunci când orice apel este înregistrat imediat în CRM, se creează carduri de client, la intrare, sunt afișate informații despre client și puteți vedea imediat cine este, ce el poate vinde si cat datoreaza. Dar telefonia de la Bitrix24 și integrarea ei cu CRM costă bani, uneori foarte mult. În articol vă voi spune experiența integrării cu instrumente deschise și popularul IP PBX freepbxși luați în considerare, de asemenea, logica lucrării diferitelor părți

Lucrez ca outsourcer într-o companie care vinde și configurează, integrează telefonie IP. Când am fost întrebat dacă putem oferi ceva acestei companii și acestei companii pentru a integra Bitrix24 cu PBX-urile pe care le au clienții, precum și cu PBX-urile virtuale de pe diverse companii VDS, am mers la Google. Și bineînțeles că mi-a dat un link către articol în habr, unde există o descriere și github și totul pare să funcționeze. Dar când am încercat să utilizați această soluție, s-a dovedit că Bitrix24 nu mai este la fel ca înainte și trebuie refăcute multe. În plus, FreePBX nu este un asterisc simplu pentru dvs., aici trebuie să vă gândiți la cum să combinați ușurința de utilizare și un dialplan hardcore în fișierele de configurare.

Studiem logica muncii

Deci, pentru început, cum ar trebui să funcționeze totul. Când se primește un apel din afara PBX (eveniment SIP INVITE de la furnizor), începe procesarea planului de apelare (plan de apelare, plan de apelare) - regulile despre ce și în ce ordine se face cu apelul. Din primul pachet, puteți obține o mulțime de informații, care pot fi apoi folosite în reguli. Un instrument excelent pentru studierea elementelor interne ale SIP este analizorul sngrep (legătură) care este pur și simplu instalat în distribuțiile populare prin apt install/yum install și altele asemenea, dar poate fi construit și din sursă. Să ne uităm la jurnalul de apeluri din sngrep

Înțelegerea FreePBX și integrarea acestuia cu Bitrix24 și altele

Într-o formă simplificată, dialplan-ul se ocupă doar de primul pachet, uneori și în timpul conversației, se transferă apeluri, apăsări de butoane (DTMF), diverse lucruri interesante precum FollowMe, RingGroup, IVR și altele.

Ce se află în pachetul de invitații

Înțelegerea FreePBX și integrarea acestuia cu Bitrix24 și altele

De fapt, majoritatea planurilor de apelare simple funcționează cu primele două câmpuri, iar întreaga logică se învârte în jurul DID și CallerID. DID - unde sunăm, CallerID - cine sună.

Dar la urma urmei, avem o companie și nu un singur telefon - ceea ce înseamnă că PBX-ul are cel mai probabil grupuri de apeluri (suneri simultane / consecutive ale mai multor dispozitive) pe numerele orașului (Ring Group), IVR (Bună ziua, ai sunat... Apăsați unul pentru...), Robote telefonice (Expresii), Condiții de timp, Redirecționare către alte numere sau către o celulă (FollowMe, Forward). Aceasta înseamnă că este foarte dificil să determinați fără ambiguitate cine va primi de fapt un apel și cu cine va avea o conversație atunci când sosește un apel. Iată un exemplu de început al unui apel tipic în PBX-ul clienților noștri

Înțelegerea FreePBX și integrarea acestuia cu Bitrix24 și altele

După ce apelul intră cu succes în PBX, acesta se deplasează prin dialplan în diferite „contexte”. Contextul din punctul de vedere al Asteriscului este un set numerotat de comenzi, fiecare dintre ele conținând un filtru după numărul format (se numește exten, pentru un apel extern în stadiul inițial exten=DID). Comenzile din linia dialplan pot fi orice - funcții interne (de exemplu, apelați un abonat intern - Dial(), pune telefonul jos - Hangup()), operatori condiționali (IF, ELSE, ExecIF și altele asemenea), treceri la alte reguli ale acestui context (Goto, GotoIF), trecerea la alte contexte sub forma unui apel de funcție (Gosub, Macro). O directivă separată include имя_контекста, care adaugă comenzi din alt context la sfârșitul contextului curent. Comenzile incluse prin include sunt întotdeauna executate după comenzile contextului curent.

Întreaga logică a FreePBX este construită pe includerea unor contexte diferite unul în celălalt prin include și apel prin intermediul handlerelor Gosub, Macro și Handler. Luați în considerare contextul apelurilor primite FreePBX

Înțelegerea FreePBX și integrarea acestuia cu Bitrix24 și altele

Apelul trece pe rând prin toate contextele de sus în jos, în fiecare context pot exista apeluri către alte contexte precum macro-uri (Macro), funcții (Gosub) sau doar tranziții (Goto), astfel încât arborele real al ceea ce se numește poate doar să fie urmărite în jurnalele.

O diagramă de configurare tipică pentru un PBX tipic este prezentată mai jos. La apel, se caută DID în rutele de intrare, se verifică condițiile temporare, dacă totul este în ordine, se lansează meniul vocal. Din acesta, apăsând butonul 1 sau timeout, ieșiți în grupul de operatori de apelare. După încheierea apelului, este apelată macro-ul hangupcall, după care nu se poate face nimic în dialplan, cu excepția handler-urilor speciali (handler hangup).

Înțelegerea FreePBX și integrarea acestuia cu Bitrix24 și altele

Unde în acest algoritm de apel ar trebui să furnizăm informații despre începutul apelului către CRM, unde să începem înregistrarea, unde să încheiem înregistrarea și să o trimitem împreună cu informații despre apelul către CRM?

Integrare cu sisteme externe

Ce este integrarea PBX și CRM? Acestea sunt setări și programe care convertesc datele și evenimentele între aceste două platforme și le trimit reciproc. Cea mai comună modalitate prin care sistemele independente de a comunica este prin intermediul API-urilor, iar cea mai populară modalitate de a accesa API-urile este HTTP REST. Dar nu pentru asterisc.

În interiorul Asterisk este:

  • AGI - apel sincron al programelor/componentelor externe, folosit în principal în dialplan, există biblioteci precum phpagi, PAGI

  • AMI - un socket TCP text care funcționează pe principiul abonării la evenimente și introducerii comenzilor text, seamănă cu SMTP din interior, poate urmări evenimente și gestiona apelurile, există o bibliotecă PAMI - cel mai popular pentru crearea unei conexiuni cu Asterisk

Exemplu de ieșire AMI

Eveniment: canal nou
Privilegi: sunați, toți
Canal: PJSIP/VMS_pjsip-0000078b
Stare canal: 4
ChannelStateDesc: Sună
Număr ID apelant: 111222
Nume ID apelant: 111222
ConnectedLineNum:
nume de linie conectat:
Limba: en
Codul contului:
Context: de la-pstn
Exten: s
Prioritate: 1
Uniqueid: 1599589046.5244
Linkedid: 1599589046.5244

  • ARI este un amestec al ambelor, toate prin REST, WebSocket, în format JSON - dar cu biblioteci și wrapper-uri proaspete, nu foarte bune, găsite de la îndemână (phparia, phpari) care au devenit în dezvoltarea lor în urmă cu aproximativ 3 ani.

Exemplu de ieșire ARI atunci când este inițiat un apel

{ "variable":"CallMeCallerIDName", "value":"111222", "type":"ChannelVarset", "timestamp":"2020-09-09T09:38:36.269+0000", "canal":{ "id »:»1599644315.5334″, «nume»:»PJSIP/VMSpjsip-000007b6″, „state”:„Sonerie”, „apelant”:{ „nume”:”111222″, „număr”:”111222″ }, „conectat”:{ „nume”:””, „număr” :"" }, "accountcode":"", "dialplan":{ "context":"from-pstn", "exten":"s", "priority":2, "appname":"Stază", "aplicațiedate":"hello-world" }, "creationtime":"2020-09-09T09:38:35.926+0000", "language":"ro" }, "asterisc"id":"48:5b:aa:aa:aa:aa", "application":"hello-world" }

Comoditatea sau inconvenientul, posibilitatea sau imposibilitatea de a lucra cu un anumit API sunt determinate de sarcinile care trebuie rezolvate. Sarcinile pentru integrarea cu CRM sunt următoarele:

  • Urmăriți începutul apelului, unde a fost transferat, scoateți ID apelant, DID, orele de început și de sfârșit, poate date din director (pentru a căuta o conexiune între telefon și utilizatorul CRM)

  • Începeți și terminați înregistrarea apelului, salvați-l în formatul dorit, informați la sfârșitul înregistrării unde se află fișierul

  • Inițiază un apel la un eveniment extern (din program), apelează un număr intern, un număr extern și conectează-le

  • Opțional: se integrează cu CRM, grupuri de dialer și FollowME pentru transferul automat al apelurilor în absența unui loc (conform CRM)

Toate aceste sarcini pot fi rezolvate prin AMI sau ARI, dar ARI oferă mult mai puține informații, nu sunt multe evenimente, multe variabile pe care AMI le mai are (de exemplu, apeluri macro, setarea variabilelor în interiorul macro-urilor, inclusiv înregistrarea apelurilor) nu sunt urmărite. Prin urmare, pentru o urmărire corectă și precisă, să alegem AMI pentru moment (dar nu complet). În plus (ei bine, unde ar fi fără asta, suntem oameni leneși) - în lucrarea originală (articol în habr) utilizați PAMI. *Apoi trebuie să încercați să rescrieți în ARI, dar nu și faptul că va funcționa.

Reinventarea integrării

Pentru ca FreePBX-ul nostru să poată raporta către AMI în moduri simple despre începutul apelului, ora de încheiere, numerele, numele fișierelor înregistrate, este mai ușor să calculați durata apelului folosind același truc ca și autorii originali. - introduceți variabilele și analizați rezultatul pentru prezența lor. PAMI sugerează să faceți acest lucru pur și simplu printr-o funcție de filtru.

Iată un exemplu de setare a propriei variabile pentru ora de începere a apelului (s este un număr special din planul de apelare care se efectuează ÎNAINTE de a începe căutarea DID)

[ext-did-custom]

exten => s,1,Set(CallStart=${STRFTIME(epoch,,%s)})

Un exemplu de eveniment AMI pentru această linie

Eveniment: canal nou

Privilegi: sunați, toți

Canal: PJSIP/VMS_pjsip-0000078b

Stare canal: 4

ChannelStateDesc: Sună

Număr ID apelant: 111222

Nume ID apelant: 111222

ConnectedLineNum:

nume de linie conectat:

Limba: en

Codul contului:

Context: de la-pstn

Exten: s

Prioritate: 1

Uniqueid: 1599589046.5244

Linkedid: 1599589046.5244

Aplicație: Setați AppData:

CallStart=1599571046

Deoarece FreePBX suprascrie fișierele extention.conf și extention_additional.conf, vom folosi fișierul extensie_personalizat.conf

Codul complet al extensiei_custom.conf

[globals]	
;; Проверьте пути и права на папки - юзер asterisk должен иметь права на запись
;; Сюда будет писаться разговоры
WAV=/var/www/html/callme/records/wav 
MP3=/var/www/html/callme/records/mp3

;; По этим путям будет воспроизводится и скачиваться запись
URLRECORDS=https://www.host.ru/callmeplus/records/mp3

;; Адрес для калбека при исходящем вызове
URLPHP=https://www.host.ru/callmeplus

;; Да пишем разговоры
RECORDING=1

;; Это макрос для записи разговоров в нашу папку. 
;; Можно использовать и системную запись, но пока пусть будет эта - 
;; она работает
[recording]
exten => ~~s~~,1,Set(LOCAL(calling)=${ARG1})
exten => ~~s~~,2,Set(LOCAL(called)=${ARG2})
exten => ~~s~~,3,GotoIf($["${RECORDING}" = "1"]?4:14)
exten => ~~s~~,4,Set(fname=${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${calling}-${called})
exten => ~~s~~,5,Set(datedir=${STRFTIME(${EPOCH},,%Y/%m/%d)})
exten => ~~s~~,6,System(mkdir -p ${MP3}/${datedir})
exten => ~~s~~,7,System(mkdir -p ${WAV}/${datedir})
exten => ~~s~~,8,Set(monopt=nice -n 19 /usr/bin/lame -b 32  --silent "${WAV}/${datedir}/${fname}.wav"  "${MP3}/${datedir}/${fname}.mp3" && rm -f "${WAV}/${fname}.wav" && chmod o+r "${MP3}/${datedir}/${fname}.mp3")
exten => ~~s~~,9,Set(FullFname=${URLRECORDS}/${datedir}/${fname}.mp3)
exten => ~~s~~,10,Set(CDR(filename)=${fname}.mp3)
exten => ~~s~~,11,Set(CDR(recordingfile)=${fname}.wav)
exten => ~~s~~,12,Set(CDR(realdst)=${called})
exten => ~~s~~,13,MixMonitor(${WAV}/${datedir}/${fname}.wav,b,${monopt})
exten => ~~s~~,14,NoOp(Finish if_recording_1)
exten => ~~s~~,15,Return()


;; Это основной контекст для начала разговора
[ext-did-custom]

;; Это хулиганство, делать это так и здесь, но работает - добавляем к номеру '8'
exten =>  s,1,Set(CALLERID(num)=8${CALLERID(num)})

;; Тут всякие переменные для скрипта
exten =>  s,n,Gosub(recording,~~s~~,1(${CALLERID(number)},${EXTEN}))
exten =>  s,n,ExecIF(${CallMeCallerIDName}?Set(CALLERID(name)=${CallMeCallerIDName}):NoOp())
exten =>  s,n,Set(CallStart=${STRFTIME(epoch,,%s)})
exten =>  s,n,Set(CallMeDISPOSITION=${CDR(disposition)})

;; Самое главное! Обработчик окончания разговора. 
;; Обычные пути обработки конца через (exten=>h,1,чтототут) в FreePBX не работают - Macro(hangupcall,) все портит. 
;; Поэтому вешаем Hangup_Handler на окончание звонка
exten => s,n,Set(CHANNEL(hangup_handler_push)=sub-call-from-cid-ended,s,1(${CALLERID(num)},${EXTEN}))

;; Обработчик окончания входящего вызова
[sub-call-from-cid-ended]

;; Сообщаем о значениях при конце звонка
exten => s,1,Set(CDR_PROP(disable)=true)
exten => s,n,Set(CallStop=${STRFTIME(epoch,,%s)})
exten => s,n,Set(CallMeDURATION=${MATH(${CallStop}-${CallStart},int)})

;; Статус вызова - Ответ, не ответ...
exten => s,n,Set(CallMeDISPOSITION=${CDR(disposition)})
exten => s,n,Return


;; Обработчик исходящих вызовов - все аналогичено
[outbound-allroutes-custom]

;; Запись
exten => _.,1,Gosub(recording,~~s~~,1(${CALLERID(number)},${EXTEN}))
;; Переменные
exten => _.,n,Set(__CallIntNum=${CALLERID(num)})
exten => _.,n,Set(CallExtNum=${EXTEN})
exten => _.,n,Set(CallStart=${STRFTIME(epoch,,%s)})
exten => _.,n,Set(CallmeCALLID=${SIPCALLID})

;; Вешаем Hangup_Handler на окончание звонка
exten => _.,n,Set(CHANNEL(hangup_handler_push)=sub-call-internal-ended,s,1(${CALLERID(num)},${EXTEN}))

;; Обработчик окончания исходящего вызова
[sub-call-internal-ended]

;; переменные
exten => s,1,Set(CDR_PROP(disable)=true)
exten => s,n,Set(CallStop=${STRFTIME(epoch,,%s)})
exten => s,n,Set(CallMeDURATION=${MATH(${CallStop}-${CallStart},int)})
exten => s,n,Set(CallMeDISPOSITION=${CDR(disposition)})

;; Вызов скрипта, который сообщит о звонке в CRM - это исходящий, 
;; так что по факту окончания
exten => s,n,System(curl -s ${URLPHP}/CallMeOut.php --data action=sendcall2b24 --data ExtNum=${CallExtNum} --data call_id=${SIPCALLID} --data-urlencode FullFname='${FullFname}' --data CallIntNum=${CallIntNum} --data CallDuration=${CallMeDURATION} --data-urlencode CallDisposition='${CallMeDISPOSITION}')
exten => s,n,Return

Caracteristică și diferență față de planul de apel original al autorilor articolului original -

  • Dialplan în format .conf, așa cum vrea FreePBX (da, poate .ael, dar nu toate versiunile și nu este întotdeauna convenabil)

  • În loc să proceseze finalul prin exten => h, procesarea a fost introdusă prin hangup_handler, deoarece dialplanul FreePBX a funcționat doar cu el

  • S-a corectat șirul de apeluri de script, ghilimele adăugate și numărul de apel extern ExtNum

  • Procesarea este mutată în contexte _personalizate și vă permite să nu atingeți sau să editați configurațiile FreePBX - primite prin [ext-a-personalizat], ieșire prin [outbound-allroutes-personalizat]

  • Fără legătură cu numere - fișierul este universal și trebuie configurat doar pentru calea și legătura la server

Pentru a începe, trebuie să rulați scripturi în AMI prin autentificare și parolă - pentru aceasta, FreePBX are și un fișier _custom

fișier manager_custom.conf

;;  это логин
[callmeplus]
;; это пароль
secret = trampampamturlala
deny = 0.0.0.0/0.0.0.0

;; я работаю с локальной машиной - но если надо, можно и другие прописать
permit = 127.0.0.1/255.255.255.255
read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan
write = system,call,agent,log,verbose,user,config,command,reporting,originate

Ambele fișiere trebuie să fie plasate în /etc/asterisk, apoi recitiți configurațiile (sau reporniți asteriscul)

# astrisk -rv
  Connected to Asterisk 16.6.2 currently running on freepbx (pid = 31629)
#freepbx*CLI> dialplan reload
     Dialplan reloaded.
#freepbx*CLI> exit

Acum să trecem la PHP

Inițializarea scripturilor și crearea unui serviciu

Deoarece schema de lucru cu Bitrix 24, un serviciu pentru AMI, nu este în întregime simplă și transparentă, trebuie discutată separat. Asterisk, când AMI este activat, pur și simplu deschide portul și gata. Când un client se alătură, acesta solicită autorizare, apoi clientul se abonează la evenimentele necesare. Evenimentele vin în text simplu, pe care PAMI îl transformă în obiecte structurate și oferă posibilitatea de a seta funcția de filtrare numai pentru evenimente de interes, câmpuri, numere etc.

Imediat ce apelul intră, evenimentul NewExten este declanșat pornind de la contextul părinte [from-pstn], apoi toate evenimentele merg în ordinea liniilor din contexte. Când se primesc informații de la variabilele CallMeCallerIDName și CallStart specificate în planul de apelare _custom,

  1. Funcția de solicitare a UserID-ului corespunzător numărului de interior la care a venit apelul. Ce se întâmplă dacă este un grup dial-up? Întrebarea este politică, trebuie să creați un apel către toată lumea deodată (când toată lumea sună deodată) sau să creați așa cum sună atunci când sună pe rând? Majoritatea clienților au strategia First Available, așa că nu este nicio problemă cu aceasta, doar unul sună. Dar problema trebuie rezolvată.

  2. Funcția de înregistrare a apelurilor din Bitrix24, care returnează CallID-ul, care este apoi necesar pentru a raporta parametrii apelului și un link către înregistrare. Necesită fie numărul de extensie, fie UserID

Înțelegerea FreePBX și integrarea acestuia cu Bitrix24 și altele

După încheierea convorbirii, este apelată funcția de descărcare a înregistrărilor, care raportează simultan starea de finalizare a apelului (Ocupat, Fără răspuns, Succes) și, de asemenea, descarcă un link către fișierul mp3 cu înregistrarea (dacă există).

Deoarece modulul CallMeIn.php trebuie să ruleze continuu, a fost creat un fișier de pornire SystemD pentru acesta callme.service, care trebuie introdus în /etc/systemd/system/callme.service

[Unit]
Description=CallMe

[Service]
WorkingDirectory=/var/www/html/callmeplus
ExecStart=/usr/bin/php /var/www/html/callmeplus/CallMeIn.php 2>&1 >>/var/log/callmeplus.log
ExecStop=/bin/kill -WINCH ${MAINPID}
KillSignal=SIGKILL

Restart=on-failure
RestartSec=10s

#тут надо смотреть,какие права на папки
#User=www-data  #Ubuntu - debian
#User=nginx #Centos

[Install]
WantedBy=multi-user.target

inițializarea și lansarea scriptului are loc prin systemctl sau service

# systemctl enable callme
# systemctl start callme

Serviciul se va reporni după cum este necesar (în caz de blocări). Serviciul de urmărire inbox nu necesită instalarea unui server web, este nevoie doar de php (care se află cu siguranță pe serverul FeePBX). Dar în lipsa accesului la înregistrările apelurilor prin serverul Web (tot cu https), nu va fi posibilă ascultarea înregistrărilor apelurilor.

Acum să vorbim despre apelurile efectuate. Scriptul CallMeOut.php are două funcții:

  • Inițierea unui apel atunci când se primește o solicitare pentru un script php (inclusiv utilizarea butonului „Apel” din Bitrix însuși). Nu funcționează fără un server web, cererea este primită prin HTTP POST, cererea conține un token

  • Mesaj despre apel, parametrii și înregistrările acestuia în Bitrix. Declanșat de Asterisk în planul de apel [sub-call-internal-ended] când se termină un apel

Înțelegerea FreePBX și integrarea acestuia cu Bitrix24 și altele

Serverul web este necesar doar pentru două lucruri - descărcarea fișierelor de înregistrare Bitrix (prin HTTPS) și apelarea script-ului CallMeOut.php. Puteți utiliza serverul FreePBX încorporat, fișierele pentru care sunt /var/www/html, puteți instala un alt server sau puteți specifica o cale diferită.

server web

Să lăsăm configurarea serverului web pentru studiu independent (tyts, tyts, tyts). Dacă nu aveți un domeniu, puteți încerca FreeDomain( https://www.freenom.com/ru/index.html), care vă va oferi un nume gratuit pentru IP-ul dumneavoastră alb (nu uitați să redirecționați porturile 80, 443 prin router dacă adresa externă este doar pe acesta). Dacă tocmai ați creat un domeniu DNS, atunci trebuie să așteptați (de la 15 minute la 48 de ore) până când toate serverele sunt încărcate. Conform experienței de lucru cu furnizorii autohtoni - de la 1 oră la o zi.

Automatizare instalatii

Un program de instalare a fost dezvoltat pe github pentru a face instalarea și mai ușoară. Dar a fost neted pe hârtie - în timp ce le instalăm pe toate manual, deoarece după ce am reparat toate acestea, a devenit clar ce este prieten cu cine, cine merge unde și cum să-l depanați. Nu există încă un instalator

Docher

Dacă doriți să încercați rapid soluția - există o opțiune cu Docker - creați rapid un container, dați-i porturi în exterior, strecurați fișierele de setări și încercați (aceasta este opțiunea cu containerul LetsEncrypt, dacă aveți deja un certificat , trebuie doar să redirecționați proxy-ul invers către serverul web FreePBX (i-am dat un alt port este 88), LetsEncrypt în docker pe baza din acest articol

Trebuie să rulați fișierul în folderul de proiect descărcat (după clonarea git), dar mai întâi intrați în configurațiile asterisc (dosarul asterisc) și scrieți acolo căile către înregistrări și adresa URL a site-ului dvs.

version: '3.3'
services:
  nginx:
    image: nginx:1.15-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/ssl_docker.conf:/etc/nginx/conf.d/ssl_docker.conf
  certbot:
    image: certbot/certbot
  freepbx:
    image: flaviostutz/freepbx
    ports:
      - 88:80 # для настройки
      - 5060:5060/udp
      - 5160:5160/udp
      - 127.0.0.1:5038:5038 # для CallMeOut.php
#      - 3306:3306
      - 18000-18100:18000-18100/udp
    restart: always
    environment:
      - ADMIN_PASSWORD=admin123
    volumes:
      - backup:/backup
      - recordings:/var/spool/asterisk/monitor
      - ./callme:/var/www/html/callme
      - ./systemd/callme.service:/etc/systemd/system/callme.conf
      - ./asterisk/manager_custom.conf:/etc/asterisk/manager_custom.conf
      - ./asterisk/extensions_custom.conf:/etc/asterisk/extensions_custom.conf
#      - ./conf/startup.sh:/startup.sh

volumes:
  backup:
  recordings:

Acest fișier docker-compose.yaml este rulat prin

docker-compose up -d

Dacă nginx nu pornește, atunci ceva este în neregulă cu configurația din folderul nginx/ssl_docker.conf

Alte integrări

Și de ce să nu punem niște CRM în scripturi în același timp, ne-am gândit. Am studiat mai multe alte API-uri CRM, în special PBX-ul încorporat gratuit - ShugarCRM și Vtiger, și da! da, principiul este acelasi. Dar aceasta este o altă poveste, pe care o vom încărca mai târziu în github separat.

referințe

Disclaimer: orice asemănare cu realitatea este fictivă și nu am fost eu.

Sursa: www.habr.com

Adauga un comentariu