package fm import ( "errors" "fmt" "net/http" "net/url" "strings" "time" "be.ems/lib/config" "be.ems/lib/dborm" "be.ems/lib/log" "be.ems/src/framework/utils/date" neDataModel "be.ems/src/modules/network_data/model" neDataService "be.ems/src/modules/network_data/service" neService "be.ems/src/modules/network_element/service" "github.com/linxGnu/gosmpp" "github.com/linxGnu/gosmpp/data" "github.com/linxGnu/gosmpp/pdu" ) func AlarmSMSForward(alarmData *Alarm) error { switch config.GetYamlConfig().Alarm.SMProxy { case "sms": users, err := AlarmForwardBySMS(alarmData) writeLog(alarmData, users, "SMS", err) return err case "smsc": users, err := AlarmForwardBySMPP(alarmData) writeLog(alarmData, users, "SMS", err) return err default: users, err := AlarmForwardBySMPP(alarmData) writeLog(alarmData, users, "SMS", err) return err } } func AlarmForwardBySMS(alarmData *Alarm) (string, error) { log.Info("AlarmForwardBySMS processing... ") SMSFforwardconfig := config.GetYamlConfig().Alarm.SMS // 阿里云短信API的请求地址 apiURL := SMSFforwardconfig.ApiURL // 阿里云短信API的AccessKey ID和AccessKey Secret //accessKeyID := SMSFforwardconfig.AccessKeyID accessKeySecret := SMSFforwardconfig.AccessKeySecret toUsers, err := dborm.XormGetAlarmForward("SMS") if err != nil { log.Error("Failed to XormGetAlarmForward:", err) return "", err } if toUsers == nil { err := errors.New("not found forward phone number") log.Error(err) return "", err } userList := strings.Join(*toUsers, ",") if len(userList) == 0 { err := errors.New("not found forward phone number") log.Error(err) return "", err } // 短信相关参数 params := url.Values{} params.Set("PhoneNumbers", userList) params.Set("SignName", SMSFforwardconfig.SignName) params.Set("TemplateCode", SMSFforwardconfig.TemplateCode) params.Set("TemplateParam", `{"message":"alarm"}`) // 构建请求URL reqURL := apiURL + "?Action=SendSms&" + params.Encode() // 创建HTTP请求 req, err := http.NewRequest("GET", reqURL, nil) if err != nil { log.Error("Failed to create request:", err) return userList, err } // 添加请求头部 req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("Authorization", "APPCODE "+accessKeySecret) // 发送请求 client := &http.Client{} resp, err := client.Do(req) if err != nil { log.Error("Failed to send request:%v", err) return userList, err } defer resp.Body.Close() // 解析响应 switch resp.StatusCode { case http.StatusOK, http.StatusAccepted, http.StatusNoContent, http.StatusCreated: return userList, nil default: log.Error(fmt.Errorf("failed to send SMS: %s(Code=%d)", resp.Status, resp.StatusCode)) return userList, err } } var smsForward = &(config.GetYamlConfig().Alarm.SMSCForward) func AlarmForwardBySMPP(alarmData *Alarm) (string, error) { log.Info("AlarmForwardBySMPP processing... ") if smsForward == nil { err := errors.New("smsForward configuration is nil") log.Error(err) return "", err } userList := smsForward.MobileList if len(userList) == 0 { err := errors.New("not found forward phone number") log.Error(err) return "", err } auth := gosmpp.Auth{ SMSC: smsForward.SMSCAddr, SystemID: smsForward.SystemID, Password: smsForward.Password, SystemType: smsForward.SystemType, } trans, err := gosmpp.NewSession( gosmpp.TXConnector(gosmpp.NonTLSDialer, auth), gosmpp.Settings{ ReadTimeout: 2 * time.Second, OnPDU: func(p pdu.PDU, _ bool) { log.Debug("%+v", p) }, OnSubmitError: func(_ pdu.PDU, err error) { log.Error(err) }, OnRebindingError: func(err error) { log.Error(err) }, OnClosed: func(state gosmpp.State) { log.Error(state) }, }, -1) if err != nil { log.Error("Failed to create SMPP new session:", err) return "", err } defer func() { if err := trans.Close(); err != nil { log.Error(err) } }() message := "Alarm Notification: " + alarmData.AlarmTitle + " from " + alarmData.NeType + "_" + alarmData.NeId + " at " + alarmData.EventTime users := strings.Split(userList, ",") for _, user := range users { if user == "" { continue } sm, err := newSubmitSM(user, message) if err != nil { log.Errorf("Failed to newSubmitSM %s short message: %v", user, err) writeLog(alarmData, user, "SMS", err) continue } if err = trans.Transceiver().Submit(sm); err != nil { log.Errorf("Failed to Submit %s short message: %v", user, err) writeLog(alarmData, user, "SMS", err) continue } writeLog(alarmData, user, "SMS", nil) } return userList, nil } func writeLog(alarmData *Alarm, toUser, forwardBy string, err error) error { var result string = fmt.Sprintf("%s Sent Successfully!", forwardBy) if err != nil { result = err.Error() } neInfo := neService.NewNeInfo.FindByCoreUidAndNeUid("*", alarmData.NeId) eventTime := date.ParseStrToDate(alarmData.EventTime, date.YYYY_MM_DDTHH_MM_SSZ) alarmForwardLog := neDataModel.AlarmForwardLog{ CoreUID: neInfo.CoreUID, NeUID: neInfo.NeUID, NeType: neInfo.NeType, AlarmSeq: int64(alarmData.AlarmSeq), AlarmId: alarmData.AlarmId, AlarmTitle: alarmData.AlarmTitle, AlarmCode: int64(alarmData.AlarmCode), AlarmStatus: fmt.Sprint(alarmData.AlarmStatus), AlarmType: alarmTypeValue(alarmData.AlarmType), OrigSeverity: origSeverityValue(alarmData.OrigSeverity), EventTime: eventTime.UnixMilli(), Type: forwardBy, Target: toUser, Result: result, } // 记录日志 insertId := neDataService.NewAlarmForwardLog.Insert(alarmForwardLog) if insertId <= 0 { return fmt.Errorf("failed to insert data") } return nil } func newSubmitSM(phoneNumber string, message string) (*pdu.SubmitSM, error) { // build up submitSM srcAddr := pdu.NewAddress() srcAddr.SetTon(5) srcAddr.SetNpi(0) err := srcAddr.SetAddress(smsForward.ServiceNumber) if err != nil { return nil, err } destAddr := pdu.NewAddress() destAddr.SetTon(1) destAddr.SetNpi(1) err = destAddr.SetAddress(phoneNumber) if err != nil { return nil, err } submitSM := pdu.NewSubmitSM().(*pdu.SubmitSM) submitSM.SourceAddr = srcAddr submitSM.DestAddr = destAddr dataCoding := data.FromDataCoding(smsForward.DataCoding) err = submitSM.Message.SetMessageWithEncoding(message, dataCoding) if err != nil { return nil, err } submitSM.ProtocolID = 0 submitSM.RegisteredDelivery = 1 submitSM.ReplaceIfPresentFlag = 0 submitSM.EsmClass = 0 return submitSM, nil } // const ( // // Short message data coding type // SMS_CODING_GSM7BIT byte = iota // SMS_CODING_ASCII // SMS_CODING_BINARY8BIT1 // SMS_CODING_LATIN1 // SMS_CODING_BINARY8BIT2 // SMS_CODING_NODEF // SMS_CODING_CYRILLIC // SMS_CODING_HEBREW // SMS_CODING_UCS2 // ) // var codingMap = map[byte]data.Encoding{ // SMS_CODING_GSM7BIT: data.GSM7BIT, // SMS_CODING_ASCII: data.ASCII, // SMS_CODING_BINARY8BIT1: data.BINARY8BIT1, // SMS_CODING_LATIN1: data.LATIN1, // SMS_CODING_BINARY8BIT2: data.BINARY8BIT2, // SMS_CODING_CYRILLIC: data.CYRILLIC, // SMS_CODING_HEBREW: data.HEBREW, // SMS_CODING_UCS2: data.UCS2, // }