Lad os se på FreePBX og integrere det med Bitrix24 og mere.

Bitrix24 — er en omfattende platform, der kombinerer CRM, dokumenthåndtering, regnskab og mange andre funktioner, som især er populære blandt ledere, men ikke altid værdsættes af IT-personalet. Portalen anvendes af mange små og mellemstore virksomheder, herunder mindre klinikker, producenter og endda skønhedssaloner. Den mest værdsatte funktion blandt ledere er integrationen af telefonitjenester med CRM, hvor hvert opkald straks registreres i CRM, der oprettes kundekort, og der vises oplysninger om kunden, så man hurtigt kan se, hvem de er, hvad man kan sælge til dem, og hvor meget de skylder. Men telefonitjenesterne fra Bitrix24 og deres integration med CRM koster penge, nogle gange en del. I denne artikel vil jeg dele erfaringerne med at integrere med åbne værktøjer og populære IP-telefoni-løsninger. FreePBX, og jeg vil også se på, hvordan forskellige dele fungerer.

Jeg arbejder som freelancer i en virksomhed, der sælger og opsætter integrationer af IP-telefoni. Da jeg blev spurgt, om vi kunne tilbyde integration af Bitrix24 med de telefonisystemer, der allerede findes hos kunderne, samt med virtuelle telefonisystemer på forskellige VDS, gik jeg i gang med at søge på Google. Og det gav mig selvfølgelig et link til en artikel på Habr, som både indeholder en beskrivelse, og der er en GitHub, hvor det hele angiveligt fungerer. Men da jeg forsøgte at bruge denne løsning, opdagede jeg, at Bitrix24 ikke er det samme som før, og der skal laves mange ændringer. Desuden er FreePBX ikke bare en simpel Asterisk; man skal tænke over, hvordan man kombinerer brugervenlighed med den komplekse dialplan i konfigurationsfilene.

Vi undersøger logikken bag arbejdet

For det første, hvordan det hele skal fungere. Når der kommer et opkald udefra til telefonisystemet (SIP INVITE-begivenheden fra udbyderen), starter behandlingen af dialplanen — reglerne for, hvad der skal gøres og i hvilken rækkefølge med opkaldet. Fra den første pakke kan man få mange oplysninger, som senere kan anvendes i reglerne. Et fremragende værktøj til at studere indholdet af SIP er analysatoren sngrep (link) som nemt kan installeres på populære distributioner via apt install/yum install og lignende, men kan også samles fra kildekoden. Lad os se på loggen for opkaldet i sngrep.

Lad os se på FreePBX og integrere det med Bitrix24 og mere.

I et forenklet perspektiv beskæftiger dialplanen sig kun med den første pakke; nogle gange under samtalen oversættes der også opkald, tastetryk (DTMF) og forskellige interessante funktioner som FollowMe, RingGroup, IVR og lignende.

Hvad er der inde i Invite-pakken

Lad os se på FreePBX og integrere det med Bitrix24 og mere.

De fleste enkle dialplaner arbejder med de første to felter, og al logik drejer sig om DID og CallerID. DID – hvor vi ringer hen, CallerID – hvem der ringer.

Men da vi er en virksomhed og ikke bare en telefon, så er der sandsynligvis grupper til opkald (simultane/sequential opkald til flere apparater) på faste numre (Ring Group), IVR (Hej, du har ringet til... Tryk 1 for...), Svarere (Phrases), Tidsbetingelser (Time Conditions), Viderebefordring til andre numre eller mobil (FollowMe, Forward). Det betyder, at det er meget svært klart at bestemme, hvem der faktisk vil modtage opkaldet og hvem samtalen vil være med, når opkaldet modtages. Her er et eksempel på starten af et typisk opkald i vores kunders PBX.

Lad os se på FreePBX og integrere det med Bitrix24 og mere.

