Kisah satu projek atau bagaimana saya menghabiskan 7 tahun mencipta PBX berdasarkan Asterisk dan Php

Pasti ramai di antara anda, seperti saya, mempunyai idea untuk melakukan sesuatu yang unik. Dalam artikel ini saya akan menerangkan masalah teknikal dan penyelesaian yang perlu saya hadapi semasa membangunkan PBX. Mungkin ini akan membantu seseorang memutuskan idea mereka sendiri, dan seseorang untuk mengikuti jalan yang dilalui dengan baik, kerana saya juga mendapat manfaat daripada pengalaman perintis.

Kisah satu projek atau bagaimana saya menghabiskan 7 tahun mencipta PBX berdasarkan Asterisk dan Php

Idea dan keperluan utama

Dan semuanya bermula hanya dengan cinta untuk Asterisk (rangka kerja untuk membina aplikasi komunikasi), automasi telefon dan pemasangan FreePBX (antara muka web untuk Asterisk). Jika keperluan syarikat adalah tanpa spesifik dan berada dalam kemampuan FreePBX - semuanya bagus. Keseluruhan pemasangan berlaku dalam masa XNUMX jam, syarikat menerima PBX yang dikonfigurasikan, antara muka mesra pengguna dan latihan pendek serta sokongan jika dikehendaki.

Tetapi tugas yang paling menarik adalah tidak standard dan kemudian ia tidak begitu hebat. Asterisk boleh melakukan banyak perkara, tetapi untuk memastikan antara muka web berfungsi, anda perlu menghabiskan lebih banyak masa. Jadi butiran kecil mungkin mengambil masa yang lebih lama daripada memasang PBX yang lain. Dan maksudnya bukanlah bahawa ia mengambil masa yang lama untuk menulis antara muka web, tetapi intinya adalah dalam ciri seni bina FreePBX. Pendekatan dan kaedah seni bina FreePBX telah dibentangkan pada masa php4, dan pada masa itu sudah ada php5.6 di mana segala-galanya boleh dibuat lebih mudah dan lebih mudah.

Penyedut minuman terakhir ialah pelan dail grafik dalam bentuk rajah. Apabila saya cuba membina sesuatu seperti ini untuk FreePBX, saya menyedari bahawa saya perlu menulis semula dengan ketara dan lebih mudah untuk membina sesuatu yang baharu.

Keperluan utama adalah:

  • persediaan mudah, boleh diakses secara intuitif walaupun kepada pentadbir baru. Oleh itu, syarikat tidak memerlukan penyelenggaraan PBX di pihak kami,
  • pengubahsuaian mudah supaya tugasan diselesaikan dalam masa yang mencukupi,
  • kemudahan integrasi dengan PBX. U FreePBX tiada API untuk menukar tetapan, i.e. Anda tidak boleh, sebagai contoh, membuat kumpulan atau menu suara daripada aplikasi pihak ketiga, hanya API itu sendiri Asterisk,
  • sumber terbuka - untuk pengaturcara ini sangat penting untuk pengubahsuaian untuk klien.

Idea pembangunan yang lebih pantas adalah untuk mempunyai semua fungsi terdiri daripada modul dalam bentuk objek. Semua objek mesti mempunyai kelas induk yang sama, yang bermaksud nama semua fungsi utama sudah diketahui dan oleh itu sudah ada pelaksanaan lalai. Objek akan membolehkan anda mengurangkan secara mendadak bilangan argumen dalam bentuk tatasusunan bersekutu dengan kunci rentetan, yang anda boleh ketahui dalam FreePBX Ia boleh dilakukan dengan memeriksa keseluruhan fungsi dan fungsi bersarang. Dalam kes objek, autolengkap cetek akan menunjukkan semua sifat, dan secara umum akan memudahkan kehidupan berkali-kali. Selain itu, pewarisan dan definisi semula sudah menyelesaikan banyak masalah dengan pengubahsuaian.

Perkara seterusnya yang memperlahankan masa kerja semula dan patut dielakkan ialah pertindihan. Jika terdapat modul yang bertanggungjawab untuk mendail pekerja, maka semua modul lain yang perlu menghantar panggilan kepada pekerja harus menggunakannya, dan tidak membuat salinan mereka sendiri. Jadi, jika anda perlu menukar sesuatu, maka anda perlu menukar hanya di satu tempat dan carian untuk "cara ia berfungsi" harus dijalankan di satu tempat, dan tidak dicari sepanjang keseluruhan projek.

