package qcloud import ( "crypto/sha256" "encoding/hex" "errors" "fmt" "strings" "time" "goutil/mathUtil" "goutil/smsUtil/sms" ) const ( SINGLE_SMS_URL = "https://yun.tim.qq.com/v5/tlssmssvr/sendsms" MULTI_SMS_URL = "https://yun.tim.qq.com/v5/tlssmssvr/sendmultisms2" ) // 创建msg类型短信(直接发送短信内容) // 参数: // // appid // appkey // nation []string 国家代码 eg: 86 // numbers []string 电话号码 // msg string 短信内容 // extend string 通道扩展码,可选字段,默认没有开通(需要填空串) // ext string 用户的session内容,腾讯server回包中会原样返回,可选字段,不需要就填空 // // nation、numbers 需要一一对应 (nation[0]将与numbers[0]组合) // msg 必须与已通过审核的模板匹配 func NewMsgSms(appid, appkey string, nation, numbers []string, msg, extend, ext string) (sms.Sms, error) { return generateSms(appid, appkey, nation, numbers, extend, ext, newMsgSmsField(0, msg), nil) } // 创建tmpl类型短信(通过模板发送短信) // 参数: // // appid // appkey // nation []string 国家代码 eg: 86 // numbers []string 电话号码 // tmplID int 模板ID // params []string 模板参数 // sign string 短信签名(前缀) // extend string 通道扩展码,可选字段,默认没有开通(需要填空串) // ext string 用户的session内容,腾讯server回包中会原样返回,可选字段,不需要就填空 // // nation、numbers 需要一一对应 (nation[0]将与numbers[0]组合) func NewTmplSms(appid, appkey string, nation, numbers []string, tmplID int, params []string, sign, extend, ext string) (sms.Sms, error) { return generateSms(appid, appkey, nation, numbers, extend, ext, nil, newTmplSmsField(sign, tmplID, params)) } // create qcloud sms instance func generateSms(appid, appkey string, nation, numbers []string, extend, ext string, msg *msgSmsField, tmpl *tmplSmsField) (s sms.Sms, err error) { err = validateMobile(nation, numbers) if err != nil { return } var url string // 区分 if len(nation) > 1 { url = MULTI_SMS_URL } else { url = SINGLE_SMS_URL } // 生成随机数、时间戳,并计算签名 rnd := mathUtil.GetRand().GetRandRangeInt(100000, 999999) timestap := time.Now().Unix() sig := calcSig(appkey, rnd, timestap, numbers) // 生成公共字段 comField := newCommonField(sig, timestap, extend, ext, generateTelField(nation, numbers)) // 生成smsData data := newSmsData(comField, msg, tmpl) // 生成qcloudsms s = newSms(url, data, rnd, appid) return } // calculate sign-string for phone numbers func calcSig(appkey string, rnd int, tm int64, numbers []string) string { mobile := strings.Join(numbers, ",") sum := sha256.Sum256([]byte(fmt.Sprintf("appkey=%v&random=%v&time=%v&mobile=%v", appkey, rnd, tm, mobile))) return hex.EncodeToString(sum[:]) } // 验证地区代码与手机号数量是否匹配 func validateMobile(nation, numbers []string) error { if len(nation) != len(numbers) { return errors.New("loadReq: nation、numbers 数量不同") } else if len(nation) == 0 { return errors.New("loadReq: nation、numbers 不能为空") } return nil } // 生成Tel字段 // 当多个号码时,生成[]telField // 单个号码时,生成telField func generateTelField(nation, numbers []string) interface{} { res := make([](*telField), len(nation)) for i := 0; i < len(nation); i++ { res[i] = newTelField(nation[i], numbers[i]) } if len(res) == 1 { return res[0] } return res }