更新时间:2024-06-21 GMT+08:00
Go
- 发送短信为单模板群发短信示例,发送分批短信为多模板群发短信示例。
- 本文档所述Demo在提供服务的过程中,可能会涉及个人数据的使用,建议您遵从国家的相关法律采取足够的措施,以确保用户的个人数据受到充分的保护。
- 本文档所述Demo仅用于功能演示,不允许客户直接进行商业使用。
- 本文档信息仅供参考,不构成任何要约或承诺。
参考API签名SDK与demo,点击下载其中的SDK与Demo。将下列代码样例替换demo.go文件内容即可。
将首层go.mod文件内容修改为:
1 2 3 4 5 6 7 |
module huaweicloud.com/apig/go/signer require huaweicloud.com/apig/signer v0.0.0 replace huaweicloud.com/apig/signer v0.0.0 => ./core go 1.12 |
发送短信示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
package main import ( "bytes" "crypto/tls" "fmt" core "huaweicloud.com/apig/signer" "io/ioutil" "net/http" "net/url" ) func main() { //必填,请参考"开发准备"获取如下数据,替换为实际值 appInfo := core.Signer{ // 认证用的appKey和appSecret硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; Key: "c8RWg3ggEcyd4D3p94bf3Y7x1Ile", //App Key Secret: "q4Ii87Bh************80SfD7Al", //App Secret } apiAddress := "https://smsapi.ap-southeast-1.myhuaweicloud.com:443/sms/batchSendSms/v1" //APP接入地址(在控制台"应用管理"页面获取)+接口访问URI sender := "csms12345678" //中国大陆短信签名通道号或全球短信通道号 templateId := "8ff55eac1d0b478ab3c06c3c6a492300" //模板ID //条件必填,中国大陆短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称 //全球短信不用关注该参数 signature := "华为云短信测试" //签名名称 //必填,全局号码格式(包含国家码),示例:+86151****6789,多个号码之间用英文逗号分隔 receiver := "+86151****6789" //短信接收人号码 //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告 statusCallBack := "" /* * 选填,使用无变量模板时请赋空值 string templateParas = ""; * 单变量模板示例:模板内容为"您的验证码是${NUM_6}"时,templateParas可填写为'["369751"]' * 双变量模板示例:模板内容为"您有${NUM_2}件快递请到${TXT_20}领取"时,templateParas可填写为'["3","人民公园正门"]' * 查看更多模板和变量规范:产品介绍>模板和变量规范 */ templateParas := "[\"369751\"]" //模板变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。 body := buildRequestBody(sender, receiver, templateId, templateParas, statusCallBack, signature) resp, err := post(apiAddress, []byte(body), appInfo) if err != nil { return } fmt.Println(resp) } /** * sender,receiver,templateId不能为空 */ func buildRequestBody(sender, receiver, templateId, templateParas, statusCallBack, signature string) string { param := "from=" + url.QueryEscape(sender) + "&to=" + url.QueryEscape(receiver) + "&templateId=" + url.QueryEscape(templateId) if templateParas != "" { param += "&templateParas=" + url.QueryEscape(templateParas) } if statusCallBack != "" { param += "&statusCallback=" + url.QueryEscape(statusCallBack) } if signature != "" { param += "&signature=" + url.QueryEscape(signature) } return param } func post(url string, param []byte, appInfo core.Signer) (string, error) { if param == nil || appInfo == (core.Signer{}) { return "", nil } // 代码样例为了简便,设置了不进行证书校验,请在商用环境自行开启证书校验。 tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{Transport: tr} req, err := http.NewRequest("POST", url, bytes.NewBuffer(param)) if err != nil { return "", err } // 对请求增加内容格式,固定头域 req.Header.Add("Content-Type", "application/x-www-form-urlencoded") // 对请求进行HMAC算法签名,并将签名结果设置到Authorization头域。 appInfo.Sign(req) fmt.Println(req.Header) // 发送短信请求 resp, err := client.Do(req) if err != nil { fmt.Println(err) } // 获取短信响应 defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return "", err } return string(body), nil } |
发送分批短信示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
package main import ( "bytes" "crypto/tls" "encoding/json" "fmt" core "huaweicloud.com/apig/signer" "io/ioutil" "net/http" ) func main() { //必填,请参考"开发准备"获取如下数据,替换为实际值 apiAddress := "https://smsapi.ap-southeast-1.myhuaweicloud.com:443/sms/batchSendDiffSms/v1" //APP接入地址(在控制台"应用管理"页面获取)+接口访问URI // 认证用的appKey和appSecret硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全; appKey := "c8RWg3ggEcyd4D3p94bf3Y7x1Ile" //APP_Key appSecret := "q4Ii87Bh************80SfD7Al" //APP_Secret sender := "csms12345678" //中国大陆短信签名通道号或全球短信通道号 templateId1 := "8ff55eac1d0b478ab3c06c3c6a492300" //模板ID1 templateId2 := "8ff55eac1d0b478ab3c06c3c6a492300" //模板ID2 //条件必填,中国大陆短信关注,当templateId指定的模板类型为通用模板时生效且必填,必须是已审核通过的,与模板类型一致的签名名称 //全球短信不用关注该参数 signature1 := "华为云短信测试" //签名名称1 signature2 := "华为云短信测试" //签名名称2 //必填,全局号码格式(包含国家码),示例:+8615123456789,多个号码之间用英文逗号分隔 receiver1 := []string{"+86151****6789", "+86152****7890"} //模板1的接收号码 receiver2 := []string{"+86151****6789", "+86152****7890"} //模板2的接收号码 //选填,短信状态报告接收地址,推荐使用域名,为空或者不填表示不接收状态报告 statusCallBack := "" /** * 选填,使用无变量模板时请赋空值 templateParas := []string{} * 单变量模板示例:模板内容为"您的验证码是${NUM_6}"时,templateParas可填写为[]string{"369751"} * 双变量模板示例:模板内容为"您有${NUM_2}件快递请到${TXT_20}领取"时,templateParas可填写为[]string{{"3","人民公园正门"} * ${DATE}${TIME}变量不允许取值为空,${TXT_20}变量可以使用英文空格或点号替代空值,${NUM_6}变量可以使用0替代空值 * 查看更多模板和变量规范:产品介绍>模板和变量规范 */ templateParas1 := []string{"123456"} //模板1变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。 templateParas2 := []string{"234567"} //模板2变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。 item1 := initDiffSms(receiver1, templateId1, templateParas1, signature1) item2 := initDiffSms(receiver2, templateId2, templateParas2, signature2) item := []map[string]interface{}{item1, item2} body := buildRequestBody(sender, item, statusCallBack) appInfo := core.Signer{ Key: appKey, //App Key Secret: appSecret, //App Secret } resp, err := post(apiAddress, []byte(body), appInfo) if err != nil { return } fmt.Println(resp) } func buildRequestBody(sender string, item []map[string]interface{}, statusCallBack string) []byte { body := make(map[string]interface{}) body["smsContent"] = item body["from"] = sender if statusCallBack != "" { body["statusCallback"] = statusCallBack } res, _ := json.Marshal(body) return res } func initDiffSms(reveiver []string, templateId string, templateParas []string, signature string) map[string]interface{} { diffSms := make(map[string]interface{}) diffSms["to"] = reveiver diffSms["templateId"] = templateId if templateParas != nil && len(templateParas) > 0 { diffSms["templateParas"] = templateParas } if signature != "" { diffSms["signature"] = signature } return diffSms } func post(url string, param []byte, appInfo core.Signer) (string, error) { if param == nil || appInfo == (core.Signer{}) { return "", nil } // 代码样例为了简便,设置了不进行证书校验,请在商用环境自行开启证书校验。 tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{Transport: tr} req, err := http.NewRequest("POST", url, bytes.NewBuffer(param)) if err != nil { return "", err } // 对请求增加内容格式,固定头域 req.Header.Add("Content-Type", "application/json") // 对请求进行HMAC算法签名,并将签名结果设置到Authorization头域。 appInfo.Sign(req) fmt.Println(req.Header) // 发送短信请求 resp, err := client.Do(req) if err != nil { fmt.Println(err) } // 获取短信响应 defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return "", err } return string(body), nil } |
接收状态报告
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package main import ( "fmt" "net/url" "strings" ) func main() { // 短信平台上报状态报告数据样例(urlencode) //success_body := "sequence=1&total=1&updateTime=2018-10-31T08%3A43%3A41Z&source=2&smsMsgId=2ea20735-f856-4376-afbf-570bd70a46ee_11840135&status=DELIVRD"; failed_body := "orgCode=E200027&sequence=1&total=1&updateTime=2018-10-31T08%3A43%3A41Z&source=2&smsMsgId=2ea20735-f856-4376-afbf-570bd70a46ee_11840135&status=RTE_ERR"; //onSmsStatusReport(success_body); onSmsStatusReport(failed_body); } func onSmsStatusReport(data string) { ss, _ := url.QueryUnescape(data) params := strings.Split(ss, "&") keyValues := make(map[string]string) for i := range params { temp := strings.Split(params[i],"=") keyValues[temp[0]] = temp[1]; } /** * Example: 此处已解析status为例,请按需解析所需参数并自行实现相关处理 * * 'smsMsgId': 短信唯一标识 * 'total': 长短信拆分条数 * 'sequence': 拆分后短信序号 * 'source': 状态报告来源 * 'updateTime': 资源更新时间 * 'status': 状态报告枚举值 * 'orgCode': 状态码 */ status := keyValues["status"]; if status == "DELIVRD" { fmt.Println("Send sms success. smsMsgId: " + keyValues["smsMsgId"]) } else { fmt.Println("Send sms failed. smsMsgId: " + keyValues["smsMsgId"]) fmt.Println("Failed status: " + keyValues["status"]) fmt.Println("Failed orgCode: " + keyValues["orgCode"]) } } |
父主题: 特殊AK/SK认证(推荐)