Versi pertama dan ralat pertama

Prototaip pertama telah siap dalam masa setahun. Keseluruhan PBX, seperti yang dirancang, adalah modular, dan modul bukan sahaja boleh menambah fungsi baharu untuk memproses panggilan, tetapi juga menukar antara muka web itu sendiri.

Kisah satu projek atau bagaimana saya menghabiskan 7 tahun mencipta PBX berdasarkan Asterisk dan Php
Ya, idea untuk membina pelan dail dalam bentuk skema sedemikian bukanlah milik saya, tetapi ia sangat mudah dan saya melakukan perkara yang sama untuk Asterisk.

Kisah satu projek atau bagaimana saya menghabiskan 7 tahun mencipta PBX berdasarkan Asterisk dan Php

Dengan menulis modul, pengaturcara sudah boleh:

  • cipta fungsi anda sendiri untuk pemprosesan panggilan, yang boleh diletakkan pada rajah, serta dalam menu elemen di sebelah kiri,
  • buat halaman anda sendiri untuk antara muka web dan tambah templat anda pada halaman sedia ada (jika pembangun halaman telah menyediakan untuk ini),
  • tambah tetapan anda pada tab tetapan utama atau buat tab tetapan anda sendiri,
  • pengaturcara boleh mewarisi daripada modul sedia ada, menukar sebahagian fungsi dan mendaftarkannya di bawah nama baharu atau menggantikan modul asal.

Sebagai contoh, ini ialah cara anda boleh mencipta menu suara anda sendiri:

......
class CPBX_MYIVR extends CPBX_IVR
{
 function __construct()
 {
 parent::__construct();
 $this->_module = "myivr";
 }
}
.....
$myIvrModule = new CPBX_MYIVR();
CPBXEngine::getInstance()->registerModule($myIvrModule,__DIR__); //Π—Π°Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ
CPBXEngine::getInstance()->registerModuleExtension($myIvrModule,'ivr',__DIR__); //ΠŸΠΎΠ΄ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ

Pelaksanaan kompleks pertama membawa kebanggaan pertama dan kekecewaan pertama. Saya gembira kerana ia berfungsi, bahawa saya sudah dapat menghasilkan semula ciri-ciri utama FreePBX. Saya gembira kerana orang menyukai idea skim itu. Masih terdapat banyak pilihan untuk memudahkan pembangunan, tetapi pada masa itu beberapa tugas telah pun dipermudahkan.

API untuk menukar konfigurasi PBX adalah mengecewakan - hasilnya tidak sama sekali seperti yang kami mahukan. Saya mengambil prinsip yang sama seperti dalam FreePBX, dengan mengklik butang Guna, keseluruhan konfigurasi dicipta semula dan modul dimulakan semula.

Ia kelihatan seperti ini:

Kisah satu projek atau bagaimana saya menghabiskan 7 tahun mencipta PBX berdasarkan Asterisk dan Php
*Pelan dail ialah peraturan (algoritma) yang mana panggilan diproses.

Tetapi dengan pilihan ini, adalah mustahil untuk menulis API biasa untuk menukar tetapan PBX. Pertama, operasi memohon perubahan kepada Asterisk terlalu lama dan intensif sumber.
Kedua, anda tidak boleh memanggil dua fungsi pada masa yang sama, kerana kedua-duanya akan membuat konfigurasi.
Ketiga, ia menggunakan semua tetapan, termasuk yang dibuat oleh pentadbir.

Dalam versi ini, seperti dalam Askozia, adalah mungkin untuk menjana konfigurasi hanya modul yang diubah dan mulakan semula hanya modul yang diperlukan, tetapi ini semua adalah separuh langkah. Ia adalah perlu untuk mengubah pendekatan.

Versi kedua. Hidung tercabut ekor tersepit

Idea untuk menyelesaikan masalah itu bukanlah untuk mencipta semula konfigurasi dan pelan dail untuk Asterisk, tetapi simpan maklumat ke pangkalan data dan baca dari pangkalan data secara langsung semasa memproses panggilan. Asterisk Saya sudah tahu cara membaca konfigurasi daripada pangkalan data, cuma tukar nilai dalam pangkalan data dan panggilan seterusnya akan diproses dengan mengambil kira perubahan, dan fungsi itu sesuai untuk membaca parameter pelan dail REALTIME_HASH.

