電話垳Freeswitch



入金


Freeswitchが私の小さな匱点であるこずがたたたた起こりたした。 はい、珟圚、アスタリスクは䞖界でより広く普及しおおり、私もそれをよく知っおいたすが、... Freeswitchは䜕かで私を魅了したす。 機胜のセット、おそらく非垞に安定した動䜜、リ゜ヌス消費の䜎さ、そしおより論理的なデバむスかもしれたせん。 たたは、私はIT業界のヒップスタヌであり、他の人ずは違っおいたらよかったず思いたす。 知る方法。 私たちは人間の魂の闇を掘り䞋げる心理孊者ではないので、私たちはそれを圓たり前のこずず思っお、より実甚的なこずをしおいたす。 カスタマヌサヌビスを改善したす。 議題に圌の認識を通じお改善されたクラむアントの個人化です。

雑孊


電話垳は完党に実甚的です。 IPテレフォニヌシステム䞊の倚かれ少なかれすべおのアドオンに存圚したす。 着信コヌルが電話番号でクラむアントを識別するこずを蚱可したす。 もちろん、私たちは営業郚門ではありたせん。CRMで党員を曞くわけではありたせんが、問題を抱えおテクニカルサポヌトに電話をかける顧客埓業員であっおも、すぐに認められたす。 アプリケヌションレベルでは、電話垳は通垞プラグむンずしお接続され、特定のむンフォメヌションストアほずんどの堎合はデヌタベヌスをデヌタ゜ヌスずしお䜿甚できたす。 私は同様の運呜ずFreeswitchを逃れたせんでした。 異なる時間に、電話垳に2぀のオプションを䜿甚したした。


䞡方のオプションの実装に぀いお説明したす。 それぞれに長所ず短所がありたす。

デヌタベヌスの電話垳は、デバむス内でよりシンプルで暙準的です。 Freeswitchの公匏Webサむトには、むンストヌルず構成に適したドックがありたす。 しかし、テレフォニヌサヌバヌにはWebむンタヌフェむスがないため私は電話亀換のWebむンタヌフェむスの䞻な盞手ですが、これは次回はたったく異なる話です、無制限の人の限られたサヌクルが電話垳を蚭定できたす。デヌタ 、 リク゚ストなど 私の堎合のように、 コン゜ヌルもです。 なぜMySQLではないのですか 必芁なかったからです。 電話垳にロシアのすべおが含たれおいるわけではありたせんが、連絡先は玄500件です。 このため、SQLiteは芋えないこずが刀明したした。 2番目の問題は、情報を远加するプロセスでした。 耇数のテヌブルに远加し、関係を考慮しお、重耇を忘れないでください。 電話垳の情報を远加および曎新する芁求の実行順序に関するドキュメントがただどこかにありたす。 利点は明らかです-デヌタベヌス゚ンゞンは、远加の゜フトりェアのむンストヌルず統合を必芁ずせず、それ自䜓はモヌニングず同じくらい簡単です。 電話垳党䜓が1぀のファむルにたずめられおおり、簡単にバックアップしお保存できたす。 内郚のテヌブルは非垞にシンプルで、構造を理解するのに特別な思考プロセスは必芁ありたせん。 スティックをより倧きく持ち䞊げお、巊偎の隣人を打぀だけで十分です。 圌にそう考えさせおください。

電話垳の2番目のバヌゞョンは実装するのが簡単ではありたせんでした。 珟圚、CMDB iTopをマスタヌしようず積極的に取り組んでいるので、電話垳を暪断するずいうアむデアが浮䞊したした。 幞いなこずに、CMDBには暙準の連絡先ストレヌゞモゞュヌルが存圚し、䞀貫しおいたす。 暙準的な方法を䜿甚しおこれを行うこずはできたせんでした。 ルアは救助に来お、圌女のすべおがきれいできれいになった。 このアプロヌチの利点には、連絡先を远加および線集するための䟿利なむンタヌフェむスの存圚、CMDBにデヌタを保存し、電話亀換機に転送し、コヌルのルヌティング時に䜿甚する機胜が含たれたすただ䜿甚されおいたせんが蚈画されおいたす。 欠点-もちろん、ネットワヌク䞊の䌝送遅延、倖郚サヌビスぞの䟝存、この経枈党䜓のプログラミングず詊運転の必芁性。 しかし、結果には䟡倀がありたす。 ずころで、このようなオプションを適甚するよう説埗するのではなく、その䟋だけで、倖郚サヌビスずのやり取りを敎理する方法を瀺したいず思いたす。

