FreePBX begrijpen en integreren met Bitrix24 en meer

Bitrix24 is een enorme combinatie die CRM, workflow, boekhouding en vele andere dingen combineert die managers erg leuk vinden en IT-personeel niet echt leuk vindt. Het portaal wordt gebruikt door veel kleine en middelgrote bedrijven, waaronder kleine klinieken, fabrikanten en zelfs schoonheidssalons. De belangrijkste functie waar managers "van houden" is de integratie van telefonie en CRM, wanneer elk gesprek onmiddellijk wordt opgenomen in CRM, worden klantkaarten gemaakt, bij inkomend wordt informatie over de klant weergegeven en kunt u onmiddellijk zien wie hij is, wat hij kan verkopen en hoeveel hij verschuldigd is. Maar telefonie uit Bitrix24 en de integratie ervan met CRM kost geld, soms veel. In het artikel vertel ik je de ervaring van het integreren met open tools en de populaire IP PBX FreePBX, en overweeg ook de logica van het werk van verschillende delen

Ik werk als outsourcer in een bedrijf dat IP-telefonie verkoopt, configureert en integreert. Toen mij werd gevraagd of we dit en dit bedrijf iets konden bieden om Bitrix24 te integreren met PBX'en die klanten hebben, evenals met virtuele PBX'en op verschillende VDS-bedrijven, stapte ik naar Google. En natuurlijk gaf hij me een link naar artikel in habr, waar een beschrijving is, en github, en alles lijkt te werken. Maar toen ik deze oplossing probeerde te gebruiken, bleek dat Bitrix24 niet meer hetzelfde is als voorheen en dat er veel opnieuw moet worden gedaan. Bovendien is FreePBX geen kaal sterretje voor jou, hier moet je nadenken over hoe je gebruiksgemak en een hardcore dialplan combineert in configuratiebestanden.

We bestuderen de logica van werk

Dus om te beginnen, hoe het allemaal zou moeten werken. Wanneer er een oproep binnenkomt van buiten de PBX (SIP INVITE-gebeurtenis van de provider), begint de verwerking van het kiesplan (kiesplan, kiesplan) - de regels van wat en in welke volgorde te doen met de oproep. Vanaf het eerste pakket kun je veel informatie krijgen, die vervolgens in de regels kan worden gebruikt. Een uitstekend hulpmiddel voor het bestuderen van de interne onderdelen van SIP is de analysator snurk (link) dat eenvoudig in populaire distributies wordt geïnstalleerd via apt install/yum install en dergelijke, maar het kan ook vanaf de bron worden gebouwd. Laten we eens kijken naar het oproeplog in sngrep

FreePBX begrijpen en integreren met Bitrix24 en meer

In een vereenvoudigde vorm behandelt het dialplan alleen het eerste pakket, soms ook tijdens het gesprek, worden oproepen doorverbonden, op knoppen gedrukt (DTMF), verschillende interessante dingen zoals FollowMe, RingGroup, IVR en andere.

Wat zit er in het uitnodigingspakket

FreePBX begrijpen en integreren met Bitrix24 en meer

Eigenlijk werken de meeste eenvoudige kiesplannen met de eerste twee velden, en de hele logica draait om DID en BellerID. DID - waar we bellen, CallerID - wie belt.

Maar we hebben tenslotte een bedrijf en niet één telefoon - wat betekent dat de PBX hoogstwaarschijnlijk oproepgroepen heeft (gelijktijdig / achtereenvolgend overgaan van meerdere apparaten) op stadsnummers (Ring Group), IVR (Hallo, u belde ... Druk op één voor ...), Antwoordapparaten ( Zinnen), Tijdcondities, Doorschakelen naar andere nummers of naar een cel (FollowMe, Doorsturen). Hierdoor is het zeer moeilijk om eenduidig ​​vast te stellen wie er daadwerkelijk gebeld wordt en met wie een gesprek gevoerd wordt als er een oproep binnenkomt. Hier is een voorbeeld van het begin van een typisch gesprek in de PBX van onze klanten