Pada akhirnya, tidak perlu untuk memulakan semula Asterisk apabila menukar tetapan dan semua tetapan mula digunakan serta-merta Asterisk.

Kisah satu projek atau bagaimana saya menghabiskan 7 tahun mencipta PBX berdasarkan Asterisk dan Php

Satu-satunya perubahan pada pelan dail ialah penambahan nombor sambungan dan Petua. Tetapi ini adalah perubahan kecil

exten=>101,1,GoSub(β€˜sub-callusers’,s,1(1)); - Ρ‚ΠΎΡ‡Π΅Ρ‡Π½ΠΎΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅, добавляСтся/измСняСтся Ρ‡Π΅Ρ€Π΅Π· ami

; sub-callusers – ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Π°Ρ функция гСнСрится ΠΏΡ€ΠΈ установкС модуля.
[sub-callusers]
exten =>s,1,Noop()
exten =>s,n,Set(LOCAL(TOUSERID)=${ARG1})
exten =>s,n,ClearHash(TOUSERPARAM)
exten =>s,n,Set(HASH(TOUSERPARAM)=${REALTIME_HASH(rl_users,id,${LOCAL(TOUSERID)})})
exten =>s,n,GotoIf($["${HASH(TOUSERPARAM,id)}"=""]?return)
...

Anda boleh menambah atau menukar baris dengan mudah dalam pelan dail menggunakan Ami (antara muka kawalan Asterisk) dan tiada but semula keseluruhan pelan dail diperlukan.

Ini menyelesaikan masalah dengan API konfigurasi. Anda juga boleh terus masuk ke pangkalan data dan menambah kumpulan baharu atau menukar, contohnya, masa dail dalam medan "masa dail" untuk kumpulan dan panggilan seterusnya akan berlangsung pada masa yang ditentukan (Ini bukan cadangan untuk tindakan, kerana beberapa operasi API memerlukan Ami panggilan).

Pelaksanaan sukar pertama sekali lagi membawa kebanggaan dan kekecewaan pertama. Saya gembira kerana ia berkesan. Pangkalan data menjadi pautan kritikal, pergantungan pada cakera meningkat, terdapat lebih banyak risiko, tetapi semuanya berfungsi dengan stabil dan tanpa masalah. Dan yang paling penting, kini semua yang boleh dilakukan melalui antara muka web boleh dilakukan melalui API, dan kaedah yang sama digunakan. Selain itu, antara muka web telah menyingkirkan butang "gunakan tetapan pada PBX", yang sering dilupakan oleh pentadbir.

Kekecewaannya ialah perkembangan itu menjadi lebih rumit. Sejak versi pertama, bahasa PHP telah menghasilkan pelan dail dalam bahasa tersebut Asterisk dan ia kelihatan sama sekali tidak boleh dibaca, ditambah dengan bahasa itu sendiri Asterisk untuk menulis pelan dail ia sangat primitif.

Seperti apa rupanya:

$usersInitSection = $dialplan->createExtSection('usersinit-sub','s');
$usersInitSection
 ->add('',new Dialplanext_gotoif('$["${G_USERINIT}"="1"]','exit'))
 ->add('',new Dialplanext_set('G_USERINIT','1'))
 ->add('',new Dialplanext_gosub('1','s','sub-AddOnAnswerSub','usersconnected-sub'))
 ->add('',new Dialplanext_gosub('1','s','sub-AddOnPredoDialSub','usersinitondial-sub'))
 ->add('',new Dialplanext_set('LOCAL(TECH)','${CUT(CHANNEL(name),/,1)}'))
 ->add('',new Dialplanext_gotoif('$["${LOCAL(TECH)}"="SIP"]','sipdev'))
 ->add('',new Dialplanext_gotoif('$["${LOCAL(TECH)}"="PJSIP"]','pjsipdev'))

Dalam versi kedua, pelan dail menjadi universal, ia termasuk semua pilihan pemprosesan yang mungkin bergantung pada parameter dan saiznya meningkat dengan ketara. Semua ini sangat melambatkan masa pembangunan, dan pemikiran bahawa sekali lagi perlu untuk mengganggu pelan dail membuat saya sedih.