ケヌキ


叀いITの䌝統によるず、単玔なものから耇雑なものに移行したす。 ゜ファに暪たわっお先延ばしから始めたしょう。 どれだけシンプルかをご芧ください。 しかし、仕事はオオカミではありたせん、あなたはそれを蹎るこずはありたせん、したがっお、私たちは䜓を垂盎䜍眮に移動し、電話亀換コン゜ヌルに近づけたす...
Freeswitchの電話垳モゞュヌルは、叀いサむトでは mod_cidlookup Descriptionず呌ばれ、新しいサむトでは Descriptionず呌ばれたす 。 最初に、モゞュヌルが䞀緒にあるかどうかを刀断する必芁がありたす。 誰が知っおいる、突然、い぀の間にか挏れた。

modulesフォルダヌでモゞュヌルの存圚を探したす。

ls -la /usr/local/freeswitch/mod/ | grep mod_cidlookup 

ファむルがなかった堎合、悪いニュヌスがありたす。 モゞュヌルを組み立おるか、再むンストヌルする必芁がありたす。 私は自分でFreeswitchをビルドしたいので、ビルドの゜ヌスツリヌは垞に手元にありたす。 Freeswitch甚のモゞュヌルを構築する方法の説明はこの蚘事の範囲を超えおいるため、そのたたにしおおき、モゞュヌルが必芁なフォルダヌに既にあるず仮定したす。 次に、構成しおデヌタを準備する必芁がありたす。 メむンモゞュヌルの構成蚭定はファむルにありたす

/usr/local/freeswitch/conf/autoload_configs/cidlookup.conf.xml
最小䜜業構成は次のようになりたす。

䜜業蚭定
 <configuration name="cidlookup.conf" description="cidlookup Configuration"> <settings> <!--   . --> <param name="cache" value="true"/> <!--      - . --> <param name="cache-expire" value="86400"/> <!--  .    3 (, !)    .   ,    ,  .    ,     . --> <param name="odbc-dsn" value="sqlite:///usr/local/freeswitch/db/phonebook.db"/> <!--    .      .      . --> <param name="sql" value=" SELECT (name || (CASE WHEN comment != '' THEN ' (' || comment || ')' ELSE '' END)) AS name FROM numbers n JOIN phonebook p ON n.pid = p.id WHERE n.number='${caller_id_number}' LIMIT 1 "/> </settings> </configuration> 


SELECTの条件匏に泚意しおください。 デヌタベヌスおよびコメントフィヌルドからクラむアントの䌚瀟を抜出できたす。 フィヌルドが空の堎合、期埅どおりに姓ず名のみが返されたす。 垞に1行のみが返されるため、重耇は無芖され、最も早い電話垳゚ントリが返されたす。 したがっお、デヌタを远加する前に、それらがデヌタベヌスにないこずを確認しおください。 電話垳バむンディングは、1人のナヌザヌに察しお耇数の電話番号をサポヌトするために䜿甚されたす。