Efter et vellykket indgående opkald til PBX'en begynder dets rejse gennem dialplanen i forskellige "kontekster". En kontekst i forhold til Asterisk er et nummereret sæt af kommandoer, hvor hver kommandos indeholder et filter baseret på det indtastede nummer (det kaldes exten, til udgående opkald i den tidlige fase exten=DID). Kommandoer i dialplanstrengen kan være hvad som helst – interne funktioner (for eksempel at ringe til en intern bruger – Dial(), lægge på – Hangup()), betingede operatorer (IF, ELSE, ExecIF og lignende), overgange til andre regler i denne kontekst (Goto, GotoIF), overgange til andre kontekster gennem funktionsopkald (Gosub, Macro). Den særlige direktiv include navn_på_konteksten, tilføjer kommandoer fra en anden kontekst til slutningen af den nuværende kontekst. Kommandoer inkluderet via include udføres altid efter kommandoerne i den nuværende kontekst.

Al logik i FreePBX er bygget op om at inkludere forskellige kontekster i hinanden gennem include og kalde via Gosub, Macro og handlerbehandlere. L lad os se på konteksten for indgående opkald i FreePBX.

Lad os se på FreePBX og integrere det med Bitrix24 og mere.

Opkaldet passerer gennem alle kontekster ovenfra og ned i rækkefølge; i hver kontekst kan der være kald til andre kontekster som makroer (Macro), funktioner (Gosub) eller blot overgange (Goto), så derfor kan det reelle træ af, hvad der bliver kaldt, kun spores i loggene.

Den typiske konfiguration af en almindelig kontor-ATC vises nedenfor. Ved opkald undersøges DID i de indgående ruter, og de tidsmæssige betingelser kontrolleres; hvis alt er i orden, aktiveres stemmemenuen. Herfra kan man via knap 1 eller timeout komme videre til en gruppe af operatører. Efter opkaldets afslutning bliver makroen hangupcall kaldt, hvorefter der ikke kan udføres yderligere handlinger i dialplanen, bortset fra særlige behandlere (hangup handler).

Lad os se på FreePBX og integrere det med Bitrix24 og mere.

Hvor i denne opkaldsalog skal vi angive information om starten af opkaldet til CRM, hvor skal optagelse starte, hvor skal optagelse slutte, og hvordan sender vi den sammen med opkaldsinformationen til CRM?

Integration med eksterne systemer

Hvad er integrationen mellem ATC og CRM? Det er indstillinger og programmer, der konverterer data og begivenheder mellem disse to platforme og sender dem til hinanden. Den mest udbredte metode til interaktion mellem uafhængige systemer er API, og den mest populære måde at tilgå API på er HTTP REST. Men ikke for asterisk.

Inden for Asterisk findes der:

  • AGI — synkron opkald af eksterne programmer/komponenter, anvendes hovedsageligt i dialplanen, der findes biblioteker som phpagi, PAGI

  • AMI — tekstbaseret TCP socket, som fungerer via begivenhedssubskription og indtastning af tekstkommandoer, minder indeni om SMTP, kan overvåge begivenheder og styre opkald, findes der et bibliotek PAMI — den mest populære til at etablere forbindelse med Asterisk

Eksempel på AMI-udskrift

Event: Newchannel
Privilege: call,all
Channel: PJSIP/VMS_pjsip-0000078b
ChannelState: 4
ChannelStateDesc: Ring
CallerIDNum: 111222
CallerIDName: 111222
ConnectedLineNum:
ConnectedLineName:
Language: en
AccountCode:
Context: from-pstn
Exten: s
Priority: 1
Uniqueid: 1599589046.5244
Linkedid: 1599589046.5244

  • ARI — en blanding af de to, alt via REST, WebSocket, i JSON-format — men moderne biblioteker og indpakninger er ikke så gode, der blev hurtigt fundet (phparia, phpari) som var blevet udviklet for tre år siden.

Eksempel på ARI-udskrift ved opkaldsinitiering

{ "variable":"CallMeCallerIDName", "value":"111222", "type":"ChannelVarset", "timestamp":"2020-09-09T09:38:36.269+0000", "channel":{"id":"1599644315.5334", "name":"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":"ru" }, "asteriskid":"48:5b:aa:aa:aa:aa", "application":"hello-world" }

