Files
be.ems/features/fm/smsforward.go

272 lines
7.0 KiB
Go

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.FindByRmuid(alarmData.NeId)
eventTime := date.ParseStrToDate(alarmData.EventTime, date.YYYY_MM_DDTHH_MM_SSZ)
alarmForwardLog := neDataModel.AlarmForwardLog{
NeType: neInfo.NeType,
NeId: neInfo.NeId,
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,
// }