電話垳甚のデヌタベヌスを䜜成しおいたす。

 sudo -u freeswitch sqlite3 /usr/local/freeswitch/db/phonebook.db 

 --     . -- . CREATE TABLE phonebook ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, name VARCHAR (128) NOT NULL, comment VARCHAR (256) ); CREATE INDEX name ON phonebook (name); --  . CREATE TABLE numbers ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, pid INTEGER REFERENCES phonebook (id) ON DELETE CASCADE NOT NULL, NUMBER VARCHAR (32) NOT NULL ); CREATE INDEX NUMBER ON numbers (NUMBER); --     . INSERT INTO `phonebook` (`name`, `comment`) VALUES (' ', '  , '); INSERT INTO `numbers` (`pid`, `number`) VALUES (LAST_INSERT_ROWID(), '79152323245'); INSERT INTO `phonebook` (`name`) VALUES (' '); INSERT INTO `numbers` (`pid`, `number`) VALUES (LAST_INSERT_ROWID(), '74953462323'); 

SQLiteコン゜ヌルを終了したす。

 .exit 

次に、モゞュヌルをダりンロヌドしお、新しく䜜成した電話垳に蚭定する必芁がありたす。 Freeswitchコン゜ヌルに入りたす。

 fs_cli 

ロヌド枈みの電話垳モゞュヌルを探しおいたす。

 freeswitch@internal> show modules mod_cidlookup 0 total. 

ええ、モゞュヌルはありたせん。 ダりンロヌドしおみおください。

 freeswitch@internal> load mod_cidlookup +OK Reloading XML +OK 2016-10-29 14:36:33.890548 [DEBUG] mod_cidlookup.c:122 Connecting to dsn: sqlite:///usr/local/freeswitch/db/phonebook.db 2016-10-29 14:36:33.890548 [INFO] mod_enum.c:880 ENUM Reloaded 2016-10-29 14:36:33.890548 [INFO] switch_time.c:1415 Timezone reloaded 1781 definitions 2016-10-29 14:36:33.890548 [CONSOLE] switch_loadable_module.c:1538 Successfully Loaded [mod_cidlookup] 2016-10-29 14:36:33.890548 [NOTICE] switch_loadable_module.c:292 Adding Application 'cidlookup' 2016-10-29 14:36:33.890548 [NOTICE] switch_loadable_module.c:338 Adding API Function 'cidlookup' . 

モゞュヌルがロヌドされたした。 デヌタベヌスぞの接続に問題がある堎合は、ログに衚瀺されたす。 ロヌドされたモゞュヌルの䞭から再び探しおいたす。

 freeswitch@internal> show modules mod_cidlookup type,name,ikey,filename api,cidlookup,mod_cidlookup,/usr/local/freeswitch/mod/mod_cidlookup.so application,cidlookup,mod_cidlookup,/usr/local/freeswitch/mod/mod_cidlookup.so 2 total. 

次に、モゞュヌルの正垞性をテストする必芁がありたす。 これは、cidlookup API関数を䜿甚しおコン゜ヌルから実行するこずもできたす。 その構文を芋たす。

 freeswitch@internal> show api cidlookup name,description,syntax,ikey cidlookup,cidlookup API,cidlookup status|number [skipurl] [skipcitystate] [verbose],mod_cidlookup 1 total. 

電話垳に远加したデヌタを思い出しお、APIの動䜜をテストしたす。

 freeswitch@internal> cidlookup 79152323245   (  , ) freeswitch@internal> cidlookup 74953462323   

ご芧のずおり、この関数は電話垳から正しい連絡先デヌタを返したす。 さらに、コメントがある堎合は、括匧で囲たれお返されたす。 次に、この機胜をダむダルプランに远加しお、人々に光ず喜びをもたらす必芁がありたす。 ダむダルプランはすべおの人で異なるように配眮されおいるため、電話垳に関する郚分のみを瀺し、おおよその䜍眮を瀺したす。 /usr/local/freeswitch/conf/dialplan/public.xmlファむルにありたす。

 <!--     . --> <!--       . --> <extension name="cid_number_cleanup" continue="true"> <condition field="caller_id_number" expression="^(\d+)$"> <action application="set" data="effective_caller_id_number=$1" inline="true"/> </condition> </extension> <!--       . --> <extension name="cid_name_cleanup" continue="true"> <condition field="caller_id_name" expression="^(\d+)$"> <action application="set" data="effective_caller_id_name=$1" inline="true"/> </condition> </extension> <!--       ,       ,   ,    .           . --> <extension name="cid_lookup" continue="true"> <condition field="${module_exists(mod_cidlookup)}" expression="true"/> <condition field="caller_id_name" expression="^(\d+)$|^$"/> <condition field="caller_id_number" expression="^(\d+)$"> <action application="cidlookup" data="$1"/> </condition> </extension> 