Versi ketiga

Adalah mustahil untuk menjana idea untuk menyelesaikan masalah Asterisk pelan dail dari php dan gunakan FastAGI dan tulis semua peraturan pemprosesan dalam PHP itu sendiri. FastAGI membolehkan Asterisk, untuk memproses panggilan, sambungkan ke soket. Terima arahan dari sana dan hantar hasil. Oleh itu, logik pelan dail sudah berada di luar sempadan Asterisk dan boleh ditulis dalam mana-mana bahasa, dalam kes saya dalam PHP.

Terdapat banyak percubaan dan kesilapan. Masalah utama ialah saya sudah mempunyai banyak kelas/fail. Ia mengambil masa kira-kira 1,5 saat untuk mencipta objek, memulakannya dan mendaftar antara satu sama lain, dan kelewatan setiap panggilan ini bukanlah sesuatu yang boleh diabaikan.

Inisialisasi sepatutnya berlaku sekali sahaja dan oleh itu pencarian untuk penyelesaian bermula dengan menulis perkhidmatan dalam php menggunakan Pthreads. Selepas seminggu percubaan, pilihan ini telah ditangguhkan kerana kerumitan cara sambungan ini berfungsi. Selepas sebulan ujian, saya juga terpaksa meninggalkan pengaturcaraan tak segerak dalam PHP; Saya memerlukan sesuatu yang mudah, biasa kepada mana-mana pemula PHP, dan banyak sambungan untuk PHP adalah segerak.

Penyelesaiannya ialah perkhidmatan berbilang benang kami sendiri dalam C, yang telah disusun bersama PHPLIB. Ia memuatkan semua fail php ATS, menunggu untuk semua modul dimulakan, menambah panggilan balik antara satu sama lain, dan apabila semuanya sudah sedia, cachenya. Apabila ditanya oleh FastAGI strim dicipta, salinan daripada cache semua kelas dan data dihasilkan semula di dalamnya, dan permintaan dihantar ke fungsi php.

Dengan penyelesaian ini, masa dari menghantar panggilan ke perkhidmatan kami kepada arahan pertama Asterisk menurun daripada 1,5s kepada 0,05s dan kali ini bergantung sedikit pada saiz projek.

Kisah satu projek atau bagaimana saya menghabiskan 7 tahun mencipta PBX berdasarkan Asterisk dan Php

Akibatnya, masa untuk pembangunan pelan dail telah dikurangkan dengan ketara, dan saya boleh menghargai ini kerana saya terpaksa menulis semula keseluruhan pelan dail semua modul dalam PHP. Pertama, kaedah sepatutnya sudah ditulis dalam php untuk mendapatkan objek dari pangkalan data; mereka diperlukan untuk paparan dalam antara muka web, dan kedua, dan ini adalah perkara utama, akhirnya mungkin untuk berfungsi dengan mudah dengan rentetan dengan nombor dan tatasusunan dengan pangkalan data serta banyak sambungan PHP.

Untuk memproses pelan dail dalam kelas modul anda perlu melaksanakan fungsi tersebut dialplanDynamicCall dan hujah pbxCallRequest akan mengandungi objek untuk berinteraksi Asterisk.

Kisah satu projek atau bagaimana saya menghabiskan 7 tahun mencipta PBX berdasarkan Asterisk dan Php

Di samping itu, adalah mungkin untuk menyahpepijat pelan dail (php mempunyai xdebug dan ia berfungsi untuk perkhidmatan kami), anda boleh bergerak langkah demi langkah dengan melihat nilai pembolehubah.

Data panggilan

Sebarang analisis dan laporan memerlukan data yang dikumpul dengan betul, dan blok PBX ini juga telah melalui banyak percubaan dan ralat dari versi pertama hingga ketiga. Selalunya, data panggilan adalah tanda. Satu panggilan = satu rakaman: siapa yang menelefon, siapa yang menjawab, berapa lama mereka bercakap. Dalam pilihan yang lebih menarik, terdapat tanda tambahan yang menunjukkan pekerja PBX mana yang dipanggil semasa panggilan. Tetapi semua ini hanya meliputi sebahagian daripada keperluan.