Bekvemmelighed eller ulempe, muligheden eller umuligheden for at arbejde med et bestemt API bestemmes af de opgaver, der skal løses. Opgaverne for integration med CRM er som følger:

  • Spor starten af opkaldet, hvor det blev videresendt, udtræk CallerID, DID, start- og sluttider, samt muligvis data fra kataloget (for at finde forbindelsen mellem telefonen og brugeren i CRM)

  • Starte og afslutte optagelsen af opkaldet, gemme det i det ønskede format, informere om, hvor filen ligger, når optagelsen er færdig

  • Initere et opkald ved en ekstern begivenhed (fra programmet), ringe til et internt nummer, et eksternt og forbinde dem

  • Valgfri: integrere med CRM, opkaldsgrupper og FollowME for automatisk viderestilling af opkald ved fravær (ifølge oplysninger fra CRM)

Alle disse opgaver kan løses gennem AMI eller ARI, men ARI giver meget mindre information, mange begivenheder spores ikke, mange variabler, som alligevel findes i AMI, spores ikke (for eksempel opkald af makroer, tildeling af variabler inden for makroer, herunder optagelse af opkald). Derfor vælger vi for nu AMI (men ikke endeligt). Desuden (hvad ville vi dog gøre uden dette, vi er trods alt dovne mennesker) — i det oprindelige arbejde (artikel i Habr) bruger PAMI. *Derefter skal vi prøve at omskrive til ARI, men det er ikke sikkert, at det lykkes.

Finder på integrationen på ny

For at vores FreePBX kan rapportere til AMI på en enkel måde om starten af opkaldet, sluttidspunktet, numrene, navne på de gemte filer, og beregne varigheden af opkaldet, er det nemmest at anvende det samme trick som de oprindelige forfattere — introducere vores egne variabler og parse output for deres tilstedeværelse. PAMI tilbyder at gøre dette let via en filterfunktion.

Her er et eksempel på tildelingen af en variabel for tidspunktet for begyndelsen af opkaldet (s er et specielt nummer i dialplanen, der udføres FØR begyndelsen af søgning efter DID)

[ext-did-custom]

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

Eksempel på AMI-begivenhed for denne linje

Event: Newchannel

Privilege: call,all

Channel: PJSIP/VMS_pjsip-0000078b

ChannelState: 4

ChannelStateDesc: Ring

CallerIDNum: 111222

CallerIDName: 111222

ConnectedLineNum:

ConnectedLineName:

Language: en

AccountCode:

Context: from-pstn

Exten: s

Priority: 1

Uniqueid: 1599589046.5244

Linkedid: 1599589046.5244

Application: Set AppData:

CallStart=1599571046

Da FreePBX overskriver filer som extention.conf og extention_additional.conf, vil vi bruge filen extention_custom.conf

Den fulde kode for extention_custom.conf

[globals]	
;; Tjek stier og rettigheder på mapper - brugeren asterisk skal have skrivrettigheder
;; Her vil samtaler blive gemt
WAV=\/var\/www\/html\/callme\/records\/wav 
MP3=\/var\/www\/html\/callme\/records\/mp3

;; Optagelser vil blive afspillet og downloadet fra disse stier
URLRECORDS=https:\/\/www.host.ru\/callmeplus\/records\/mp3

;; Adresse til callback ved udgående opkald
URLPHP=https:\/\/www.host.ru\/callmeplus

;; Ja, vi optager samtaler
RECORDING=1

;; Dette er makroen til at optage samtaler i vores mappe. 
;; Man kan også bruge systemoptagelse, men lad os bruge denne - 
;; den virker
[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()


;; Dette er den primære kontekst for at starte samtalen
[ext-did-custom]

;; Dette er lidt af et trick, men det virker - tilføjer '8' til nummeret
exten =>  s,1,Set(CALLERID(num)=8${CALLERID(num)})

;; Her er forskellige variabler til scriptet
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)})

;; Det vigtigste! Håndterer slutningen af samtalen. 
;; Almindelige måder at håndtere slutningen gennem (exten=>h,1, noget her) i FreePBX virker ikke - Macro(hangupcall,) ødelægger det. 
;; Derfor tilføjer vi Hangup_Handler til slutningen af opkaldet
exten => s,n,Set(CHANNEL(hangup_handler_push)=sub-call-from-cid-ended,s,1(${CALLERID(num)},${EXTEN}))

;; Håndterer afslutningen af indgående opkald
[sub-call-from-cid-ended]

;; Informerer om værdierne ved slutningen af opkaldet
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)})

;; Opkaldets status - Besvaret, ikke besvaret...
exten => s,n,Set(CallMeDISPOSITION=${CDR(disposition)})
exten => s,n,Return