ファむルを保存し、コマンドでダむダルプランを再起動したす

 fs_cli -x reloadxml 

゚ラヌがなければ、モゞュヌルの動䜜を確認できたす。 十分にプレむしたら、自動ロヌドするモゞュヌルを远加したす。 これは、ファむル/usr/local/freeswitch/conf/autoload_configs/modules.conf.xmlで行われたす。 そこに行を探しおいたす

 <load module="mod_cidlookup"/> 

コメントを倖したす。 欠萜しおいる堎合は、ファむルの最埌に远加したす。

これで、電話垳が蚭定されたした。 しかし、䜕かを絶えず改善したくない堎合、管理者は管理者ではありたせん。 そしお、この道に沿った旅は、私たちの物語の次の郚分に぀ながりたす。

ロックしたしょう


FreeswitchずiTopの盞互䜜甚は、 公匏Webサむトで説明されおいるRESTむンタヌフェむスを介しお、完党に暙準的な方法で配眮されたす。 難しさは䜕ですか 圌ずは盎接連携しないため、プラグむンswanの力を借りる必芁がありたす。 圓初mod_curlを䜿甚する予定でしたが、 どういうわけか間違っおいたした 。 Luaで小さなスクリプトを蚘述し、 mod_luaを介しお呌び出すこずにしたした 。 たず最初に、電話垳自䜓を準備する必芁がありたす。぀たり、䜕らかの方法で連絡先をiTopにアップロヌドしたす。 遞択-同期の゜ヌス、CSVのダりンロヌド、たたは電話垳ぞの手動入力。 ここにはサンドボックスがあり、倚くの連絡先は必芁ないので、1぀の組織を䜜成し、それに耇数の連絡先を远加したしょう。 CMDBを倉曎するには、適切な暩限を持っおいるか、管理者である必芁がありたす。













。



同様に、さらにいく぀かの連絡先を远加したす。 これで、どこに目を向ければよいかがわかり、電話亀換の蚭定に進むこずができたす。 先ほど蚀ったように、iTop RESTむンタヌフェヌスを䜿甚しおリク゚ストしたす。 圌のリストず思慮深いテむスティングの結果、次のリク゚ストが出されたした。

 { "operation": "core/get", "class": "Person", "key": "SELECT Person AS P WHERE P.phone = '79101001122' OR P.add_phone = '79101001122' OR P.add_phone_2 = '79101001122' OR P.mobile_phone = '79101001122' OR P.add_mobile_phone = '79101001122'", "output_fields": "friendlyname,org_id_friendlyname,function" } 

Curlを䜿甚しお実行しおみたしょう。

 curl -XPOST 'https://<itop_address>/webservices/rest.php?version=1.0' -d 'auth_user=admin&auth_pwd=password&json_data=%7B%22operation%22%3A%22core%2Fget%22%2C%22class%22%3A%22Person%22%2C%22key%22%3A%22SELECT%20Person%20AS%20P%20WHERE%20P.phone%20%3D%20%2779101001122%27%20OR%20P.add_phone%20%3D%20%2779101001122%27%20OR%20P.add_phone_2%20%3D%20%2779101001122%27%20OR%20P.mobile_phone%20%3D%20%2779101001122%27%20OR%20P.add_mobile_phone%20%3D%20%2779101001122%27%22%2C%22output_fields%22%3A%22friendlyname%2Corg_id_friendlyname%2Cfunction%22%7D' 

ご芧のずおり、リク゚ストには認蚌が必芁です。 iTopのナヌザヌが存圚し、芁求を実行するために必芁な暩限を持っおいる必芁がありたす。

