Browse Source

完成热转接

dujunchen 1 day ago
parent
commit
74becbaa17
2 changed files with 139 additions and 206 deletions
  1. 139 206
      api/admin/zoho/push.go
  2. BIN
      deployments/crm-api

+ 139 - 206
api/admin/zoho/push.go

@@ -1,7 +1,6 @@
 package zoho
 
 import (
-	"crm-api/pkg/configs"
 	"crm-api/pkg/httpclient"
 	"crm-api/pkg/lfshook"
 	"encoding/json"
@@ -19,68 +18,10 @@ var TimestampList = make(map[string]string)
 var StartTimeList = make(map[string]time.Time) // 事件中 Timestamp 转 StartTime 有问题,重新记录时间
 var LinkedidList = make(map[string]string)     // 临时记录 incoming 和 outgoing
 var DialStatusList = make(map[string]string)   // 临时记录 DialStatus:ANSWER NOANSWER
-//	func addOneToStringNumber(s string) string {
-//		num, err := strconv.Atoi(s)
-//		if err != nil {
-//			fmt.Println("xxxxxxxxxxxxx = ", err)
-//		}
-//		num++
-//		return strconv.Itoa(num)
-//	}
+var CallTypeList = make(map[string]string)     //通过Linkedid临时记录拨打类型呼入还是呼出
+
 func CallNotify(event map[string]string) {
-	// fmt.Println("=========================================== ")
-	fmt.Println("event111111111111111111111111111111111[] = ", event)
-	fmt.Println("Cause111111111111111111111111111111111 = ", event["Cause"])
-	fmt.Println("AMIPushUrl1111111111111111111111111111 = ", configs.PushConfigValue.AMIPushUrl)
-	fmt.Println("Channel1111111111111111111111111111111 = ", event["Uniqueid"])
-
-	/* ===================不这样取callDest,删除 ====================
-	var callDest string
-	if event["Channel"] != "" {
-		callDest = strings.Split(strings.Split(event["Channel"], "/")[1], "-")[0]
-		fmt.Println("callDest = ", callDest)
-	}
-	// * ========================================================= */
-
-	// var callId string
-	// timestamp := time.Now().Unix()
-	// rand.Seed(time.Now().UnixNano())
-
-	// // 字符串
-	// charset := "abcdefghijklmnopqrstuvwxyz"
-
-	// // 获取随机字符
-	// c := charset[rand.Intn(len(charset))]
-	// callId = "callid" + strconv.Itoa(int(timestamp))
-	// if callId == " " {
-	// 	input := "callid100000"
-	// 	num, err := strconv.Atoi(input)
-	// 	if err != nil {
-	// 		fmt.Println("x11111111111 = ", err)
-	// 	}
-	// 	num++
-	// 	callId = strconv.Itoa(num)
-	// 	fmt.Println("callId111111111 = ", callId)
-	// } else {
-	// 	num, err := strconv.Atoi(callId)
-	// 	if err != nil {
-	// 		fmt.Println("x22222222222222 = ", err)
-	// 	}
-	// 	num++
-	// 	callId = strconv.Itoa(num)
-	// 	fmt.Println("callId2222222222 = ", callId)
-	// }
-	// var callId = "callid100014" // 测试用,每次测试 +1
-	// event["Exten"] = "123456789" // 测试用
-	// fmt.Println("callId = ", callId)
-	// var zohoUser = "872297346" // 测试用 872297346 873447071  // 后面看是否从数据库中取 t_zoho_user
-	// var info TabZohouser
-	// if _, err := mysql.DBOrmInstance.Insert(&info); err != nil {
-	// 	lfshook.NewLogger().Error(err)
-	// 	return
-	// }
-	// var zohoUser = info.UserId
-	// 读取vtiger配置文件
+
 	confPath := "/etc/asterisk/crm_api.conf"
 	cfg, err := ini.Load(confPath)
 	if err != nil {
@@ -94,36 +35,12 @@ func CallNotify(event map[string]string) {
 	}
 
 	// var getURL string
-	fmt.Println("Context = ", event["Context"])
+	// fmt.Println("Context = ", event["Context"])
 	// 呼叫发起事件
 	// if event["Event"] == "DialBegin" && event["Context"] == "macro-stdexten" {
 	// if event["Event"] == "DialBegin" && strings.Compare(event["Context"], "macro-stdexten") == 0 {
 	if event["Event"] == "DialBegin" {
 
-		/* ===================先放这里测试用 ============================================================
-		// 记录开始时间
-		TimestampList[event["Uniqueid"]] = event["Timestamp"]
-		// StartTimeList[event["Uniqueid"]] = time.Now().Format("2006-01-02 15:04:09")
-		StartTimeList[event["Uniqueid"]] = time.Now()
-		/* ===================先放这里测试用 ============================================================
-		fmt.Printf("Uniqueid=%s\n", event["Uniqueid"])
-		fmt.Printf("Timestamp=%s\n", event["Timestamp"])
-
-		TimestampTmp, err := strconv.Atoi(event["Timestamp"]) // 不要
-		if err != nil {
-			fmt.Printf("转换出错: %v\n", err)
-			return
-		}
-		fmt.Printf("TimestampAtoi=%d\n", TimestampTmp)
-
-		TimestampTmp002, err := strconv.ParseFloat(event["Timestamp"], 64) // OK
-		if err != nil {
-			fmt.Printf("转换出错: %v\n", err)
-			return
-		}
-		fmt.Printf("TimestampParseFloat=%f\n", TimestampTmp002)
-
-		// * ===================================================================================== */
 		Channel := strings.Split(event["Channel"], "/")
 		fmt.Println("Channel[0] = ", Channel[0])
 		// Outgoing Call - Ringing
@@ -159,6 +76,13 @@ func CallNotify(event map[string]string) {
 			fmt.Println("getURL = ", getURL)
 			go httpclient.ZohoGet(getURL)
 
+		} else if strings.HasPrefix(event["Context"], "department") || strings.HasSuffix(event["Context"], "queue") {
+			getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ringing&id=%s&from=%s&to=%s", ZOHO_URL, event["Linkedid"], event["CallerIDNum"], event["DestCallerIDNum"])
+			// if zohoUser != "" {
+			// 	getURL = fmt.Sprintf("%s&zohouser=%s", getURL, zohoUser)
+			// }
+			fmt.Println("getURL = ", getURL)
+			go httpclient.ZohoGet(getURL)
 		}
 
 		// 呼叫结束事件
@@ -185,7 +109,7 @@ func CallNotify(event map[string]string) {
 			// }
 			fmt.Println("getURL = ", getURL)
 			go httpclient.ZohoGet(getURL)
-
+			delete(StartTimeList, event["Linkedid"])
 			// Incoming Call - Missed
 			// if event["Context"] == "macro-stdexten" && event["DialStatus"] != "ANSWER" {
 		} else if event["Context"] == "macro-trunkdial-failover" && event["DialStatus"] == "NOANSWER" {
@@ -204,7 +128,7 @@ func CallNotify(event map[string]string) {
 			// }
 			fmt.Println("getURL = ", getURL)
 			go httpclient.ZohoGet(getURL)
-
+			delete(StartTimeList, event["Linkedid"])
 			// Incoming Call - Missed
 			// if event["Context"] == "macro-stdexten" && event["DialStatus"] != "ANSWER" {
 		} else if event["Context"] == "macro-trunkdial-failover" && event["DialStatus"] == "BUSY" {
@@ -223,7 +147,7 @@ func CallNotify(event map[string]string) {
 			// }
 			fmt.Println("getURL = ", getURL)
 			go httpclient.ZohoGet(getURL)
-
+			delete(StartTimeList, event["Linkedid"])
 			// Incoming Call - Missed
 			// if event["Context"] == "macro-stdexten" && event["DialStatus"] != "ANSWER" {
 		} else if (event["Context"] == "macro-stdexten" && event["DialStatus"] != "ANSWER" && Channel[0] != "Local") || (event["Context"] == "macro-stdexten-withoutvm" && event["DialStatus"] != "ANSWER" && Channel[0] != "Local") { // 开启语音留言:macro-stdexten  关闭语音留言:macro-stdexten-withoutvm
@@ -242,7 +166,7 @@ func CallNotify(event map[string]string) {
 			// }
 			fmt.Println("getURL = ", getURL)
 			go httpclient.ZohoGet(getURL)
-
+			delete(StartTimeList, event["Linkedid"])
 		}
 
 		// 呼叫已连接事件
@@ -261,6 +185,7 @@ func CallNotify(event map[string]string) {
 			TimestampList[event["Linkedid"]] = event["Timestamp"]
 			StartTimeList[event["Linkedid"]] = time.Now().Add(-8 * time.Hour)
 			LinkedidList["Linkedid"] = event["Linkedid"]
+			CallTypeList[event["Linkedid"]] = "outgoing"
 			// https: //www.zohoapis.com/phonebridge/v3/callnotify?type=dialed&state=answered&id=10003&from=123456789&to=12300000001
 			// getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=dialed&state=answered&id=%s&from=%s&to=%s", ZOHO_URL, callId, event["CallerIDNum"], event["ConnectedLineNum"])
 			getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=dialed&state=answered&id=%s&from=%s&to=%s", ZOHO_URL, event["Linkedid"], event["ConnectedLineNum"], event["CallerIDNum"])
@@ -283,6 +208,7 @@ func CallNotify(event map[string]string) {
 			TimestampList[event["Linkedid"]] = event["Timestamp"]             // 呼入时设置 Uniqueid 不是 Linkedid
 			StartTimeList[event["Linkedid"]] = time.Now().Add(-8 * time.Hour) // 呼入时设置 Uniqueid 不是 Linkedid
 			LinkedidList["Linkedid"] = event["Linkedid"]
+			CallTypeList[event["Linkedid"]] = "incoming"
 			// https://www.zohoapis.com/phonebridge/v3/callnotify?type=received&state=answered&id=10023&from=12300000001&to=123456789
 			getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=answered&id=%s&from=%s&to=%s", ZOHO_URL, event["Linkedid"], event["CallerIDNum"], event["ConnectedLineNum"])
 			// if zohoUser != "" {
@@ -291,79 +217,56 @@ func CallNotify(event map[string]string) {
 			fmt.Println("getURL = ", getURL)
 			go httpclient.ZohoGet(getURL)
 
+		} else if (strings.HasPrefix(event["Context"], "department") && event["Priority"] == "1") || strings.HasSuffix(event["Context"], "queue") {
+			TimestampList[event["Linkedid"]] = event["Timestamp"]             // 呼入时设置 Uniqueid 不是 Linkedid
+			StartTimeList[event["Linkedid"]] = time.Now().Add(-8 * time.Hour) // 呼入时设置 Uniqueid 不是 Linkedid
+			LinkedidList["Linkedid"] = event["Linkedid"]
+			CallTypeList[event["Linkedid"]] = "incoming"
+			if event["Priority"] == "1" {
+
+				getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=answered&id=%s&from=%s&to=%s", ZOHO_URL, event["Linkedid"], event["ConnectedLineNum"], event["CallerIDNum"])
+				// if zohoUser != "" {
+				// 	getURL = fmt.Sprintf("%s&zohouser=%s", getURL, zohoUser)
+				// }
+				fmt.Println("getURL = ", getURL)
+				go httpclient.ZohoGet(getURL)
+			} else {
+				getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=answered&id=%s&from=%s&to=%s", ZOHO_URL, event["Linkedid"], event["CallerIDNum"], event["ConnectedLineNum"])
+				// if zohoUser != "" {
+				// 	getURL = fmt.Sprintf("%s&zohouser=%s", getURL, zohoUser)
+				// }
+				fmt.Println("getURL = ", getURL)
+				go httpclient.ZohoGet(getURL)
+			}
+
 		}
 
 		// 呼叫挂断事件
 	} else if event["Event"] == "HangupRequest" {
-		/* ===================先放这里测试用 ============================================================
-		// 记录结束时间
-		// TimestampList[event["Uniqueid"]] = event["Timestamp"]
-		// startTimeStamp := int64(TimestampList[event["Uniqueid"]])
-
-		fmt.Println("startTimeStamp Str: ", TimestampList[event["Uniqueid"]])
-		// keyTmp := event["Uniqueid"]
-		// fmt.Println("keyTmp: ", keyTmp)
-		// fmt.Println("startTimeStamp Str: ", TimestampList[keyTmp])
-
-		startTimeStamp, err := strconv.ParseFloat(TimestampList[event["Uniqueid"]], 64) // OK
-		if err != nil {
-			fmt.Printf("startTimeStamp转换出错: %v\n", err)
-			return
-		}
-		fmt.Printf("startTimeStamp=%f\n", startTimeStamp)
 
-		endTimeStamp, err := strconv.ParseFloat(event["Timestamp"], 64) // OK
-		if err != nil {
-			fmt.Printf("endTimeStamp转换出错: %v\n", err)
-			return
-		}
-		fmt.Printf("endTimeStamp=%f\n", endTimeStamp)
-
-		durationTime := time.Duration(endTimeStamp-startTimeStamp) * time.Second
-		fmt.Println("durationTime=", durationTime)
-		// 删除记录时间
-		// delete(TimestampList, event["Uniqueid"])
 		// * ===================================================================================== */
 		// 判断呼叫状态,为 ANSWER 时才推送,否则见以上推送 Outgoing Call - Unattended 或 Incoming Call - Missed
 		Channel := strings.Split(event["Channel"], "/")
 		fmt.Println("event[] = ", event)
 		fmt.Println("Channel[0] = ", Channel[0])
-		lfshook.NewLogger().Errorf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa %+v", event["Context"])
+		// lfshook.NewLogger().Errorf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa %+v", event["Context"])
 		fmt.Println("ChannelHangupRequest1 = ", DialStatusList[event["Linkedid"]])
 		fmt.Println("ChannelHangupRequest1 = ", event["DialStatus"])
-		if DialStatusList[event["Linkedid"]] == "ANSWER" {
-			lfshook.NewLogger().Errorf("ChannelHangupRequest = %+v", event["Uniqueid"])
-			fmt.Println("event[] = ", event)
-			fmt.Println("event = ", event["Event"])
-			lfshook.NewLogger().Errorf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa %+v", event["Context"])
-			lfshook.NewLogger().Errorf("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb %+v", event["Linkedid"])
-			lfshook.NewLogger().Errorf("ccccccccccccccccccccccccccccccc %+v", event["DialStatus"])
+		// if DialStatusList[event["Linkedid"]] == "ANSWER" {//暂时不使用dialend的呼叫状态
+		lfshook.NewLogger().Errorf("ChannelHangupRequest = %+v", event["Uniqueid"])
+		fmt.Println("event[] = ", event)
+		fmt.Println("event = ", event["Event"])
+
+		startTimeutc := StartTimeList[event["Linkedid"]].In(time.UTC) // 存储从string 改为 time.Time
+		startTime := startTimeutc.Format(time.RFC3339)
+		fmt.Println("startTime: ", startTime)
+		// Outgoing Call - Ended
+		if event["Context"] == "macro-trunkdial-failover" && CallTypeList[event["Linkedid"]] == "outgoing" {
+			fmt.Println("Linkedid = ", event["Timestamp"])
 			durationTime := getDuration(event["Linkedid"], event["Timestamp"])
-			startTimeutc := StartTimeList[event["Linkedid"]].In(time.UTC) // 存储从string 改为 time.Time
-			startTime := startTimeutc.Format(time.RFC3339)
-			fmt.Println("startTime: ", startTime)
-			// Outgoing Call - Ended
-			if event["Context"] == "macro-trunkdial-failover" && durationTime != -1 {
-				fmt.Println("Linkedid = ", event["Timestamp"])
-				// 获取时间
-				// durationTime := getDuration(event["Uniqueid"], event["Timestamp"])
-				// durationTime := getDuration(event["Linkedid"], event["Timestamp"])
-				// /* ===================测试用 ============================================================
-				// startTime, _ := time.Parse("2006-01-02 15:04:05", TimestampList[event["Uniqueid"]]) // error   1734328213.774410  =>  0001-01-01 00:00:00 +0000 UTC
-				// startTime := StartTimeList[event["Uniqueid"]]
-				// startTime := StartTimeList[event["Uniqueid"]].Format("2006-01-02 15:04:09") // 存储从string 改为 time.Time
-				// startTime := StartTimeList[event["Linkedid"]].Format("2006-01-02 15:04:09") // 存储从string 改为 time.Time
-				// startTimeutc := StartTimeList[event["Linkedid"]].In(time.UTC) // 存储从string 改为 time.Time
-				// startTime := startTimeutc.Format(time.RFC3339)
-				// fmt.Println("startTime: ", startTime)
-				// durationTime002 := getDuration002(startTime)
-				// durationTime002 := time.Now().Sub(StartTimeList[event["Uniqueid"]]) // ok    durationTime002:  7.78408849s   // should use time.Since instead of time.Now().Sub (S1012)
-				// durationTime002 := time.Since(StartTimeList[event["Uniqueid"]]) // ok    durationTime002:  11.611233458s
-				// fmt.Println("durationTime002: ", durationTime002)
-				// * ===================================================================================== */
-
-				// 删除记录时间
-				delete(StartTimeList, event["Linkedid"])
+
+			lfshook.NewLogger().Errorf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCallTypeList %+v", CallTypeList)
+			if durationTime != -1 {
 				if event["Priority"] == "1" {
 					// 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
 					// getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=dailed&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%d", ZOHO_URL, callId, event["CallerIDNum"], event["ConnectedLineNum"], startTime, durationTime)
@@ -383,13 +286,18 @@ func CallNotify(event map[string]string) {
 					fmt.Println("getURL = ", getURL)
 					go httpclient.ZohoGet(getURL)
 				}
-
-				// Incoming Call - Ended
-				// 	// if event["Context"] == "macro-stdexten" { // Context:DialPlan1
-				// } else if Channel[0] != "Local" && durationTime != -1 { // 开启语音留言:macro-stdexten  关闭语音留言:macro-stdexten-withoutvm
-			} else if (event["Context"] == "macro-stdexten" || event["Context"] == "macro-stdexten-withoutvm") && Channel[0] != "Local" && durationTime != -1 {
-				// if event["Context"] != "macro-trunkdial-failover" {
-				fmt.Println("Linkedid = ", event["Timestamp"])
+			}
+			// 删除记录时间
+			delete(StartTimeList, event["Linkedid"])
+			delete(CallTypeList, event["Linkedid"])
+			// Incoming Call - Ended
+			// 	// if event["Context"] == "macro-stdexten" { // Context:DialPlan1
+			// } else if Channel[0] != "Local" && durationTime != -1 { // 开启语音留言:macro-stdexten  关闭语音留言:macro-stdexten-withoutvm
+		} else if Channel[0] != "Local" && CallTypeList[event["Linkedid"]] == "incoming" {
+			// if event["Context"] != "macro-trunkdial-failover" {
+			fmt.Println("Linkedid = ", event["Timestamp"])
+			durationTime := getDuration(event["Linkedid"], event["Timestamp"])
+			if durationTime != -1 {
 				if event["Priority"] == "1" {
 					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)
@@ -407,47 +315,85 @@ func CallNotify(event map[string]string) {
 					fmt.Println("getURL = ", getURL)
 					go httpclient.ZohoGet(getURL)
 				}
-				// 还需优化判断,开启语音留言时,主叫挂断才是 macro-stdexten , 被叫挂断是 DialPlan1
-				//              关闭语音留言时,主叫挂断才是 macro-stdexten-withoutvm , 被叫挂断是 DialPlan1
-				// 如果 Outgoing Call 只会是 macro-trunkdial-failover 的话,那么和以下判断换一下,else 不判断,都为 Incoming Call 处理
-
-				// 获取时间
-				// durationTime := getDuration(event["Uniqueid"], event["Timestamp"])
-				// startTime := StartTimeList[event["Uniqueid"]].Format("2006-01-02 15:04:09") // 存储从string 改为 time.Time
-				// durationTime := getDuration(event["Linkedid"], event["Timestamp"])
-				// startTimeutc := StartTimeList[event["Linkedid"]].In(time.UTC) // 存储从string 改为 time.Time
-				// startTime := startTimeutc.Format(time.RFC3339)
-				// fmt.Println("startTime: ", startTime)
+			}
 
-				// https://www.zohoapis.com/phonebridge/v3/callnotify?type=received&state=ended&id=100&from=12300000001&to=123456789&start_time=2024-12-04 10:32:10&duration=223
+			delete(StartTimeList, event["Linkedid"])
+			delete(CallTypeList, event["Linkedid"])
+			// 还需优化判断,开启语音留言时,主叫挂断才是 macro-stdexten , 被叫挂断是 DialPlan1
+			//              关闭语音留言时,主叫挂断才是 macro-stdexten-withoutvm , 被叫挂断是 DialPlan1
+			// 如果 Outgoing Call 只会是 macro-trunkdial-failover 的话,那么和以下判断换一下,else 不判断,都为 Incoming Call 处理
 
-			}
 		}
-	} else if event["Event"] == "Cdr" {
-		if event["Disposition"] == "ANSWERED" {
-			startTimeutc := StartTimeList[LinkedidList["Linkedid"]].In(time.UTC) // 存储从string 改为 time.Time
+		// }
+	} else if event["Event"] == "SoftHangupRequest" {
+		if event["Exten"] == "s-CHANUNAVAIL" {
+			startTimebj := time.Now().Add(-8 * time.Hour)
+			startTimeutc := startTimebj.In(time.UTC) // 存储从string 改为 time.Time
 			startTime := startTimeutc.Format(time.RFC3339)
-			CallSrcNum := strings.Split(strings.Split(event["CallSrcNum"], "<")[1], ">")[0]
-			if event["CallType"] == "outgoing" {
-				getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=dailed&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%s", ZOHO_URL, LinkedidList["Linkedid"], CallSrcNum, event["CallDestNum"], startTime, event["Duration"])
-				// if zohoUser != "" {
-				// 	getURL = fmt.Sprintf("%s&zohouser=%s", getURL, zohoUser)
-				// }
-				fmt.Println("getURL = ", getURL)
-				go httpclient.ZohoGet(getURL)
-				delete(LinkedidList, "Linkedid")
-			} else if event["CallType"] == "incoming" {
-				getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%s", ZOHO_URL, LinkedidList["Linkedid"], CallSrcNum, event["CallDestNum"], startTime, event["Duration"])
-				// 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)
-				// if zohoUser != "" {
-				// 	getURL = fmt.Sprintf("%s&zohouser=%s", getURL, zohoUser)
-				// }
-				fmt.Println("getURL = ", getURL)
-				go httpclient.ZohoGet(getURL)
-				delete(LinkedidList, "Linkedid")
-			}
+			ConnectedLineNum := strings.Split(strings.Split(event["ConnectedLineNum"], "<")[1], ">")[0]
+			getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=missed&id=%s&from=%s&to=%s&start_time=%s", ZOHO_URL, event["Linkedid"], event["CallerIDNum"], ConnectedLineNum, startTime)
+			// if zohoUser != "" {
+			// 	getURL = fmt.Sprintf("%s&zohouser=%s", getURL, zohoUser)
+			// }
+			fmt.Println("getURL = ", getURL)
+			go httpclient.ZohoGet(getURL)
+		}
+	} else if event["Event"] == "AttendedTransfer" { //热转接
+		if event["Result"] == "Success" {
+			durationTime := getDuration(event["SecondTransfererLinkedid"], event["Timestamp"])
+			startTimeutc := StartTimeList[event["SecondTransfererLinkedid"]].In(time.UTC) // 存储从string 改为 time.Time
+			startTime := startTimeutc.Format(time.RFC3339)
+			fmt.Println("startTime: ", startTime)
+			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["SecondTransfererLinkedid"], event["TransfereeCallerIDNum"], event["TransfereeConnectedLineNum"], startTime, durationTime)
+			// if zohoUser != "" {
+			// 	getURL = fmt.Sprintf("%s&zohouser=%s", getURL, zohoUser)
+			// }
+			fmt.Println("getURL = ", getURL)
+			go httpclient.ZohoGet(getURL)
 		}
 	}
+	// else if event["Event"] == "Cdr" {
+	// 	if event["Disposition"] == "ANSWERED" && event["CallType"] == "incoming" && strings.HasPrefix(event["DestinationContext"], "department") {
+	// 		durationTime := getDuration(LinkedidList["Linkedid"], event["Timestamp"])
+	// 		startTimeutc := StartTimeList[LinkedidList["Linkedid"]].In(time.UTC) // 存储从string 改为 time.Time
+	// 		startTime := startTimeutc.Format(time.RFC3339)
+	// 		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["Source"], event["Destination"], 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)
+	// 		// if zohoUser != "" {
+	// 		// 	getURL = fmt.Sprintf("%s&zohouser=%s", getURL, zohoUser)
+	// 		// }
+	// 		fmt.Println("getURL = ", getURL)
+	// 		go httpclient.ZohoGet(getURL)
+	// 		delete(LinkedidList, "Linkedid")
+	// 	}
+	// }
+	// else if event["Event"] == "Cdr" {
+	// 	if event["Disposition"] == "ANSWERED" {
+	// 		durationTime := getDuration(LinkedidList["Linkedid"], event["Timestamp"])
+	// 		startTimeutc := StartTimeList[LinkedidList["Linkedid"]].In(time.UTC) // 存储从string 改为 time.Time
+	// 		startTime := startTimeutc.Format(time.RFC3339)
+	// 		CallSrcNum := strings.Split(strings.Split(event["CallSrcNum"], "<")[1], ">")[0]
+	// 		if event["CallType"] == "outgoing" {
+	// 			getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=dailed&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%d", ZOHO_URL, LinkedidList["Linkedid"], CallSrcNum, event["CallDestNum"], startTime, durationTime)
+	// 			// if zohoUser != "" {
+	// 			// 	getURL = fmt.Sprintf("%s&zohouser=%s", getURL, zohoUser)
+	// 			// }
+	// 			fmt.Println("getURL = ", getURL)
+	// 			go httpclient.ZohoGet(getURL)
+	// 			delete(LinkedidList, "Linkedid")
+	// 		} else if event["CallType"] == "incoming" {
+	// 			getURL := fmt.Sprintf("%s/phonebridge/v3/callnotify?type=received&state=ended&id=%s&from=%s&to=%s&start_time=%s&duration=%d", ZOHO_URL, LinkedidList["Linkedid"], CallSrcNum, event["CallDestNum"], 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)
+	// 			// if zohoUser != "" {
+	// 			// 	getURL = fmt.Sprintf("%s&zohouser=%s", getURL, zohoUser)
+	// 			// }
+	// 			fmt.Println("getURL = ", getURL)
+	// 			go httpclient.ZohoGet(getURL)
+	// 			delete(LinkedidList, "Linkedid")
+	// 		}
+	// 	}
+	// }
+
 	// fmt.Println("getURL = ", getURL)
 
 	// 测试验证下上面有没有删除,以防TimestampList越来越大
@@ -501,19 +447,6 @@ func getDuration(linkedid string, timeStamp string) int { // 都改为 Linkedid
 	return int(durationTime.Seconds())
 }
 
-// // 程序中取时间计算间隔多少秒
-// func getDuration002(startTime string) time.Duration {
-// 	// durationTime := endTime.Sub(startTime)
-// 	startTime002, err := time.Parse("2006-01-02 15:04:05", startTime)
-// 	if err != nil {
-// 		fmt.Println("Error parsing time:", err)
-// 		return 0
-// 	}
-// 	durationTime := time.Now().Sub(startTime002)
-// 	return durationTime
-
-// }
-
 // @tags PBX-zoho
 // @Summary 刷新token
 // @Description 刷新token

BIN
deployments/crm-api