|
|
@@ -20,12 +20,13 @@ var TimestampList = make(map[string]string) //临时记录通话成功时的
|
|
|
var StartTimeList = make(map[string]time.Time) //临时记录通话的初始时间,通话结束时删除
|
|
|
// var LinkedidList = make(map[string]string) // 临时记录 incoming 和 outgoing
|
|
|
// var DialStatusList = make(map[string]string) // 临时记录 DialStatus:ANSWER NOANSWER
|
|
|
-var CallTypeList = make(map[string]string) //通过Linkedid临时记录拨打类型呼入还是呼出,通话结束后删除
|
|
|
-var TimetimesList = make(map[string]int) //通过Linkedid临时记录呼入队列或部门的数量,通话结束后删除
|
|
|
-var AttendedTransferList = make(map[string]string) //临时记录协商转接的初始时间戳
|
|
|
-var ZohoExtenList = make([]string, 0) //记录zoho用户分机列表,只有zoho用户分机的呼入和呼出才会进行推送
|
|
|
-var n int //临时记录判断通话未接听的数量,若与呼入数量相同进行推送,若接听让n归0
|
|
|
-var ZOHO_URL string //设置推送地址
|
|
|
+var CallTypeList = make(map[string]string) //通过Linkedid临时记录拨打类型呼入还是呼出,通话结束后删除
|
|
|
+var TimetimesList = make(map[string]int) //通过Linkedid临时记录呼入队列或部门的数量,通话结束后删除
|
|
|
+var AttendedTransferList = make(map[string]string) //临时记录协商转接的初始时间戳
|
|
|
+var AttendedSecondTransferList = make(map[string]string) //临时记录协商转接后的初始时间戳
|
|
|
+var ZohoExtenList = make([]string, 0) //记录zoho用户分机列表,只有zoho用户分机的呼入和呼出才会进行推送
|
|
|
+var n int //临时记录判断通话未接听的数量,若与呼入数量相同进行推送,若接听让n归0
|
|
|
+var ZOHO_URL string //设置推送地址
|
|
|
// macro-trunkdial-failover为呼出判定;macro-stdexten为呼入开启语音留言的判定;macro-stdexten-withoutvm为呼入关闭语音留言的判定
|
|
|
func CallClicktodialerror(event map[string]string) {
|
|
|
//CallClicktodialerrorh函数用于过滤zoho crm拨打时出现的错误
|
|
|
@@ -33,7 +34,7 @@ func CallClicktodialerror(event map[string]string) {
|
|
|
Channel := strings.Split(event["Channel"], "/")
|
|
|
if (event["Context"] == "macro-stdexten" || event["Context"] == "macro-stdexten-withoutvm") && len(event["Exten"]) > 3 && Channel[0] == "Local" {
|
|
|
ExtenStatus := strings.Split(event["Exten"], "-")
|
|
|
- fmt.Println(len(event["Exten"]))
|
|
|
+
|
|
|
if ExtenStatus[1] == "NOANSWER" && slices.Contains(ZohoExtenList, event["ConnectedLineNum"]) { //坐席未接听,通过ExtenStatus判断挂断原因,slices.Contains(ZohoExtenList, event["ConnectedLineNum"])判断主叫是否时zoho用户分机(坐席)
|
|
|
getURL := fmt.Sprintf("%s/phonebridge/v3/clicktodialerror?code=noanswer&from=%s&to=%s", ZOHO_URL, event["ConnectedLineNum"], event["CallerIDNum"])
|
|
|
|
|
|
@@ -80,11 +81,9 @@ func CallNotify(event map[string]string) {
|
|
|
lfshook.NewLogger().Error(event)
|
|
|
|
|
|
Channel := strings.Split(event["Channel"], "/")
|
|
|
- fmt.Println("Channel[0] = ", Channel[0])
|
|
|
+
|
|
|
// Outgoing Call - Ringing
|
|
|
if event["Context"] == "macro-trunkdial-failover" && slices.Contains(ZohoExtenList, event["CallerIDNum"]) {
|
|
|
- lfshook.NewLogger().Info("Outgoing Call - Ringing")
|
|
|
-
|
|
|
StartTimeList[event["Linkedid"]] = time.Now().Add(-8 * time.Hour)
|
|
|
// https://www.zohoapis.com/phonebridge/v3/callnotify?type=dialed&state=ringing&id=10031&from=123456789&to=12300000001
|
|
|
getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=dialed&state=ringing&id=%s&from=%s&to=%s", ZOHO_URL, event["Linkedid"], event["CallerIDNum"], event["DestCallerIDNum"])
|
|
|
@@ -94,7 +93,7 @@ func CallNotify(event map[string]string) {
|
|
|
|
|
|
// Incoming Call - Ringing
|
|
|
} else if (event["Context"] == "macro-stdexten" && Channel[0] != "Local" && slices.Contains(ZohoExtenList, event["DestCallerIDNum"])) || (event["Context"] == "macro-stdexten-withoutvm" && Channel[0] != "Local" && slices.Contains(ZohoExtenList, event["DestCallerIDNum"])) { // 开启语音留言:macro-stdexten 关闭语音留言:macro-stdexten-withoutvm
|
|
|
- lfshook.NewLogger().Error("Incoming Call - Ringing")
|
|
|
+
|
|
|
StartTimeList[event["Linkedid"]] = time.Now().Add(-8 * time.Hour)
|
|
|
// https://www.zohoapis.com/phonebridge/v3/callnotify?type=received&state=ringing&id=10033&from=12300000001&to=123456789
|
|
|
// getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ringing&id=%s&from=%s&to=%s", ZOHO_URL, callId, event["Exten"], callDest) // 取得from to 可能不准
|
|
|
@@ -115,10 +114,9 @@ func CallNotify(event map[string]string) {
|
|
|
} else if event["Event"] == "DialEnd" { // 呼叫结束事件,未接听集合
|
|
|
Channel := strings.Split(event["Channel"], "/")
|
|
|
// 记录呼叫状态
|
|
|
- // DialStatusList[event["Linkedid"]] = event["DialStatus"]
|
|
|
// Outgoing Call - Unattended
|
|
|
if event["Context"] == "macro-trunkdial-failover" && event["DialStatus"] == "CANCEL" && slices.Contains(ZohoExtenList, event["CallerIDNum"]) { //坐席取消呼叫客户电话,event["DialStatus"]判断未接听挂断原因
|
|
|
- lfshook.NewLogger().Info("Outgoing Call - CANCEL")
|
|
|
+
|
|
|
// startTime := StartTimeList[event["Linkedid"]].Format("2006-01-02 15:04:09")
|
|
|
startTimeutc := StartTimeList[event["Linkedid"]].In(time.UTC) // 存储从string 改为 time.Time
|
|
|
startTime := startTimeutc.Format(time.RFC3339)
|
|
|
@@ -130,7 +128,7 @@ func CallNotify(event map[string]string) {
|
|
|
delete(StartTimeList, event["Linkedid"])
|
|
|
// Incoming Call - Missed
|
|
|
} else if event["Context"] == "macro-trunkdial-failover" && event["DialStatus"] == "NOANSWER" && slices.Contains(ZohoExtenList, event["CallerIDNum"]) { //坐席呼出,客户未接听,event["DialStatus"]判断未接听挂断原因
|
|
|
- lfshook.NewLogger().Info("Outgoing Call - NOANSWER")
|
|
|
+
|
|
|
startTimeutc := StartTimeList[event["Linkedid"]].In(time.UTC) // 存储从string 改为 time.Time
|
|
|
startTime := startTimeutc.Format(time.RFC3339)
|
|
|
// https://www.zohoapis.com/phonebridge/v3/callnotify?type=dialed&state=busy&id=10025&from=123456789&to=12300000001&start_time=2024-12-04 15:09:10
|
|
|
@@ -141,7 +139,7 @@ func CallNotify(event map[string]string) {
|
|
|
delete(StartTimeList, event["Linkedid"])
|
|
|
// Incoming Call - Missed
|
|
|
} else if event["Context"] == "macro-trunkdial-failover" && event["DialStatus"] == "BUSY" && slices.Contains(ZohoExtenList, event["CallerIDNum"]) { //坐席呼出,客户拒接
|
|
|
- lfshook.NewLogger().Info("Outgoing Call - BUSY")
|
|
|
+
|
|
|
startTimeutc := StartTimeList[event["Linkedid"]].In(time.UTC) // 存储从string 改为 time.Time
|
|
|
startTime := startTimeutc.Format(time.RFC3339)
|
|
|
// https://www.zohoapis.com/phonebridge/v3/callnotify?type=dialed&state=busy&id=10025&from=123456789&to=12300000001&start_time=2024-12-04 15:09:10
|
|
|
@@ -152,7 +150,7 @@ func CallNotify(event map[string]string) {
|
|
|
delete(StartTimeList, event["Linkedid"])
|
|
|
// Incoming Call - Missed
|
|
|
} else if (event["Context"] == "macro-stdexten" && event["DialStatus"] != "ANSWER" && Channel[0] != "Local" && slices.Contains(ZohoExtenList, event["DestCallerIDNum"])) || (event["Context"] == "macro-stdexten-withoutvm" && event["DialStatus"] != "ANSWER" && Channel[0] != "Local" && slices.Contains(ZohoExtenList, event["DestCallerIDNum"])) { // 呼入坐席未接听
|
|
|
- lfshook.NewLogger().Error("Incoming Call - Missed")
|
|
|
+
|
|
|
startTimeutc := StartTimeList[event["Linkedid"]].In(time.UTC) // 存储从string 改为 time.Time
|
|
|
startTime := startTimeutc.Format(time.RFC3339)
|
|
|
// https://www.zohoapis.com/phonebridge/v3/callnotify?type=received&state=missed&id=10005&from=12300000001&to=123456789&start_time=2024-12-04 15:09:10
|
|
|
@@ -192,11 +190,9 @@ func CallNotify(event map[string]string) {
|
|
|
// 呼叫已连接事件
|
|
|
} else if event["Event"] == "BridgeEnter" { //接听标志事件
|
|
|
Channel := strings.Split(event["Channel"], "/")
|
|
|
- fmt.Println("Channel[0] = ", Channel[0])
|
|
|
// Outgoing Call - Answered
|
|
|
if event["Context"] == "macro-trunkdial-failover" && event["Priority"] == "1" && slices.Contains(ZohoExtenList, event["ConnectedLineNum"]) { // 注意这里选择 Priority:1 的,便于确认 CallerIDNum,ConnectedLineNum
|
|
|
// 记录开始时间
|
|
|
- lfshook.NewLogger().Info("Outgoing Call - Answered")
|
|
|
TimestampList[event["Linkedid"]] = event["Timestamp"]
|
|
|
StartTimeList[event["Linkedid"]] = time.Now().Add(-8 * time.Hour)
|
|
|
// LinkedidList["Linkedid"] = event["Linkedid"]
|
|
|
@@ -211,7 +207,6 @@ func CallNotify(event map[string]string) {
|
|
|
// Incoming Call - Answered
|
|
|
} else if (event["Context"] == "macro-stdexten" || event["Context"] == "macro-stdexten-withoutvm") && Channel[0] != "Local" && slices.Contains(ZohoExtenList, event["ConnectedLineNum"]) && event["SwapUniqueid"] == "" { // event["SwapUniqueid"]判断是否转移
|
|
|
// 记录开始时间
|
|
|
- lfshook.NewLogger().Error("Incoming Call - Answered")
|
|
|
TimestampList[event["Linkedid"]] = event["Timestamp"] // 呼入时设置 Uniqueid 不是 Linkedid
|
|
|
StartTimeList[event["Linkedid"]] = time.Now().Add(-8 * time.Hour) // 呼入时设置 Uniqueid 不是 Linkedid
|
|
|
CallTypeList[event["Linkedid"]] = "incoming"
|
|
|
@@ -241,9 +236,12 @@ func CallNotify(event map[string]string) {
|
|
|
delete(TimetimesList, event["Linkedid"])
|
|
|
n = 0
|
|
|
}
|
|
|
+ // else if event["SwapUniqueid"] != "" {
|
|
|
+ // CallTypeList[event["Linkedid"]] = "incoming"
|
|
|
+ // }
|
|
|
|
|
|
// 呼叫挂断事件
|
|
|
- } else if event["Event"] == "HangupRequest" { //接听挂断标志事件
|
|
|
+ } else if event["Event"] == "Hangup" { //接听挂断标志事件
|
|
|
|
|
|
// * ===================================================================================== */
|
|
|
// 判断呼叫状态,为 ANSWER 时才推送,否则见以上推送 Outgoing Call - Unattended 或 Incoming Call - Missed
|
|
|
@@ -258,7 +256,6 @@ func CallNotify(event map[string]string) {
|
|
|
startTime := startTimeutc.Format(time.RFC3339)
|
|
|
durationTime := getDuration(event["Linkedid"], event["Timestamp"])
|
|
|
|
|
|
- lfshook.NewLogger().Errorf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCallTypeList %+v", CallTypeList)
|
|
|
if durationTime != -1 { //判断通话时长是否正常
|
|
|
if event["Priority"] == "1" && slices.Contains(ZohoExtenList, event["ConnectedLineNum"]) {
|
|
|
// https://www.zohoapis.com/phonebridge/v3/callnotify?type=dailed&state=ended&id=10030&from=123456789&to=12300000001&start_time=2024-12-04 11:32:15&duration=325
|
|
|
@@ -280,7 +277,7 @@ func CallNotify(event map[string]string) {
|
|
|
delete(StartTimeList, event["Linkedid"])
|
|
|
delete(CallTypeList, event["Linkedid"])
|
|
|
|
|
|
- } else if Channel[0] != "Local" && CallTypeList[event["Linkedid"]] == "incoming" { //坐席呼入挂断
|
|
|
+ } else if Channel[0] != "Local" && CallTypeList[event["Linkedid"]] == "incoming" && AttendedTransferList[event["Linkedid"]] == "" { //坐席呼入挂断
|
|
|
|
|
|
startTimeutc := StartTimeList[event["Linkedid"]].In(time.UTC) // 存储从string 改为 time.Time
|
|
|
startTime := startTimeutc.Format(time.RFC3339)
|
|
|
@@ -302,45 +299,61 @@ func CallNotify(event map[string]string) {
|
|
|
}
|
|
|
|
|
|
}
|
|
|
-
|
|
|
delete(StartTimeList, event["Linkedid"])
|
|
|
delete(CallTypeList, event["Linkedid"])
|
|
|
|
|
|
- } else if AttendedTransferList[event["Linkedid"]] != "" { //转接挂断
|
|
|
- startTimeutc := StartTimeList[AttendedTransferList[event["Linkedid"]]].In(time.UTC) // 存储从string 改为 time.Time
|
|
|
+ } else if AttendedTransferList[event["Linkedid"]] != "" && CallTypeList[event["Linkedid"]] == "incoming" { //转接挂断
|
|
|
+
|
|
|
+ startTimeutc := StartTimeList[event["Linkedid"]].In(time.UTC) // 存储从string 改为 time.Time
|
|
|
startTime := startTimeutc.Format(time.RFC3339)
|
|
|
- durationTime := getDuration(AttendedTransferList[event["Linkedid"]], event["Timestamp"])
|
|
|
+ durationTime := getDuration(event["Linkedid"], event["Timestamp"])
|
|
|
if event["Priority"] == "1" && slices.Contains(ZohoExtenList, event["CallerIDNum"]) {
|
|
|
- getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%d", ZOHO_URL, AttendedTransferList[event["Linkedid"]], event["ConnectedLineNum"], event["CallerIDNum"], startTime, durationTime)
|
|
|
+ getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%d", ZOHO_URL, event["Linkedid"], event["ConnectedLineNum"], event["CallerIDNum"], startTime, durationTime)
|
|
|
// getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%d", ZOHO_URL, callId, event["ConnectedLineNum"], event["CallerIDName"], startTime, durationTime)
|
|
|
|
|
|
fmt.Println("getURL = ", getURL)
|
|
|
go httpclient.ZohoGet(getURL)
|
|
|
} else if slices.Contains(ZohoExtenList, event["ConnectedLineNum"]) {
|
|
|
- getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%d", ZOHO_URL, AttendedTransferList[event["Linkedid"]], event["CallerIDNum"], event["ConnectedLineNum"], startTime, durationTime)
|
|
|
+ getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%d", ZOHO_URL, event["Linkedid"], event["CallerIDNum"], event["ConnectedLineNum"], startTime, durationTime)
|
|
|
// getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%d", ZOHO_URL, callId, event["ConnectedLineNum"], event["CallerIDName"], startTime, durationTime)
|
|
|
|
|
|
fmt.Println("getURL = ", getURL)
|
|
|
go httpclient.ZohoGet(getURL)
|
|
|
}
|
|
|
- delete(StartTimeList, AttendedTransferList[event["Linkedid"]])
|
|
|
- delete(CallTypeList, AttendedTransferList[event["Linkedid"]])
|
|
|
+ AttendedSecondTransferList[event["Linkedid"]] = AttendedTransferList[event["Linkedid"]] //创建转移后通话的初始时间戳
|
|
|
+ delete(StartTimeList, event["Linkedid"])
|
|
|
+ delete(CallTypeList, event["Linkedid"])
|
|
|
delete(AttendedTransferList, event["Linkedid"])
|
|
|
|
|
|
+ } else if AttendedSecondTransferList[event["Linkedid"]] != "" { //转接挂断
|
|
|
+ startTimeutc := StartTimeList[AttendedSecondTransferList[event["Linkedid"]]].In(time.UTC) // 存储从string 改为 time.Time
|
|
|
+ startTime := startTimeutc.Format(time.RFC3339)
|
|
|
+ durationTime := getDuration(AttendedSecondTransferList[event["Linkedid"]], event["Timestamp"])
|
|
|
+
|
|
|
+ if event["Priority"] == "1" && slices.Contains(ZohoExtenList, event["CallerIDNum"]) {
|
|
|
+ getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%d", ZOHO_URL, AttendedSecondTransferList[event["Linkedid"]], event["ConnectedLineNum"], event["CallerIDNum"], startTime, durationTime)
|
|
|
+ // getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%d", ZOHO_URL, callId, event["ConnectedLineNum"], event["CallerIDName"], startTime, durationTime)
|
|
|
+
|
|
|
+ fmt.Println("getURL = ", getURL)
|
|
|
+ go httpclient.ZohoGet(getURL)
|
|
|
+ } else if slices.Contains(ZohoExtenList, event["ConnectedLineNum"]) {
|
|
|
+ getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%d", ZOHO_URL, AttendedSecondTransferList[event["Linkedid"]], event["CallerIDNum"], event["ConnectedLineNum"], startTime, durationTime)
|
|
|
+ // getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%d", ZOHO_URL, callId, event["ConnectedLineNum"], event["CallerIDName"], startTime, durationTime)
|
|
|
+
|
|
|
+ fmt.Println("getURL = ", getURL)
|
|
|
+ go httpclient.ZohoGet(getURL)
|
|
|
+ }
|
|
|
+ delete(StartTimeList, AttendedSecondTransferList[event["Linkedid"]])
|
|
|
+ delete(AttendedSecondTransferList, event["Linkedid"])
|
|
|
+
|
|
|
}
|
|
|
|
|
|
} else if event["Event"] == "AttendedTransfer" && slices.Contains(ZohoExtenList, event["TransfereeConnectedLineNum"]) { //热转接
|
|
|
if event["Result"] == "Success" {
|
|
|
- durationTime := getDuration(event["OrigTransfererLinkedid"], event["Timestamp"])
|
|
|
- startTimeutc := StartTimeList[event["OrigTransfererLinkedid"]].In(time.UTC) // 存储从string 改为 time.Time
|
|
|
- startTime := startTimeutc.Format(time.RFC3339)
|
|
|
+
|
|
|
AttendedTransferList[event["OrigTransfererLinkedid"]] = event["SecondTransfererLinkedid"]
|
|
|
- getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%d", ZOHO_URL, event["OrigTransfererLinkedid"], event["TransfereeCallerIDNum"], event["TransfereeConnectedLineNum"], startTime, durationTime)
|
|
|
|
|
|
- fmt.Println("getURL = ", getURL)
|
|
|
- go httpclient.ZohoGet(getURL)
|
|
|
- delete(StartTimeList, event["OrigTransfererLinkedid"])
|
|
|
- delete(CallTypeList, event["OrigTransfererLinkedid"])
|
|
|
+ delete(CallTypeList, event["SecondTransfererLinkedid"])
|
|
|
}
|
|
|
} else if event["Event"] == "SoftHangupRequest" { //呼入离线坐席
|
|
|
Channel := strings.Split(event["Channel"], "/")
|
|
|
@@ -409,7 +422,6 @@ func getDuration(linkedid string, timeStamp string) int { // 都改为 Linkedid
|
|
|
// @Produce json
|
|
|
// @Router /api/zoho/refresh-token [post]
|
|
|
func RefreshToken() {
|
|
|
- fmt.Printf("RefreshToken ............\n")
|
|
|
|
|
|
// 获取配置文件信息
|
|
|
// confPath := "/etc/asterisk/vtiger_api.conf"
|
|
|
@@ -490,7 +502,7 @@ func RefreshToken() {
|
|
|
|
|
|
// 每隔55分钟刷新token
|
|
|
func RefreshTokenTicker() {
|
|
|
- fmt.Printf("RefreshTokenTicker ............\n")
|
|
|
+
|
|
|
ticker := time.NewTicker(55 * time.Minute)
|
|
|
defer ticker.Stop()
|
|
|
done := make(chan bool)
|
|
|
@@ -528,7 +540,7 @@ func ZohoUserExtenList() {
|
|
|
// lfshook.NewLogger().Error(ZohoExtenList)
|
|
|
}
|
|
|
func RefreshZohoUserExtenListTicker() {
|
|
|
- fmt.Printf("RefreshTokenTicker ............\n")
|
|
|
+
|
|
|
ticker := time.NewTicker(5 * time.Second)
|
|
|
defer ticker.Stop()
|
|
|
done := make(chan bool)
|