応答ずしお、ナヌザヌを芋぀けたす

 { "objects": { "Person::486": { "code": 0, "message": "", "class": "Person", "key": "486", "fields": { "friendlyname": "\u0412\u0430\u0441\u0438\u043b\u0438\u0439 \u041f\u0443\u043f\u043a\u0435\u0432\u0438\u0447", "org_id_friendlyname": "\u0420\u043e\u0433\u0430 \u0438 \u043a\u043e\u043f\u044b\u0442\u0430", "function": "\u0421\u0443\u043f\u0435\u0440\u0445\u043e\u043c\u044f\u043a" } } }, "code": 0, "message": "Found: 1" } 

より読みやすいバヌゞョンで

 { "objects": { "Person::486": { "code": 0, "message": "", "class": "Person", "key": "486", "fields": { "friendlyname": " ", "org_id_friendlyname": "  ", "function": "" } } }, "code": 0, "message": "Found: 1" } 

そのため、デヌタが送受信され、ナヌザヌが怜玢されたす。 お気に入りのIDEを芋぀けお、むンスピレヌションを䞎える䜕かを曞く時が来たした。 Freeswitchスクリプト甚に別のフォルダヌを䜜成したす。

 mkdir /usr/local/freeswitch/scripts 

このフォルダヌに、共有ラむブラリヌを栌玍するサブフォルダヌlibを䜜成したす。

 mkdir /usr/local/freeswitch/scripts/lib 

゜ケットずSSLを操䜜するための暙準ラむブラリが必芁になりたす。
 sudo apt-get install lua-socket lua-sec 

JSONの゚ンコヌドずデコヌドにも圹立぀ラむブラリ。 私はhttp://regex.info/blog/lua/jsonラむブラリを遞択したした。 それをダりンロヌドしお、適切なフォルダヌに配眮したす。
 wget http://regex.info/code/JSON.lua -O lib/json.lua 

そしお今、私たちのコヌドがこの䞖界に入るためのすべおの準備が敎いたした。 scriptsフォルダヌにcidlookup.luaファむルを䜜成し、ハヌドキヌボヌドで次のコヌドを远加したす。

/usr/local/freeswitch/scripts/cidlookup.lua
 --    iTop. local itop_addr = 'https://<itop_address:port>'; local itop_user = 'admin'; local itop_pass = 'password'; --  . local json = (loadfile '/usr/local/freeswitch/scripts/lib/json.lua')(); --    . --[[      .               Freeswitch.            .  . ,  ,      .       Lua,    .  -. ]]-- -- local phone = arg[1]; local phone = argv[1]; --  . local command = { operation = 'core/get', class = 'Person', key = 'SELECT Person AS P WHERE P.phone = "' .. phone .. '" OR P.add_phone = "' .. phone .. '" OR P.add_phone_2 = "' .. phone .. '" OR P.mobile_phone = "' .. phone .. '" OR P.add_mobile_phone = "' .. phone .. '"', output_fields = 'friendlyname,org_id_friendlyname,function' }; --   iTop. local http = require 'socket.http'; local https = require 'ssl.https'; local ltn12 = require 'ltn12'; local request = 'auth_user=' .. itop_user .. '&auth_pwd=' .. itop_pass .. '&json_data=' .. json:encode(command); local respbody = {}; --  ,     ,    iTop  -   . --      - ,  . http.TIMEOUT = 3; local body, code, headers, status = https.request { protocol = 'tlsv1', method = 'POST', url = 'https://' .. itop_addr .. '/webservices/rest.php?version=1.0', source = ltn12.source.string(request), headers = { ["Accept"] = "*/*", ["Accept-Encoding"] = "gzip, deflate", ["Accept-Language"] = "en-us", ["Content-Type"] = "application/x-www-form-urlencoded", ["content-length"] = string.len(request) }, sink = ltn12.sink.table(respbody) }; --    ,    . caller_id = phone; --  JSON. local response = json:decode(tostring(table.concat(respbody))); -- ,   - . if(not((response == nil) or (response["objects"] == nil))) then local index = next(response["objects"]); local contact = response.objects[index]["fields"]; --   . caller_id = contact.friendlyname .. "(".. contact.org_id_friendlyname .. (not(contact["function"] == "") and ", " .. contact["function"] or "") .. ")"; end --[[             Freeswitch.             .  . ]]-- stream:write(caller_id); -- io.write(caller_id .. "\n"); 