;; Håndtering af udgående opkald - alt er analogt
[outbound-allroutes-custom]

;; Optagelse
exten => _.,1,Gosub(recording,~~s~~,1(${CALLERID(number)},${EXTEN}))
;; Variabler
exten => _.,n,Set(__CallIntNum=${CALLERID(num)})
exten => _.,n,Set(CallExtNum=${EXTEN})
exten => _.,n,Set(CallStart=${STRFTIME(epoch,,%s)})
exten => _.,n,Set(CallmeCALLID=${SIPCALLID})

;; Tilføjer Hangup_Handler til slutningen af opkaldet
exten => _.,n,Set(CHANNEL(hangup_handler_push)=sub-call-internal-ended,s,1(${CALLERID(num)},${EXTEN}))

;; Håndtering af afslutningen af udgående opkald
[sub-call-internal-ended]

;; variabler
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)})

;; Kalder scriptet, der vil informere om opkaldet til CRM - dette er et udgående, 
;; så ved afslutning
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

Funktionen og forskellen fra den oprindelige dialplan fra forfatterne af den oprindelige artikel —

  • Dialplan i .conf-format, som FreePBX ønsker (ja, den kan også .ael, men ikke alle versioner og ikke altid er det praktisk)

  • I stedet for at behandle afslutningen gennem exten=>h er der indført behandling gennem hangup_handler, fordi FreePBX dialplan kun fungerer med den

  • Opkaldsskriptet er rettet, der er tilføjet anførselstegn og et eksternt nummer ExtNum

  • Behandlingerne er flyttet til _custom kontekster og tillader ikke at røre eller redigere FreePBX-konfigurationer — indgående gennem [ext-did-custom], udgående gennem [outbound-allroutes-custom]

  • Ingen binding til numre — filen er universel og kræver kun indstilling af stien og henvisningen til serveren

For at starte arbejdet skal man også tillade scripts i AMI med login og adgangskode — for dette er der også en _custom fil i FreePBX

Fil manager_custom.conf

;;  dette er login
[callmeplus]
;; dette er adgangskoden
secret = trampampamturlala
deny = 0.0.0.0/0.0.0.0

;; jeg arbejder med den lokale maskine - men hvis nødvendigt, kan man også angive andre
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

Disse to filer skal placeres i /etc/asterisk, derefter skal konfigurationerne genlæsning (eller Asterisk genstartes)

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

Nu går vi videre til PHP

Initialisering af scripts og oprettelse af tjenesten

Da arbejdet med Bitrix 24, en service til AMI, ikke er helt enkelt og gennemsigtigt, skal vi stoppe ved den. Asterisk åbner ganske enkelt en port ved aktivering af AMI, og når en klient tilslutter sig, anmoder den om godkendelse, hvorefter klienten abonnerer på de nødvendige begivenheder. Begivenhederne kommer som almindelig tekst, som PAMI konverterer til strukturerede objekter og giver mulighed for at filtrere kun ved de interessante begivenheder, felter, numre osv.

Når opkaldet modtages, opstår begivenheden NewExten, der starter med den overordnede kontekst [from-pstn], hvorefter alle begivenheder følger i rækkefølge i konteksterne. Når der modtages oplysninger fra de angivne i dialplanen _custom variabler CallMeCallerIDName og CallStart kaldes

  1. Funktionen til forespørgslen UserID, der svarer til det interne nummer, hvor opkaldet kom ind. Men hvad hvis det er en opkaldsgruppe? Det er et politisk spørgsmål; skal vi lave et opkald til alle samtidig (når alle ringer samtidig) eller lave dem én ad gangen, når opkaldet foretages? De fleste kunder har strategien First Available, så der er ikke problemer med det, kun én ringer. Men spørgsmålet skal løses.

  2. Funktionen til registrering af opkald i Bitrix24, som returnerer CallID, der senere er nødvendig for at rapportere om opkaldets parametre og linket til optagelsen. Kræver enten et internt nummer eller UserID.

Lad os se på FreePBX og integrere det med Bitrix24 og mere.

Efter afslutningen af opkaldet kaldes funktionen til at uploade optagelsen, som samtidig rapporterer status for opkaldets afslutning (Optaget, Ingen svar, Succes), og uploader linket til mp3-filen med optagelsen (hvis der er en).