Keperluan awal adalah:

  • menyelamatkan bukan sahaja siapa yang dipanggil PBX, tetapi juga siapa yang menjawab, kerana terdapat pemintasan dan ini perlu diambil kira semasa menganalisis panggilan,
  • masa sebelum berhubung dengan pekerja. Dalam FreePBX dan beberapa PBX lain, panggilan itu dianggap dijawab sebaik sahaja PBX mengangkat telefon. Tetapi untuk menu suara anda sudah perlu mengangkat telefon, jadi semua panggilan dijawab dan masa menunggu untuk jawapan menjadi 0-1 saat. Oleh itu, diputuskan untuk menjimatkan bukan sahaja masa sebelum respons, tetapi masa sebelum menyambung dengan modul utama (modul itu sendiri menetapkan bendera ini. Pada masa ini ia adalah "Pekerja", "Barisan Luar"),
  • untuk pelan dail yang lebih kompleks, apabila panggilan bergerak antara kumpulan yang berbeza, adalah perlu untuk dapat memeriksa setiap elemen secara berasingan.

Pilihan terbaik ternyata apabila modul PBX menghantar maklumat tentang diri mereka semasa panggilan dan akhirnya menyimpan maklumat dalam bentuk pokok.

Ia kelihatan seperti ini:

Pertama, maklumat umum tentang panggilan (seperti orang lain - tiada yang istimewa).

Kisah satu projek atau bagaimana saya menghabiskan 7 tahun mencipta PBX berdasarkan Asterisk dan Php

  1. Menerima panggilan di talian luar "Untuk ujian"pada 05:55:52 dari nombor 89295671458 ke nombor 89999999999, akhirnya dijawab oleh pekerja"Setiausaha2Β» dengan nombor 104. Pelanggan menunggu 60 saat dan bercakap selama 36 saat.
  2. pekerja"Setiausaha2"membuat panggilan ke 112 dan pekerja menjawab"Pengurus1Β» selepas 8 saat. Mereka bercakap selama 14 saat.
  3. Pelanggan dipindahkan kepada Pekerja "pengurus1" di mana mereka terus bercakap selama 13 saat lagi

Tetapi ini adalah puncak gunung ais; untuk setiap rekod anda boleh mendapatkan sejarah panggilan terperinci melalui PBX.

Kisah satu projek atau bagaimana saya menghabiskan 7 tahun mencipta PBX berdasarkan Asterisk dan Php

Semua maklumat dibentangkan sebagai sarang panggilan:

  1. Menerima panggilan di talian luar "Untuk ujianΒ» pada 05:55:52 daripada nombor 89295671458 ke nombor 89999999999.
  2. Pada 05:55:53 talian luar menghantar panggilan ke litar Masuk "ujianΒ»
  3. Apabila memproses panggilan mengikut skema, modul "panggilan pengurus", di mana panggilan adalah 16 saat. Ini adalah modul yang dibangunkan untuk pelanggan.
  4. Modul "panggilan pengurus" menghantar panggilan kepada pekerja yang bertanggungjawab untuk nombor (pelanggan) "Pengurus1” dan menunggu 5 saat untuk jawapan. Pengurus tidak menjawab.
  5. Modul "panggilan pengurus"menghantar panggilan kepada kumpulan"pengurus CORP" Ini adalah pengurus lain dari arah yang sama (duduk di dalam bilik yang sama) dan menunggu 11 saat untuk jawapan.
  6. Kumpulan "pengurus CORP"panggil pekerja"Pengurus1, Pengurus2, Pengurus3"secara serentak selama 11 saat. Tiada jawapan.
  7. Panggilan pengurus ditamatkan. Dan litar menghantar panggilan ke modul "Memilih laluan dari 1c" Juga modul yang ditulis untuk pelanggan. Di sini panggilan diproses selama 0 saat.
  8. Litar menghantar panggilan ke menu suara "Asas dengan pendailan tambahan" Pelanggan menunggu di sana selama 31 saat, tiada pendailan tambahan.
  9. Skim ini menghantar panggilan kepada Kumpulan "Setiausaha", di mana pelanggan menunggu 12 saat.
  10. Dalam satu kumpulan, 2 pekerja dipanggil pada masa yang sama "Setiausaha1"Dan"Setiausaha2" dan selepas 12 saat pekerja menjawab "Setiausaha2" Jawapan kepada panggilan diduakan menjadi panggilan ibu bapa. Ternyata dalam kumpulan dia menjawab β€œSetiausaha2", apabila memanggil litar menjawab "Setiausaha2" dan menjawab panggilan di talian luar dengan "Setiausaha2'.