FreePBX begrijpen en integreren met Bitrix24 en meer

Nadat het gesprek met succes de PBX is binnengekomen, doorloopt het het kiesplan in verschillende "contexten". De context vanuit het oogpunt van Asterisk is een genummerde reeks commando's, die elk een filter bevatten op basis van het gekozen nummer (het heet exten, voor een extern gesprek in de beginfase exten=DID). De commando's in de dialplan-regel kunnen van alles zijn - interne functies (bijvoorbeeld een interne deelnemer bellen - Dial(), leg de telefoon neer - Hangup()), voorwaardelijke operatoren (IF, ELSE, ExecIF en dergelijke), overgangen naar andere regels van deze context (Goto, GotoIF), overgang naar andere contexten in de vorm van een functieaanroep (Gosub, Macro). Een aparte richtlijn include имя_контекста, die commando's uit een andere context toevoegt aan het einde van de huidige context. Commando's opgenomen via include worden altijd uitgevoerd na commando's van de huidige context.

De hele logica van FreePBX is gebaseerd op het in elkaar opnemen van verschillende contexten door middel van include en call via Gosub-, Macro- en Handler-handlers. Houd rekening met de context van inkomende FreePBX-oproepen

FreePBX begrijpen en integreren met Bitrix24 en meer

De aanroep gaat beurtelings door alle contexten van boven naar beneden, in elke context kunnen er aanroepen zijn naar andere contexten zoals macro's (Macro), functies (Gosub) of alleen overgangen (Goto), dus de echte boom van wat wordt aangeroepen kan alleen worden gevolgd in de logboeken.

Hieronder ziet u een typisch configuratieschema voor een typische PBX. Bij het bellen wordt DID gezocht in inkomende routes, tijdelijke voorwaarden worden gecontroleerd, als alles in orde is, wordt het spraakmenu gestart. Hieruit, door op knop 1 of time-out te drukken, gaat u naar de groep bellende operators. Nadat het gesprek is beëindigd, wordt de ophang-macro aangeroepen, waarna er niets meer kan worden gedaan in het kiesplan, behalve speciale handlers (ophang-handler).

FreePBX begrijpen en integreren met Bitrix24 en meer

Waar in dit oproepalgoritme moeten we informatie verstrekken over het begin van het gesprek naar CRM, waar de opname starten, waar de opname beëindigen en samen met informatie over het gesprek naar CRM sturen?

Integratie met externe systemen

Wat is PBX- en CRM-integratie? Dit zijn instellingen en programma's die gegevens en gebeurtenissen tussen deze twee platforms converteren en naar elkaar sturen. De meest gebruikelijke manier voor onafhankelijke systemen om te communiceren is via API's, en de meest populaire manier om toegang te krijgen tot API's is HTTP REST. Maar niet voor sterretjes.

Binnen Asterisk is:

  • AGI - synchrone oproep van externe programma's/componenten, voornamelijk gebruikt in het dialplan, er zijn bibliotheken zoals phpage, PAGI

  • AMI - een tekst-TCP-socket die werkt volgens het principe van abonneren op gebeurtenissen en het invoeren van tekstopdrachten, lijkt op SMTP van binnenuit, kan gebeurtenissen volgen en oproepen beheren, er is een bibliotheek PAMI - de meest populaire voor het maken van een verbinding met Asterisk

Voorbeeld van AMI-uitvoer

Evenement: Nieuw kanaal
Privilege: bellen, allemaal
Kanaal: PJSIP/VMS_pjsip-0000078b
Kanaalstatus: 4
KanaalStatusBeschrijving: Ring
BellerIDNum: 111222
Naam beller: 111222
ConnectedLineNum:
verbonden lijnnaam:
Taal: nl
rekeningcode:
Context: van-pstn
Uitgebreid: s
Prioriteit: 1
Uniek ID: 1599589046.5244
Linkedid: 1599589046.5244

  • ARI is een mix van beide, allemaal via REST, WebSocket, in JSON-formaat - maar met verse bibliotheken en wrappers, niet erg goed, terloops gevonden (phparia, phpari) die ongeveer 3 jaar geleden in hun ontwikkeling kwamen.