Da modulet CallMeIn.php skal køre kontinuerligt, blev der oprettet en SystemD startfil til det. callme.service, som skal placeres i /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

# her skal du se, hvilke rettigheder der er på mapperne
#User=www-data  #Ubuntu - debian
#User=nginx #Centos

[Install]
WantedBy=multi-user.target

initialisering og start af scriptet sker via systemctl eller service.

# systemctl enable callme
# systemctl start callme

Tjenesten vil selv blive genstartet efter behov (ved nedbrud). Overvågningstjenesten for indkommende opkald kræver ikke installation af en webserver, kun php (som helt sikkert er på FeePBX-serveren). Men uden adgang til opkaldsoptagelserne via en webserver (især med https) vil der ikke være mulighed for at lytte til samtaleoptagelser.

Lad os nu tale om udgående opkald. Scriptet CallMeOut.php har to funktioner:

  • Initiere opkaldet, når der kommer en anmodning til php-scriptet (også via knappen 'Ring op' i Bitrix). Uden webserver fungerer det ikke; anmodningen kommer via HTTP POST, og anmodningen indeholder en token.

  • Rapportering om opkaldet, dets parametre og optagelser i Bitrix. Dette sker ved initiativ fra Asterisk i dialplanen [sub-call-internal-ended] ved afslutningen af opkaldet.

Lad os se på FreePBX og integrere det med Bitrix24 og mere.

Webserveren er kun nødvendig for to ting — upload af optagelsesfiler til Bitrix (via HTTPS) og kald af scriptet CallMeOut.php. Du kan bruge den indbyggede server i FreePBX, hvis filer er placeret i /var/www/html, eða installere en anden server eller angive en anden sti.

Webserver

Lad os overlade konfigureringen af webserveren til selvlæring (klik her, klik her, klik her). Hvis du ikke har et domæne, kan du prøve FreeDomain( https://www.freenom.com/ru/index.html), som gratis vil give dig et navn til din offentlige IP (husk at portforwarde 80, 443 gennem routeren, hvis den eksterne adresse kun er på den). Hvis du lige har oprettet DNS-domænet, skal du vente (fra 15 minutter til 48 timer), indtil alle servere er opdateret. Efter erfaring med lokale udbydere kan det tage fra 1 time til en dag.

Automatisering af installation

På GitHub er udviklingen af en installationsprogram startet, så det bliver endnu nemmere at installere. Men det ser godt ud på papiret - vi installerer alt dette manuelt indtil videre, og efter at have rodet med det hele, er det klart, hvem der går sammen, hvem der går hvor, og hvordan man debugger det. Der er stadig ikke nogen installationsprogram (

Docker

Hvis du gerne vil prøve løsningen hurtigt, er der en mulighed med Docker - hurtigt oprette en container, åbne dens porte, tilføje konfigurationsfiler og teste (dette er en løsning med LetsEncrypt-containeren, hvis certifikatet allerede er der, skal du blot omdirigere reverse proxy til webserveren FreePBX (her har vi givet en anden port - 88), LetsEncrypt i Docker inspireret af denne artikel

Du skal køre filen i den downloadede projektmappe (efter git clone), men først kigge ind i Asterisk-konfigurationerne (mappen asterisk) og angive stierne til optagelserne og URL'en til dit websted

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 # til konfiguration
      - 5060:5060\/udp
      - 5160:5160\/udp
      - 127.0.0.1:5038:5038 # til 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:

Denne fil docker-compose.yaml køres ved hjælp af

docker-compose up -d

Hvis nginx ikke startede, er der noget galt med konfigurationen i mappen nginx\/ssl_docker.conf

Andre integrationer

Og hvorfor ikke også inkludere flere CRM i scripts, tænkte vi. Vi har undersøgt flere API'er fra andre CRM'er, især den gratis, der er indbygget i nogle PBX'er - ShugarCRM og Vtiger, og ja! det kan lade sig gøre, princippet er det samme. Men det er en anden historie, som vi senere vil uploade til GitHub separat.

Links

Disclaimer: eventuelle ligheder med virkeligheden er opdigtede, og det var ikke mig,

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster