package sms import ( "encoding/json" "fmt" "strings" "github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi" ) func newAliyun(options Options) (sys *Aliyun, err error) { sys = &Aliyun{options: options} sys.client, err = dysmsapi.NewClientWithAccessKey(options.RegionId, options.AccessKeyId, options.AccessKeySecret) return } type Aliyun struct { options Options client *dysmsapi.Client } // SendCaptcha 发送验证码短信(阿里云 Dysmsapi SendSms)。 func (this *Aliyun) SendCaptcha(mobile string, captcha string) (err error) { template, err := pickTemplate(this.options, mobile) if err != nil { return } param, err := json.Marshal(map[string]string{this.options.TemplateParamName: captcha}) if err != nil { return } request := dysmsapi.CreateSendSmsRequest() request.Scheme = "https" request.PhoneNumbers = aliMobile(mobile) request.SignName = this.options.SignName request.TemplateCode = template request.TemplateParam = string(param) resp, err := this.client.SendSms(request) if err != nil { return } // 阿里云同样是「HTTP 成功 ≠ 发送成功」:真实结果看 Code,成功为 "OK"。 if resp == nil { return fmt.Errorf("阿里云短信发送失败: 返回为空") } if resp.Code != "OK" { return fmt.Errorf("阿里云短信发送失败: %s %s", resp.Code, resp.Message) } return } // aliMobile 把号码转成阿里云要求的格式: // 国内号只要 11 位裸号(带 +86/0086 前缀会被判为非法号码), // 国际/港澳台号用 "00+国际区号+号码"(阿里云不接受 "+" 开头)。 func aliMobile(mobile string) string { m := normalizeMobile(mobile) if isDomestic(m) { m = strings.TrimPrefix(m, "+86") m = strings.TrimPrefix(m, "0086") return m } if strings.HasPrefix(m, "+") { return "00" + strings.TrimPrefix(m, "+") } return m }