FreeSWITCH 簡單圖形化界面40 - 使用mod_curl模塊進行http請求

FreeSWITCH 簡單圖形化界面40 - 使用mod_curl模塊進行http請求

  • 0、界面預覽
  • 00、簡介
  • 1、編譯安裝
    • 1.1 編輯模塊配置文件
  • 2、使用
    • 2.1 撥號規則
      • GET 請求
      • POST 請求
      • JSON 數據
    • 2.2 Lua 腳本
      • GET 請求
      • POST 請求
      • JSON 數據
  • 3 、示例
    • 3.1 示例 1:提交 CDR 到第三方接口
    • 3.2 示例 2:提交外呼狀態到第三方接口


0、界面預覽

http://myfs.f3322.net:8020/
用戶名:admin,密碼:admin

FreeSWITCH界面安裝參考:https://blog.csdn.net/jia198810/article/details/137820796

00、簡介

mod_curl是 FreeSWITCH 的一個強大模塊,它允許用戶通過 HTTP 請求與外部服務進行交互,從而實現數據的獲取和提交。無論是簡單的 GET 請求,還是復雜的 POST 請求和文件傳輸,mod_curl都能輕松應對。

1、編譯安裝

在使用mod_curl之前,需要確保該模塊已正確編譯并加載到 FreeSWITCH 中。以下是詳細的編譯和安裝步驟:

1.1 編輯模塊配置文件

  1. 打開 FreeSWITCH 源代碼目錄下的modules.conf文件,找到以下行并取消注釋:
   #applications/mod_curl

保存文件并退出。

  1. 重新編譯 FreeSWITCH

在終端中執行以下命令,重新編譯 FreeSWITCH:

   makemake install
  1. 加載模塊

編輯 FreeSWITCH 的模塊加載配置文件modules.conf.xml(路勁為/usr/local/freeswitch/conf/autoload_configs),添加以下內容:

   <load module="mod_curl"/>

保存文件后,重新加載 FreeSWITCH 以使模塊生效。

  1. 驗證模塊加載

啟動 FreeSWITCH 并進入 CLI,執行以下命令以驗證mod_curl是否已正確加載:

   module_exists mod_curl

如果返回true,則表示模塊加載成功。

2、使用

2.1 撥號規則

mod_curl提供了兩種主要的應用方式:curlcurl_sendfile(不常用)。
在撥號規則中,可以通過以下方式調用curl應用:

<action application="curl" data="http://example.com/api?param=value"/>

curl應用的請求,會生成兩個通道變量 curl_response_data 和curl_response_code,可以使用${}獲取。

GET 請求

通過 URL 參數發送 GET 請求:

  <action application="curl" data="http://example.com/api?param=value"/>

POST 請求

發送 POST 請求并攜帶數據:

  <action application="curl" data="http://example.com/api post param=value"/>

JSON 數據

發送 JSON 格式的數據:

  <action application="curl" data="http://example.com/api content-type application/json post {\"key\":\"value\"}"/>

2.2 Lua 腳本

mod_curl也可以在 Lua 腳本中使用,通過 FreeSWITCH 的 API 接口調用 HTTP 請求。

GET 請求

在 Lua 腳本中發起 GET 請求的示例如下:

local api = freeswitch.API()local url = "http://example.com/api?param=value"
local response = api:execute("curl", url)freeswitch.consoleLog("INFO", "Response: " .. response .. "\n")

POST 請求

發送 POST 請求的示例如下:

local api = freeswitch.API()local url = "http://example.com/api"
local data = "param=value"
local response = api:execute("curl", url .. " post " .. data)freeswitch.consoleLog("INFO", "Response: " .. response .. "\n")

JSON 數據

發送 JSON 格式數據的示例如下:

local api = freeswitch.API()local url = "http://example.com/api"
local json_data = "{ \"key\": \"value\" }"
local response = api:execute("curl", url .. " content-type application/json post " .. json_data)freeswitch.consoleLog("INFO", "Response: " .. response .. "\n")

3 、示例

3.1 示例 1:提交 CDR 到第三方接口

在呼叫結束后,將通話詳情記錄(CDR)提交到第三方接口。以下是 Lua 腳本的實現示例:

#!/usr/bin/env lua
-- upload_cdr.lua
-- 2024年6月29日
-- 提交話單信息到第三方接口
-- 撥號規則,提前設置掛機回調
-- session:execute("set", string.format("api_hangup_hook=lua upload_cdr.lua")-- 序列化并打印env對象的所有通話信息,調試專用
-- local call_info = env:serialize()
-- freeswitch.consoleLog("INFO", "所有通話信息:\n" .. call_info)
local mobile = env:getHeader("destination_number") or ""
local caller_ani = env:getHeader("Caller-ANI") or ""
local sip_account = env:getHeader("sip_from_user") or ""
local start_time = env:getHeader("start_stamp") or ""
-- local start_time = env:getHeader("answer_stamp") or ""
local end_time = env:getHeader("end_stamp") or ""
local use_time_length = env:getHeader("billsec") or "0"
local order_no = string.format("freeSWITCH%s%s", sip_account, mobile)
local mobile_hangup_api = env:getHeader("mobile_hangup_api") or ""
local api_timeout = env:getHeader("api_timeout") or "3"-- 打印詳細信息,確保變量不為空
if sip_account == mobile thenfreeswitch.consoleLog("INFO", "異常呼叫主叫=被叫,再次獲取SIP賬號為 : " .. caller_ani .. "\n")sip_account = caller_ani
end
freeswitch.consoleLog("INFO", "CallerANI    : " .. caller_ani .. "\n")
freeswitch.consoleLog("INFO", "SIP賬號      : " .. sip_account .. "\n")
freeswitch.consoleLog("INFO", "被叫號碼     : " .. mobile .. "\n")
freeswitch.consoleLog("INFO", "開始時間     : " .. start_time .. "\n")
freeswitch.consoleLog("INFO", "結束時間     : " .. end_time .. "\n")
freeswitch.consoleLog("INFO", "通話時長     : " .. use_time_length .. "\n")
freeswitch.consoleLog("INFO", "訂單號       : " .. order_no .. "\n")
freeswitch.consoleLog("INFO", "CDR推送接口  : " .. mobile_hangup_api .. "\n")
freeswitch.consoleLog("INFO", "接口超時時間  : " .. api_timeout .. "\n")-- 準備執行命令
local api = freeswitch.API();--[[
-- 使用python提交
local cmd = string.format("/usr/local/python310/bin/python /usr/local/freeswitch/scripts/upload_cdr.py '%s' '%s' '%s' '%s' '%s' '%s' '%s'",mobile, sip_account, start_time, end_time, use_time_length, order_no, mobile_hangup_api)
local response = api:execute("bg_system", cmd)
]]-- 使用curl提交
local cmd = string.format("%s connect-timeout %s timeout %s post mobile=%s&sip_account=%s&start_time='%s'&end_time='%s'&use_time_length=%s&order_no=%s",mobile_hangup_api, api_timeout, api_timeout, mobile, sip_account, start_time, end_time, use_time_length, order_no)
freeswitch.consoleLog("INFO", "推送命令: " .. cmd .. "\n")
local response = api:execute("curl", cmd)
if (response == "") thenfreeswitch.consoleLog("INFO", "推送結果: 無響應,可能連接接口失敗!")
elsefreeswitch.consoleLog("INFO", "推送結果: " .. response .. "\n")
end

3.2 示例 2:提交外呼狀態到第三方接口

在外呼結束后,將外呼狀態提交到第三方接口。以下是 Lua 腳本的實現示例:

#!/usr/bin/env lua
-- handle-callout-result.lua
-- 2025年2月26日
-- 處理外呼結果 
-- 外呼api設置掛機回調。originate {origination_caller_id_number=300,orgination_caller_id_name=outcall,api_hangup_hook='lua handle-callout-result.lua'}sofia/gateway/gw01/172xxxx2122 401 xml Local-Extensions -- local env
-- local freeswitchlocal call_info = env:serialize()
-- -- 序列化并打印env對象的所有通話信息,調試專用
-- freeswitch.consoleLog("INFO", "所有通話信息:\n" .. call_info)-- 開始時間
local start_time = env:getHeader("start_stamp") or ""-- 結束時間
local end_time = env:getHeader("end_stamp") or ""-- 通話時間
local duration = env:getHeader("billsec") or "0"-- SIP中繼名稱
local trunk_name = env:getHeader("trunk_name") or ""-- 被叫號碼
local destination_number = env:getHeader("destination_number") or ""-- 本地號碼
local local_number = env:getHeader("rdnis") or ""-- 備用被叫號碼
local sip_to_user = env:getHeader("sip_to_user") or ""-- 呼出主叫號碼
local outgoing_caller_id_number = env:getHeader("origination_caller_id_number") or ""-- answer api
local answer_api = env:getHeader("answer_api") or ""-- no_answer api
local no_answer_api = env:getHeader("no_answer_api") or ""-- api 超時時間
local api_timeout = 3-- 通話結果
local hangup_cause = env:getHeader("hangup_cause") or ""-- 是否檢查主叫號碼被占用
local check_number_in_use = env:getHeader("check_number_in_use") or "false"local response
local result
local temp_string-- 打印詳細信息,確保變量不為空
if destination_number == "" thenfreeswitch.consoleLog("INFO", string.format("# destination_number未空,使用sip_to_user的值%s\n",sip_to_user))destination_number = sip_to_user
end
freeswitch.consoleLog("INFO", "# ==============API接口外呼掛機處理============= \n")freeswitch.consoleLog("INFO", "# ------------------外呼呼叫信息---------------- \n")
freeswitch.consoleLog("INFO", "# 開始時間  : " .. start_time .. "\n")
freeswitch.consoleLog("INFO", "# 結束時間  : " .. end_time .. "\n")
freeswitch.consoleLog("INFO", "# 通話時長  : " .. duration .. "\n")
freeswitch.consoleLog("INFO", "# 外呼號碼  : " .. destination_number .. "\n")
freeswitch.consoleLog("INFO", "# 本地號碼  : " .. local_number .. "\n")
freeswitch.consoleLog("INFO", "# 呼出主叫  : " .. outgoing_caller_id_number .. "\n")
freeswitch.consoleLog("INFO", "# 掛機接口  : " .. no_answer_api .. "\n")
freeswitch.consoleLog("INFO", "# ---------------------------------------------\n\n")-- 執行fs api命令
local api = freeswitch.API();-- 應答提交api,在401 xml Local-Extensions中。
-- if (hangup_cause == "ANSWER" or hangup_cause == "NORMAL_CLEARING") then
--     -- 呼叫應答提交
--     freeswitch.consoleLog("INFO", "# 呼叫結果  : 呼叫已經應答,推送應答接口\n")
--     if (answer_api == "") then
--         freeswitch.consoleLog("INFO", "# 推送結果  : 應答接口為空,不提交!\n")
--         return
--     else
--         -- 提交無應答結果
--         temp_string = string.format(
--             "%s connect-timeout %s timeout %s post destination_number=%s",
--             no_answer_api, api_timeout, api_timeout, destination_number)
--         freeswitch.consoleLog("INFO", string.format("# 推送結果  : 請求地址:%s\n",temp_string))--         -- 執行推送
--         response = api:execute("curl",temp_string)
--         if (response == "") then
--             freeswitch.consoleLog("INFO", "# 推送結果  : 接口無響應,可能連接接口失敗!\n")
--         else
--             freeswitch.consoleLog("INFO", "# 推送結果  : " .. response .. "\n")
--         end
--     endfreeswitch.consoleLog("INFO", "# ----------------外呼掛機處理-----------------\n")if (hangup_cause  == "BUSY" or hangup_cause == "USER_BUSY" or hangup_cause == "NO_USER_RESPONSE" or hangup_cause == "NO_ROUTE_DESTINATION" or  hangup_cause == "CALL_REJECTED" or hangup_cause == "NO_ANSWER") thenfreeswitch.consoleLog("INFO", "# 掛機結果  : " .. hangup_cause .. "\n")-- 呼叫未應答提交freeswitch.consoleLog("INFO", "# 呼叫結果  : 呼叫未應答,推送未應答接口\n")if (no_answer_api == "") thenfreeswitch.consoleLog("INFO", "# 推送結果  : 未應答接口為空,不提交!\n")returnelse-- 提交無應答結果temp_string = string.format("%s content-type application/json connect-timeout %s timeout %s post {\"destination_number\":\"%s\"}",no_answer_api, api_timeout, api_timeout, destination_number)freeswitch.consoleLog("INFO", string.format("# 推送結果  : 請求地址:%s\n",temp_string))-- 執行推送response = api:execute("curl", temp_string)if (response == "") thenfreeswitch.consoleLog("INFO", "# 推送結果  : 接口無響應,可能連接接口失敗!\n")elsefreeswitch.consoleLog("INFO", "# 推送結果  : ".. response.. "\n")endend
elseif (hangup_cause  == "NORMAL_CLEARING") thenfreeswitch.consoleLog("INFO", "# 掛機結果   : " .. hangup_cause .. "\n")freeswitch.consoleLog("INFO", "# 掛機結果   : 通話正常掛斷\n")
elsefreeswitch.consoleLog("INFO", "# 掛機結果   : " .. hangup_cause .. "\n")
end
freeswitch.consoleLog("INFO", "# ----------------------------------------------\n")-- 如果要檢查主叫號碼是否被占用,則呼叫結束后,刪除正在使用的主叫號碼
if (check_number_in_use == "true") thenfreeswitch.consoleLog("INFO", string.format("# 通話已結束 : 開啟了檢查主叫號碼占用,將釋放主叫%s\n",outgoing_caller_id_number))-- 檢查號碼是否被占用temp_string = string.format("delete/%s/number_in_use_%s",trunk_name, outgoing_caller_id_number)freeswitch.consoleLog("INFO", string.format("# 通話已結束 : 釋放正在使用的主叫號碼:%s\n",temp_string))result = api:execute("hash",temp_string)freeswitch.consoleLog("INFO", string.format("# 通話已結束 : 釋放正在使用的主叫號碼:%s\n",result))
end
freeswitch.consoleLog("INFO", "# ===============================================\n\n")
return

祝君好運

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/72783.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/72783.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/72783.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux 開發工具

linux中&#xff0c;常見的軟件安裝方式---下載 yum/apt.rpm安裝包安裝源碼安裝 yum 查看軟件包 通過yumlist命令可以羅列出當前?共有哪些軟件包.由于包的數?可能?常之多,這?我們需要使? grep 命令只篩選出我們關注的包.例如: # Centos $ yum list | grep lrzsz lr…

Agent革命:Manus如何用工作流拆解掀起AI生產力革命

一、現象級產品的誕生背景 2025年3月6日&#xff0c;一款名為Manus的AI產品在技術圈引發地震式傳播。其官方測試數據顯示&#xff1a;在GAIA基準測試中&#xff0c;基礎任務準確率達86.5%&#xff08;接近人類水平&#xff09;&#xff0c;中高級任務完成率突破57%。這標志著A…

Linux13-TCP\HTTP

一、TCP粘包問題 1.TCP在接受數據時,多包數據粘在一起 2.原因: 2.1TCP發送數據時,會根據緩沖區數據的情況進行重新組包 2.2TCP接收方,沒有及時讀走緩沖區數據,導致緩沖區大量數據緩存。 3.如何解決 3.1發指定大小字節 將要發數據,封裝在結構體里 struct data { …

網絡安全等級保護2.0 vs GDPR vs NIST 2.0:全方位對比解析

在網絡安全日益重要的今天&#xff0c;各國紛紛出臺相關政策法規&#xff0c;以加強信息安全保護。本文將對比我國網絡安全等級保護2.0、歐盟的GDPR以及美國的NIST 2.0&#xff0c;分析它們各自的特點及差異。 網絡安全等級保護2.0 網絡安全等級保護2.0是我國信息安全領域的一…

oracle通過dmp導入數據

1、創建用戶&#xff0c;并賦予sysdba權限 登錄sysdba用戶 sqlplus / as sysdba 賦予sysdba權限 grant sysdba to your_user; 2、導入dmp文件 imp target_user/passwordip:port/SERVER_NAME fromusersource_user tousertarget_user fileyour.dmp logdmp_file.log statist…

MySQL 面試篇

MySQL相關面試題 定位慢查詢 **面試官&#xff1a;**MySQL中&#xff0c;如何定位慢查詢? 我們當時做壓測的時候有的接口非常的慢&#xff0c;接口的響應時間超過了2秒以上&#xff0c;因為我們當時的系統部署了運維的監控系統Skywalking &#xff0c;在展示的報表中可以看到…

MyBatis 操作數據庫

目錄 1、MyBatis 是什么2、配置 MyBatis 開發環境2.1、添加 MyBatis 框架支持2.1.1、老項目添加 MyBatis2.1.2、新項目添加 MyBatis 2.2、配置數據庫連接字符串2.3、配置 MyBatis 中的 XML 路徑 3、添加業務代碼3.1、添加實體類3.2、添加 mapper 接口3.3、添加 xml 文件3.4、添…

uniapp使用藍牙,usb,局域網,打印機打印

使用流程&#xff08;支持安卓和iOS&#xff09; 引入SDK 引入原生插件包地址如下 https://github.com/oldfive20250214/UniPrinterDemo 連接設備 安卓支持經典藍牙、ble藍牙、usb、局域網&#xff08;參考API&#xff09; iOS支持ble藍牙、局域網&#xff08;參考API&…

Jmeter進行http接口測試詳解

&#x1f345; 點擊文末小卡片&#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 本文主要針對http接口進行測試&#xff0c;使用 jmeter工具實現。 Jmeter工具設計之初是用于做性能測試的&#xff0c;它在實現對各種接口的調用方面已經做的比較…

力扣35.搜索插入位置-二分查找

class Solution:def searchInsert(self, nums: List[int], target: int) -> int:# 初始化左右指針left, right 0, len(nums) - 1# 當左指針小于等于右指針時&#xff0c;繼續循環while left < right:# 計算中間位置mid (left right) // 2# 如果中間元素等于目標值&…

為AI聊天工具添加一個知識系統 之133 詳細設計之74通用編程語言 之4 架構及其核心

本篇繼續討論 通用編程語言。 說明&#xff1a;本階段的所有討論都是圍繞這一主題展開的&#xff0c;但前面的討論分成了三個大部分&#xff08;后面列出了這一段的討論題目的歸屬關系&#xff09;-區別distinguish&#xff08;各別&#xff09;&#xff1a; 文化和習俗。知識…

PPT 技能:巧用 “節” 功能,讓演示文稿更有序

在制作PPT時&#xff0c;你是否遇到過這樣的情況&#xff1a;幻燈片越來越多&#xff0c;內容越來越雜&#xff0c;找某一頁內容時翻得眼花繚亂&#xff1f;尤其是在處理大型PPT文件時&#xff0c;如果沒有合理的結構&#xff0c;編輯和調整都會變得非常麻煩。這時候&#xff0…

劉火良 FreeRTOS內核實現與應用之1——列表學習

重要數據 節點的命名都以_ITEM后綴進行&#xff0c;鏈表取消了后綴&#xff0c;直接LIST 普通的節點數據類型 /* 節點結構體定義 */ struct xLIST_ITEM { TickType_t xItemValue; /* 輔助值&#xff0c;用于幫助節點做順序排列 */ struct xLIST_I…

Uniapp項目運行到微信小程序、H5、APP等多個平臺教程

摘要&#xff1a;Uniapp作為一款基于Vue.js的跨平臺開發框架&#xff0c;支持“一次開發&#xff0c;多端部署”。本文將手把手教你如何將Uniapp項目運行到微信小程序、H5、APP等多個平臺&#xff0c;并解析常見問題。 一、環境準備 在開始前&#xff0c;請確保已安裝以下工具…

100天精通Python(爬蟲篇)——第115天:爬蟲在線小工具_Curl轉python爬蟲代碼工具(快速構建初始爬蟲代碼)

文章目錄 一、curl是什么&#xff1f;二、爬蟲在線小工具&#xff08;牛逼puls&#xff09;三、實戰操作 一、curl是什么&#xff1f; 基本概念&#xff1a;curl 支持多種協議&#xff0c;如 HTTP、HTTPS、FTP、SFTP 等&#xff0c;可用于從服務器獲取數據或向服務器發送數據&a…

[內網安全] Windows 域認證 — Kerberos 協議認證

&#x1f31f;想系統化學習內網滲透&#xff1f;看看這個&#xff1a;[內網安全] 內網滲透 - 學習手冊-CSDN博客 0x01&#xff1a;Kerberos 協議簡介 Kerberos 是一種網絡認證協議&#xff0c;其設計目標是通過密鑰系統為客戶機 / 服務器應用程序提供強大的認證服務。該認證過…

PyTorch中的損失函數:F.nll_loss 與 nn.CrossEntropyLoss

文章目錄 背景介紹F.nll_loss什么是負對數似然損失&#xff1f;應用場景 nn.CrossEntropyLoss簡化工作流程內部機制 區別與聯系 背景介紹 無論是圖像分類、文本分類還是其他類型的分類任務&#xff0c;交叉熵損失&#xff08;Cross Entropy Loss&#xff09;都是最常用的一種損…

案例1_3:流水燈

文章目錄 文章介紹原理圖&#xff08;同案例1_2&#xff09;代碼效果圖 文章介紹 原理圖&#xff08;同案例1_2&#xff09; 代碼 #include <reg51.h> // 包含頭文件void delay(unsigned int time) {unsigned int i, j;for (i 0; i < time; i)for (j 0; j < 1…

基于物聯網技術的電動車防盜系統設計(論文+源碼)

1總體設計 本課題為基于物聯網技術的電動車防盜系統&#xff0c;在此將整個系統架構設計如圖2.1所示&#xff0c;其采用STM32F103單片機為控制器&#xff0c;通過NEO-6M實現GPS定位功能&#xff0c;通過紅外傳感器檢測電瓶是否離開位&#xff0c;通過Air202 NBIOT模塊將當前的數…

學習知識的心理和方法雜記-02

本文簡單記錄下我個人對大腦學習模式的認識。 人腦的基本能力是什么&#xff1f; 接收輸入的能力。語言和聲音 視覺圖像 觸覺 嗅覺 味覺等。 存儲能力。人腦存儲能力背后的物理化學結構我們人類目前還無法完全認知&#xff0c;但是存儲的目標物一定是人可以通過五官獲得的形…