Voorbeeld van ARI-uitvoer wanneer een oproep wordt gestart

{ "variable":"CallMeCallerIDName", "value":"111222", "type":"ChannelVarset", "timestamp":"2020-09-09T09:38:36.269+0000", "channel":{ "id »:»1599644315.5334″, «naam»:»PJSIP/VMSpjsip-000007b6″, "state":"Ring", "caller":{ "name":"111222″, "number":"111222″ }, "connected":{ "name":"", "number" :"" }, "accountcode":"", "dialplan":{ "context":"from-pstn", "exten":"s", "priority":2, "appname":"Stasis", "appdata":"hello-world" }, "creationtime":"2020-09-09T09:38:35.926+0000", "language":"en" }, "asteriskid":"48:5b:aa:aa:aa:aa", "application":"hallo-wereld" }

Gemak of ongemak, de mogelijkheid of onmogelijkheid om met een bepaalde API te werken, wordt bepaald door de taken die moeten worden opgelost. De taken voor integratie met CRM zijn als volgt:

  • Volg het begin van het gesprek, waar het is doorverbonden, haal nummerherkenning, DID, begin- en eindtijden eruit, misschien gegevens uit de directory (om te zoeken naar een verbinding tussen de telefoon en de CRM-gebruiker)

  • Start en stop de opname van het gesprek, sla het op in het gewenste formaat, informeer aan het einde van de opname waar het bestand zich bevindt

  • Start een oproep op een externe gebeurtenis (vanuit het programma), bel een intern nummer, een extern nummer en verbind ze

  • Optioneel: integreren met CRM, kiezergroepen en FollowME voor automatische doorschakeling van oproepen bij afwezigheid van een plaats (volgens CRM)

Al deze taken kunnen worden opgelost via AMI of ARI, maar ARI geeft veel minder informatie, er zijn niet veel gebeurtenissen, veel variabelen die AMI nog heeft (bijvoorbeeld macro-oproepen, instellingsvariabelen binnen macro's, inclusief oproepopname) worden niet bijgehouden. Laten we daarom voor een correcte en nauwkeurige tracking voorlopig AMI kiezen (maar niet volledig). Bovendien (nou ja, waar zou het zijn zonder dit, we zijn luie mensen) - in het originele werk (artikel in habr) gebruik PAMI. *Dan moet je proberen te herschrijven naar ARI, maar niet het feit dat het zal werken.

Integratie opnieuw uitvinden

Om ervoor te zorgen dat onze FreePBX op eenvoudige manieren aan AMI kan rapporteren over het begin van het gesprek, de eindtijd, nummers, namen van opgenomen bestanden, is het het gemakkelijkst om de duur van het gesprek te berekenen met dezelfde truc als de oorspronkelijke auteurs - voer uw variabelen in en ontleed de uitvoer op hun aanwezigheid. PAMI stelt voor dit eenvoudig te doen door middel van een filterfunctie.

Hier is een voorbeeld van het instellen van uw eigen variabele voor de starttijd van de oproep (s is een speciaal nummer in het kiesplan dat wordt uitgevoerd VOORDAT de DID-zoekopdracht wordt gestart)

[ext-did-custom]

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

Een voorbeeld van een AMI-gebeurtenis voor deze lijn

Evenement: Nieuw kanaal

Privilege: bellen, allemaal

Kanaal: PJSIP/VMS_pjsip-0000078b

Kanaalstatus: 4

KanaalStatusBeschrijving: Ring

BellerIDNum: 111222

Naam beller: 111222

ConnectedLineNum:

verbonden lijnnaam:

Taal: nl

rekeningcode:

Context: van-pstn

Uitgebreid: s

Prioriteit: 1

Uniek ID: 1599589046.5244

Linkedid: 1599589046.5244

Applicatie: Stel AppData in:

BelStart=1599571046

Omdat FreePBX de extension.conf- en extension_-bestanden overschrijftadditional.conf, zullen we het bestand gebruiken extension_gewoonte.conf

Volledige code van extention_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

Kenmerk en verschil met het originele inbelplan van de auteurs van het originele artikel -

  • Dialplan in .conf-formaat, zoals FreePBX het wil (ja, het kan .ael, maar niet alle versies en het is niet altijd handig)

  • In plaats van het einde te verwerken via exten=>h, werd de verwerking geïntroduceerd via hangup_handler, omdat het FreePBX-kiesplan alleen daarmee werkte

  • Vaste script-oproepstring, toegevoegde aanhalingstekens en extern oproepnummer ExtNum

  • Verwerking is verplaatst naar _custom contexten en stelt u in staat FreePBX-configuraties niet aan te raken of te bewerken - inkomend via [ext-deed-gebruik], uitgaand via [uitgaand-alleroutes-aangepast]

  • Geen binding aan nummers - het bestand is universeel en hoeft alleen te worden geconfigureerd voor het pad en de link naar de server

Om aan de slag te gaan, moet u ook scripts in AMI uitvoeren met login en wachtwoord - hiervoor heeft FreePBX ook een _custom-bestand

manager_custom.conf-bestand

;;  это логин
[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

Beide bestanden moeten in /etc/asterisk worden geplaatst en vervolgens de configuraties opnieuw lezen (of de asterisk opnieuw starten)

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

Laten we nu verder gaan met PHP

Scripts initialiseren en een service maken

Aangezien het schema voor het werken met Bitrix 24, een service voor AMI, niet geheel eenvoudig en transparant is, moet dit apart worden besproken. Asterisk, wanneer AMI is geactiveerd, opent gewoon de poort en dat is alles. Wanneer een client lid wordt, vraagt ​​deze om autorisatie, waarna de client zich abonneert op de noodzakelijke gebeurtenissen. Gebeurtenissen komen in platte tekst, die PAMI converteert naar gestructureerde objecten en biedt de mogelijkheid om de filterfunctie alleen in te stellen voor interessante gebeurtenissen, velden, getallen, enz.

Zodra de oproep binnenkomt, wordt de NewExten-gebeurtenis geactiveerd, uitgaande van de bovenliggende [from-pstn]-context, waarna alle gebeurtenissen in de volgorde van de regels in de contexten gaan. Wanneer informatie wordt ontvangen van de variabelen CallMeCallerIDName en CallStart die zijn opgegeven in het _custom dialplan,

  1. De functie van het aanvragen van de gebruikers-ID die overeenkomt met het toestelnummer waar de oproep binnenkwam. Wat als het een inbelgroep is? De vraag is politiek: moet je iedereen tegelijk bellen (wanneer iedereen tegelijk belt) of creëren terwijl ze bellen wanneer ze beurtelings bellen? De meeste klanten hebben de Fisrt Available-strategie, dus hier is geen probleem mee, er belt er maar één. Maar het probleem moet worden opgelost.

  2. De oproepregistratiefunctie in Bitrix24, die de CallID retourneert, die vervolgens nodig is om de oproepparameters en een link naar de opname te rapporteren. Vereist toestelnummer of gebruikers-ID

FreePBX begrijpen en integreren met Bitrix24 en meer

Na het einde van het gesprek wordt de functie voor het downloaden van opnames opgeroepen, die tegelijkertijd de status van de voltooiing van het gesprek (Bezet, Geen antwoord, Success) meldt en ook een link downloadt naar het mp3-bestand met de opname (indien aanwezig).

Omdat de CallMeIn.php-module continu moet draaien, is hiervoor een SystemD-opstartbestand gemaakt bel mij.service, die in /etc/systemd/system/callme.service moet worden geplaatst

[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

initialisatie en lancering van het script vindt plaats via systemctl of service

# systemctl enable callme
# systemctl start callme

De service zal zichzelf indien nodig opnieuw opstarten (in geval van crashes). Voor de inbox-trackingservice hoeft geen webserver te worden geïnstalleerd, alleen php is nodig (wat zeker op de FeePBX-server staat). Maar bij gebrek aan toegang tot oproeprecords via de webserver (ook met https), is het niet mogelijk om naar oproeprecords te luisteren.

Laten we het nu hebben over uitgaande oproepen. Het CallMeOut.php-script heeft twee functies:

  • Initiatie van een oproep wanneer er een verzoek wordt ontvangen voor een php-script (inclusief het gebruik van de knop "Bellen" in de Bitrix zelf). Zonder webserver werkt het niet, het verzoek komt binnen via HTTP POST, het verzoek bevat een token

  • Bericht over het gesprek, de parameters en records in Bitrix. Ontstoken door Asterisk in het [sub-call-internal-ended] dialplan wanneer een gesprek eindigt

FreePBX begrijpen en integreren met Bitrix24 en meer

De webserver is slechts nodig voor twee dingen: het downloaden van Bitrix-recordbestanden (via HTTPS) en het aanroepen van het CallMeOut.php-script. U kunt de ingebouwde FreePBX-server gebruiken, waarvan de bestanden /var/www/html zijn, u kunt een andere server installeren of een ander pad specificeren.

web Server

Laten we de configuratie van de webserver overlaten aan zelfstudie (tyts, tyts, tyts). Als u geen domein heeft, kunt u FreeDomain( https://www.freenom.com/ru/index.html), waarmee je een gratis naam krijgt voor je witte IP (vergeet niet om poorten 80, 443 door te sturen via de router als het externe adres er alleen op staat). Als je net een DNS-domein hebt aangemaakt, moet je wachten (van 15 minuten tot 48 uur) totdat alle servers zijn geladen. Volgens de ervaring van het werken met binnenlandse providers - van 1 uur tot een dag.

Installatie automatisering

Op github is een installer ontwikkeld om de installatie nog eenvoudiger te maken. Maar het was vlot op papier - terwijl we het allemaal handmatig installeren, want na het sleutelen aan dit alles werd het glashelder wat vrienden zijn met wie, wie waar naartoe gaat en hoe het te debuggen. Er is nog geen installateur

havenarbeider

Als je de oplossing snel wilt proberen - er is een optie met Docker - maak snel een container, geef hem poorten naar buiten, schuif de instellingenbestanden en probeer (dit is de optie met de LetsEncrypt-container, als je al een certificaat hebt , je hoeft alleen maar de reverse proxy om te leiden naar de FreePBX-webserver (we hebben hem een ​​andere poort gegeven is 88), LetsEncrypt in docker gebaseerd op dit artikel

U moet het bestand uitvoeren in de gedownloade projectmap (na git clone), maar ga eerst naar de asterisk configs (asterisk-map) en schrijf daar de paden naar de records en de URL van uw site

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:

Dit bestand docker-compose.yaml wordt uitgevoerd via

docker-compose up -d

Als nginx niet start, is er iets mis met de configuratie in de map nginx/ssl_docker.conf

Andere integraties

En waarom zouden we niet tegelijkertijd wat CRM in scripts stoppen, dachten we. We hebben verschillende andere CRM-API's bestudeerd, vooral de gratis ingebouwde PBX - ShugarCRM en Vtiger, en ja! ja het principe is hetzelfde. Maar dit is een ander verhaal, dat we later afzonderlijk naar de github zullen uploaden.

referenties

Disclaimer: elke gelijkenis met de werkelijkheid is fictief en ik was het niet.

Bron: www.habr.com

Voeg een reactie