戊いで私たちの創造をテストする時が来たした。 コマンドラむンから操䜜甚のスクリプトを線集し、操䜜性を確認したす。

 lua cidlookup.lua 79101001122  (  , ) 

玠晎らしい、すべおが正垞に機胜したす。 スクリプトを線集し、コマンドラむンからの䜜業を無効にしたす。 次に、スクリプトをFreeswitchに接続したす。 最初に、適切なモゞュヌルがあるこずを確認する必芁がありたす。 Freeswitchコン゜ヌルに入りたす。

 fs_cli 

Luaモゞュヌルの負荷を確認したす。

 freeswitch@internal> show modules mod_lua type,name,ikey,filename api,lua,mod_lua,/usr/local/freeswitch/mod/mod_lua.so api,luarun,mod_lua,/usr/local/freeswitch/mod/mod_lua.so application,lua,mod_lua,/usr/local/freeswitch/mod/mod_lua.so dialplan,LUA,mod_lua,/usr/local/freeswitch/mod/mod_lua.so 4 total. 

これらの行が衚瀺されおいる堎合、すべおが正垞であり、モゞュヌルがロヌドされおいたす。 そこにない堎合、モゞュヌルは組み立おられたすが、起動されたせん。 実行しようずしおいたす。

 freeswitch@internal> load mod_lua 

Freeswitchが実行するモゞュヌルを芋぀けるこずができない堎合、それを組み立おお再むンストヌルする必芁がありたす。 この問題が正垞に解決され、モゞュヌルがロヌドされたず想定しおいたす。 スクリプトを実行しようずしたす。

 freeswitch@internal> lua cidlookup.lua 79101001122  (  , ) 

ご芧のずおり、スクリプトは正垞に動䜜し、受信する必芁があるすべおのものが動䜜したす。 それをダむダルプランに远加するこずは残っおいたす。 蚘事の最初の郚分のように、どこに眮くかは教えたせんが、その仕事に責任を負うダむダルプランの䞀郚を提䟛したす。

 <!--     . --> <!--       . --> <extension name="cid_number_cleanup" continue="true"> <condition field="caller_id_number" expression="^(\d+)$"> <action application="set" data="effective_caller_id_number=$1" inline="true"/> </condition> </extension> <!--       . --> <extension name="cid_name_cleanup" continue="true"> <condition field="caller_id_name" expression="^(\d+)$"> <action application="set" data="effective_caller_id_name=$1" inline="true"/> </condition> </extension> <!--       ,       ,       .           . --> <extension name="cid_lookup" continue="true"> <condition field="${module_exists(mod_lua)}" expression="true"/> <condition field="caller_id_name" expression="^(\d+)$|^$"/> <condition field="caller_id_number" expression="^(\d+)$"> <action application="set" data="effective_caller_id_name=${lua(cidlookup.lua ${caller_id_name})}"/> </condition> </extension> 

次のコマンドでダむダルプランをリロヌドしたす

 fs_cli -x reloadxml 

そしお結果を楜しんでください。

面付け


はい、改善および改善できるこずがわかっおいたす。 mod_curlに関連付けおコヌドを簡玠化するこずができ、スクリプトを終了しお最適化するこずができたすが、それに぀いおは議論したせん。 完璧に制限はありたせん。 しかし、どんな道も最初のステップから始たりたす。この蚘事が圌の勀勉な仕事に圹立぀なら、それは無駄に曞かれおいないこずを意味したす。 =それでは、こんにちは。

PS誰かが圹に立぀ずいいな。 あなたのコメントを歓迎したす。

Source: https://habr.com/ru/post/J330360/


All Articles