package action import ( "pbx-api-gin/internal/app/ami/model" "pbx-api-gin/internal/app/mysql" "pbx-api-gin/internal/app/stc/active" "pbx-api-gin/internal/app/stc/priority" alstatus "pbx-api-gin/internal/app/stc/sendstatus" "pbx-api-gin/internal/pkg/configs" "pbx-api-gin/pkg/lfshook" "pbx-api-gin/pkg/utils" "time" "github.com/sirupsen/logrus" "github.com/tqcenglish/amigo-go" "github.com/tqcenglish/amigo-go/pkg" ) var AminInstance *amigo.Amigo //type Operation func(src, dst string, whisper, bargein bool) func HandleAMI(event map[string]string) { lfshook.NewLogger().Infof("===start======%s", event["Event"]) //return if not actived if !active.Actived { return } switch event["Event"] { case "UserEvent": lfshook.NewLogger().Infof("========event:%s File:%s", event["Event"], event["FILENAME"]) if event["UserEvent"] == "SetRecordFile" { //get record file name alstatus.SendRecordFile(event["FILENAME"], event["RecordType"]) } case "Newchannel": lfshook.NewLogger().Infof("=========%s", event["Event"]) if utils.IsPAIU(event["CallerIDNum"]) && event["Exten"] == "0300" { // Alarm dial queue start; PAD dialing alstatus.PaStatus(event["CallerIDNum"], "PAD", "start") alstatus.AlarmStatus(event["CallerIDNum"], "dial") } case "SoftHangupRequest": //pre-recored broadcast end lfshook.NewLogger().Infof("=========%s", event["Event"]) if event["CallerIDName"] == "EMG" && event["Exten"] == "0502" { // EMG broadcast hangup alstatus.PaStatus(event["CallerIDName"], "EMG", "end") } else if event["CallerIDName"] == "STN" && event["Exten"] == "0503" { alstatus.PaStatus(event["CallerIDName"], "STN", "end") } else if event["CallerIDName"] == "DCS" && event["Exten"] == "0504" { alstatus.PaStatus(event["CallerIDName"], "DCS", "end") } else if event["CallerIDName"] == "SPC" && event["Exten"] == "0505" { alstatus.PaStatus(event["CallerIDName"], "SPC", "end") } else if event["CallerIDName"] == "CHK" && event["Exten"] == "0510" { alstatus.PaStatus(event["CallerIDName"], "CHK", "end") } case "Hangup": lfshook.NewLogger().Infof("=========%s", event["Event"]) if utils.IsPACU(event["CallerIDNum"]) && utils.IsICP(event["ConnectedLineNum"]) { // TMS-ICP answer PAD, hangup res, _ := QueueStatus("0300", "") // check ICP queue ,if empty PAD end if res.Calls == "0" { priority.ICPAnswer = 0 alstatus.PaStatus(event["CallerIDNum"], "PAD", "end") break } } if utils.IsPAIU(event["CallerIDNum"]) && utils.IsICP(event["ConnectedLineNum"]) { // TMS-ICP answer PAD(PACU not availabe), hangup res, _ := QueueStatus("0300", "") // check ICP queue ,if empty PAD end if res.Calls == "0" { priority.ICPAnswer = 0 alstatus.PaStatus(event["CallerIDNum"], "PAD", "end") break } } if (event["CallerIDNum"] == "ani1" || event["CallerIDNum"] == "ani8") && utils.IsICP(event["ConnectedLineNum"]) { // ICP answer PAD, hangup res, _ := QueueStatus("0300", "") // check ICP queue ,if empty PAD end if res.Calls == "0" { priority.ICPAnswer = 0 alstatus.PaStatus(event["CallerIDNum"], "PAD", "end") break } } //OCC answer PAD, hangup, redirect the next PAD to OCC if (event["CallerIDNum"] == "ano1" || event["CallerIDNum"] == "ano8") && utils.IsIO(event["ConnectedLineNum"]) { res, _ := QueueStatus("0301", "") // check OCC queue ,if empty PAD end if res.Calls == "0" { //OCC queue is empty priority.OCCAnswer = 0 alstatus.OccPad("end") break } else { //OCC queue is not empty if active.CabNum == "1" && active.Actived && ExtenStatus("1411") == "Idle" { //check active and OCC status Dial("0401", "0512", "pad-rule-pacus-occ", "ano1", event["CallerIDNum"], "1") // PACUs dial OCC1 } else if active.CabNum == "8" && active.Actived && ExtenStatus("1481") == "Idle" { Dial("0401", "0512", "pad-rule-pacus-occ", "ano8", event["CallerIDNum"], "8") // PACUs dial OCC8 } } } case "QueueCallerJoin": lfshook.NewLogger().Infof("=========%s", event["Event"]) if priority.OCCAnswer == 1 && event["Queue"] == "0300" { //New PAD Goto the OCC queue in the first time, if OCC answered go RedirectInQueue(event["CallerIDNum"], "0301", "queues-occ", "") break } if utils.IsPAIU(event["CallerIDNum"]) && event["Queue"] == "0300" { // Alarm join the queue, PAD in the queue alstatus.AlarmStatus(event["CallerIDNum"], "queue") //send status to STC time.AfterFunc(30*time.Second, func() { // check the PAD 30s timeout if priority.ICPAnswer == 0 { //ICP did not answer any res, err := QueueStatus("0301", "") // check OCC queue , if empty OCC-PAD start if err != nil { lfshook.NewLogger().Infof("===OCC-QueueStatus==%+v", err) } if res.Calls == "0" { // OCC queue empty resCaller, err := QueueStatus("0300", "") // check ICP queue, get entries if err != nil { lfshook.NewLogger().Infof("===QueueStatus==%+v", err) } for _, caller := range resCaller.Entrys { go RedirectInQueue(caller.CallerIDNum, "0301", "queues-occ", "") // redirect All ICP-PAD redirect to OCC queue } } } }) break } //first caller goto OCC if utils.IsPAIU(event["CallerIDNum"]) && event["Queue"] == "0301" && priority.OCCAnswer == 0 { // The first PAD to OCC ,caller is PAD if active.CabNum == "1" && active.Actived && ExtenStatus("1411") == "Idle" { //check active and OCC status priority.OCCAnswer = 1 alstatus.OccPad("start") Dial("0401", "0512", "pad-rule-pacus-occ", "ano1", event["CallerIDNum"], "1") // PACUs dial OCC1 } else if active.CabNum == "8" && active.Actived && ExtenStatus("1481") == "Idle" { priority.OCCAnswer = 1 alstatus.OccPad("start") Dial("0401", "0512", "pad-rule-pacus-occ", "ano8", event["CallerIDNum"], "8") // PACUs dial OCC8 } } case "ConfbridgeJoin": lfshook.NewLogger().Infof("=========%s", event["Event"]) if utils.IsICP(event["CallerIDNum"]) && event["Exten"] == "0500" { // PA start lfshook.NewLogger().Infof("====PA status:%s=====", "start") alstatus.PaStatus(event["CallerIDNum"], "PA", "start") break } if utils.IsIO(event["CallerIDNum"]) && event["Exten"] == "0501" { //CPA start lfshook.NewLogger().Infof("====CPA status:%s=====", "start") alstatus.PaStatus(event["CallerIDNum"], "CPA", "start") break } //ICP answer PAD; //ICP8->whisper->ICP1; PAD->whisper->ICP8 if event["ConnectedLineNum"] == "ani1" && event["Exten"] == "0511" { //PAD answered by ICP; PACUs connected ICP1 lfshook.NewLogger().Infof("====PAD answered by ICP1:%s=====", event["ConnectedLineName"]) alstatus.AlarmStatus(event["ConnectedLineName"], "connect") go Dial("0402", "2311", "chanspy-rule", "ani1", event["ConnectedLineName"], "8") //trigger ChanSpyStart ,ICP8 whisper ICP1 //goto event=ChanSpyStart; PAD whisper ICP8 break } //ICP1->whisper->ICP8; PAD->whisper->ICP1 if event["ConnectedLineNum"] == "ani8" && event["Exten"] == "0511" { //PAD ansered by ICP8; PACUs connected ICP8 lfshook.NewLogger().Infof("====PAD answered by ICP8:%s=====", event["ConnectedLineName"]) alstatus.AlarmStatus(event["ConnectedLineName"], "connect") go Dial("0402", "2381", "chanspy-rule", "ani8", event["ConnectedLineName"], "1") //trigger ChanSpyStart ,ICP1 whisper ICP8 //goto event=ChanSpyStart; PAD whisper ICP1 break } //OCC answer PAD; if event["ConnectedLineNum"] == "ano1" && event["Exten"] == "0512" { //PAD answered by OCC; PACUs connected IO1 lfshook.NewLogger().Infof("====PAD answered by OCC1:%s=====", event["ConnectedLineName"]) alstatus.AlarmStatus(event["ConnectedLineName"], "connect") go RedirectInQueue(event["ConnectedLineName"], "1411", "chanspy-rule", "") //PAD whisper IO1 //goto event=ChanSpyStart; ICPs spy PAD break } if event["ConnectedLineNum"] == "ano8" && event["Exten"] == "0512" { //PAD ansered by OCC8; PACUs connected IO8 lfshook.NewLogger().Infof("====PAD answered by OCC8:%s=====", event["ConnectedLineName"]) alstatus.AlarmStatus(event["ConnectedLineName"], "connect") go RedirectInQueue(event["ConnectedLineName"], "1481", "chanspy-rule", "") //PAD whisper IO8 //goto event=ChanSpyStart; ICPs spy PAD break } //ICP-TMS answer PAD, PACU idle if utils.IsPACU(event["ConnectedLineNum"]) && event["Exten"] == "0403" { //PAD ansered by ICP-TMS; PACU Page() ICPs connected lfshook.NewLogger().Infof("====PAD answered by ICP-TMS:%s===PACU idle==", event["ConnectedLineName"]) alstatus.AlarmStatus(event["ConnectedLineName"], "connect") if active.CabNum == "1" && active.Actived { go RedirectInQueue(event["ConnectedLineName"], "2311", "chanspy-rule", "") //PAD whisper ICP1 } else if active.CabNum == "8" && active.Actived { go RedirectInQueue(event["ConnectedLineName"], "2381", "chanspy-rule", "") //PAD whisper ICP8 } break } if utils.IsPAIU(event["ConnectedLineName"]) && event["Exten"] == "0403" { //PAD ansered by ICP-TMS; PAD Page() ICPs connected lfshook.NewLogger().Infof("====PAD answered by ICP-TMS:%s==PADU no available===", event["ConnectedLineName"]) alstatus.AlarmStatus(event["ConnectedLineName"], "connect") break } case "ChanSpyStart": lfshook.NewLogger().Infof("=========%s", event["Event"]) //PAD answered by ICP ; PAD whisper ICP if event["SpyerConnectedLineName"] == "2381" && event["SpyerCallerIDNum"] == "2311" { //check if it is ICP8 whisper ICP1 lfshook.NewLogger().Infof("====PAD answered by ICP===;PAD whisper 2381=====") go RedirectInQueue(event["SpyeeConnectedLineName"], "2381", "chanspy-rule", "") //PAD whisper ICP8 break } if event["SpyerConnectedLineName"] == "2311" && event["SpyerCallerIDNum"] == "2381" { //check if it is ICP1 whisper ICP8 lfshook.NewLogger().Infof("====PAD answered by ICP===;PAD whisper 2311=====") go RedirectInQueue(event["SpyeeConnectedLineName"], "2311", "chanspy-rule", "") //PAD whisper ICP1 break } //PAD answered by OCC; ICPs chanspy PAD if utils.IsPAIU(event["SpyeeConnectedLineName"]) && utils.IsIO(event["SpyerExten"]) { // check if it is PAD whisper IO Dial("0404", event["SpyeeConnectedLineName"], "chanspy-rule-icps", "ano", "ano", "") //ICPs chanspy PAD } case "ConfbridgeLeave": lfshook.NewLogger().Infof("=========%s", event["Event"]) if utils.IsICP(event["CallerIDNum"]) && event["Exten"] == "0500" { // PA end lfshook.NewLogger().Infof("====PA status =====%s", "end") alstatus.PaStatus(event["CallerIDNum"], "PA", "end") } if utils.IsIO(event["CallerIDNum"]) && event["Exten"] == "0501" { //CPA end lfshook.NewLogger().Infof("====CPA status =====%s", "end") alstatus.PaStatus(event["CallerIDNum"], "CPA", "end") } case "DialEnd": lfshook.NewLogger().Infof("=========%s", event["Event"]) //Cab Cab start if utils.IsICP(event["CallerIDNum"]) && utils.IsICP(event["ConnectedLineNum"]) && event["DialStatus"] == "ANSWER" { alstatus.PaStatus(event["CallerIDNum"], "C2C", "start") } case "BridgeLeave": //Cab Cab end if utils.IsICP(event["CallerIDNum"]) && utils.IsICP(event["ConnectedLineNum"]) && event["Exten"] == "0400" { alstatus.PaStatus(event["CallerIDNum"], "C2C", "end") } case "ExtensionStatus": lfshook.NewLogger().Infof("=========event:%s status:%s", event["Event"], event["StatusText"]) status := &model.Extension{ Extension: event["Exten"], Status: event["StatusText"], } _, err := mysql.DBOrmInstance.Where("exten = ?", status.Extension).Cols("status").Update(status) if err != nil { lfshook.NewLogger().Infof("update extension status err : %+v", err.Error()) } if event["StatusText"] == "Idle" || event["StatusText"] == "Unavailable" { if len(event["Exten"]) > 3 { alstatus.AlarmStatus(event["Exten"], event["StatusText"]) // PAD idle + unavailable } } /* case "BridgeEnter": lfshook.NewLogger().Infof("=========event:%s callerid:%s", event["Event"], event["CallerIDNum"]) //ICP and PACU connected if utils.IsPACU(event["CallerIDNum"]) && utils.IsPAIU(event["CallerIDName"]) { //TMS-ICP connected PACU lfshook.NewLogger().Infof("====BridgeEnter==IN action===%s===ID:%s Name:%s", event["Event"], event["CallerIDNum"], event["CallerIDName"]) alstatus.AlarmStatus(event["CallerIDName"], "connect") // Alarm connected if active.CabNum == "1" && active.Actived { go RedirectInQueue(event["CallerIDName"], "2311", "chanspy-rule", "") // 1车TMS-ICP接听PAIU, PAD whisper ICP } else if active.CabNum == "8" && active.Actived { go RedirectInQueue(event["CallerIDName"], "2381", "chanspy-rule", "") // 8车TMS-ICP接听PAIU, PAD whisper ICP } } else if utils.IsPAIU(event["CallerIDNum"]) { lfshook.NewLogger().Infof("====send pad status=====") alstatus.AlarmStatus(event["CallerIDNum"], "connect") // PAD connect ICP-TMS }*/ } } func StartAMI(connectOKCallBack func(), handleEvents []func(event map[string]string)) { lfshook.NewLogger().Info("Start AMI") settings := &amigo.Settings{ Host: configs.ConfigGlobal.AsteriskAMIHost, Port: configs.ConfigGlobal.AsteriskAMIPort, Username: configs.ConfigGlobal.AsteriskAMIUser, Password: configs.ConfigGlobal.AsteriskAMISecret, LogLevel: logrus.ErrorLevel} lfshook.NewLogger().Infof("ami setting: %+v", settings) AminInstance = amigo.New(settings, lfshook.NewLogger()) AminInstance.EventOn(func(payload ...interface{}) { // lfshook.NewLogger().Infof("ami event on %+v", payload[0]) event := payload[0].(map[string]string) HandleAMI(event) for _, handle := range handleEvents { go handle(event) } }) AminInstance.ConnectOn(func(payload ...interface{}) { lfshook.NewLogger().Infof("ami connect on %+v", payload[0]) if payload[0] == pkg.Connect_OK { connectOKCallBack() } else { lfshook.NewLogger().Errorf("ami connect failure %+v", payload) } }) AminInstance.Connect() } func Connected() bool { if AminInstance != nil { return AminInstance.Connected() } return false }