Ia adalah penjimatan maklumat tentang setiap operasi dan sarangnya yang membolehkan anda membuat laporan dengan mudah. Laporan pada menu suara akan membantu anda mengetahui sejauh mana ia membantu atau menghalang. Bina laporan mengenai panggilan yang terlepas oleh pekerja, dengan mengambil kira bahawa panggilan itu dipintas dan oleh itu tidak dianggap terlepas, dan mengambil kira bahawa ia adalah panggilan kumpulan, dan orang lain menjawab lebih awal, yang bermaksud panggilan itu juga tidak terlepas.

Penyimpanan maklumat sedemikian akan membolehkan anda mengambil setiap kumpulan secara berasingan dan menentukan keberkesanannya, dan membina graf kumpulan yang dijawab dan terlepas mengikut jam. Anda juga boleh menyemak sejauh mana tepat sambungan kepada pengurus yang bertanggungjawab dengan menganalisis pemindahan selepas menyambung kepada pengurus.

Anda juga boleh menjalankan kajian yang agak tidak tipikal, contohnya, kekerapan nombor yang tiada dalam pangkalan data mendail sambungan yang betul atau berapa peratusan panggilan keluar dimajukan ke telefon bimbit.

Hasilnya?

Pakar tidak diperlukan untuk mengekalkan PBX; pentadbir yang paling biasa boleh melakukannya - diuji dalam amalan.

Untuk pengubahsuaian, pakar dengan kelayakan yang serius tidak diperlukan; pengetahuan tentang PHP adalah mencukupi, kerana Modul telah pun ditulis untuk protokol SIP, dan untuk baris gilir, dan untuk memanggil pekerja, dan lain-lain. Terdapat kelas pembalut untuk Asterisk. Untuk membangunkan modul, seorang pengaturcara boleh (dan dengan cara yang baik harus) memanggil modul siap sedia. Dan pengetahuan Asterisk adalah tidak perlu sama sekali jika pelanggan meminta untuk menambah halaman dengan beberapa laporan baharu. Tetapi amalan menunjukkan bahawa walaupun pengaturcara pihak ketiga boleh mengatasinya, mereka berasa tidak selamat tanpa dokumentasi dan liputan biasa ulasan, jadi masih ada ruang untuk penambahbaikan.

Modul boleh:

  • cipta keupayaan pemprosesan panggilan baharu,
  • tambah blok baharu pada antara muka web,
  • mewarisi daripada mana-mana modul sedia ada, mentakrifkan semula fungsi dan menggantikannya, atau hanya menjadi salinan yang diubah suai sedikit,
  • tambahkan tetapan anda pada templat tetapan modul lain dan banyak lagi.

Tetapan PBX melalui API. Seperti yang diterangkan di atas, semua tetapan disimpan dalam pangkalan data dan dibaca pada masa panggilan, jadi anda boleh menukar semua tetapan PBX melalui API. Apabila memanggil API, konfigurasi tidak dicipta semula dan modul tidak dimulakan semula, oleh itu, tidak kira berapa banyak tetapan dan pekerja yang anda ada. Permintaan API dilaksanakan dengan cepat dan tidak menyekat satu sama lain.

PBX menyimpan semua operasi utama dengan panggilan dengan tempoh (menunggu/perbualan), bersarang dan dalam istilah PBX (pekerja, kumpulan, talian luar, bukan saluran, nombor). Ini membolehkan anda membina pelbagai laporan untuk pelanggan tertentu dan kebanyakan kerja adalah untuk mencipta antara muka yang mesra pengguna.

Masa akan menentukan apa yang akan berlaku seterusnya. Masih banyak nuansa yang perlu dibuat semula, masih terdapat banyak rancangan, tetapi setahun telah berlalu sejak penciptaan versi ke-3 dan kita sudah boleh mengatakan bahawa idea itu berfungsi. Kelemahan utama versi 3 ialah sumber perkakasan, tetapi ini biasanya yang anda perlu bayar untuk kemudahan pembangunan.

Sumber: www.habr.com

Tambah komen