|
|
package sms_providers
|
|
|
|
|
|
import (
|
|
|
"context"
|
|
|
"encoding/json"
|
|
|
"fmt"
|
|
|
|
|
|
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
|
|
|
dysmsapi20170525 "github.com/alibabacloud-go/dysmsapi-20170525/v5/client"
|
|
|
util "github.com/alibabacloud-go/tea-utils/v2/service"
|
|
|
"github.com/alibabacloud-go/tea/tea"
|
|
|
credential "github.com/aliyun/credentials-go/credentials"
|
|
|
"github.com/veypi/OneAuth/cfg"
|
|
|
"github.com/vyes-ai/vigo"
|
|
|
"github.com/vyes-ai/vigo/logv"
|
|
|
)
|
|
|
|
|
|
// AliyunProvider 阿里云短信服务
|
|
|
type AliyunProvider struct {
|
|
|
accessKeyID string
|
|
|
accessKeySecret string
|
|
|
signName string
|
|
|
endpoint string
|
|
|
templateID string
|
|
|
}
|
|
|
|
|
|
// NewAliyunProvider 创建阿里云短信服务
|
|
|
func NewAliyunProvider(config cfg.RegionConfig) (SMSProvider, error) {
|
|
|
|
|
|
if config.Endpoint == "" {
|
|
|
config.Endpoint = "dysmsapi.aliyuncs.com"
|
|
|
}
|
|
|
|
|
|
return &AliyunProvider{
|
|
|
accessKeyID: config.Key,
|
|
|
accessKeySecret: config.Secret,
|
|
|
signName: config.SignName,
|
|
|
endpoint: config.Endpoint,
|
|
|
templateID: config.TemplateID,
|
|
|
}, nil
|
|
|
}
|
|
|
|
|
|
// SendSMS 发送短信
|
|
|
func (p *AliyunProvider) SendSMS(ctx context.Context, req *SendSMSRequest) (string, error) {
|
|
|
if req.Phone == "" {
|
|
|
return "", fmt.Errorf("phone is required")
|
|
|
}
|
|
|
|
|
|
// 工程代码建议使用更安全的无AK方式,凭据配置方式请参见:https://help.aliyun.com/document_detail/378661.html。
|
|
|
credential, err := credential.NewCredential(new(credential.Config).SetType("access_key").SetAccessKeyId(p.accessKeyID).SetAccessKeySecret(p.accessKeySecret))
|
|
|
// credential, err := credential.NewCredential(nil)
|
|
|
if err != nil {
|
|
|
return "", err
|
|
|
}
|
|
|
|
|
|
config := &openapi.Config{
|
|
|
Credential: credential,
|
|
|
}
|
|
|
// Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
|
|
|
config.Endpoint = tea.String(p.endpoint)
|
|
|
client, err := dysmsapi20170525.NewClient(config)
|
|
|
if err != nil {
|
|
|
return "", err
|
|
|
}
|
|
|
templateID := req.TemplateID
|
|
|
if templateID == "" {
|
|
|
templateID = p.templateID
|
|
|
}
|
|
|
|
|
|
paramsBytes, _ := json.Marshal(req.Params)
|
|
|
logv.Warn().Msgf("Send SMS to %s, %s, templateID: %s, params: %s", req.Phone, p.signName, templateID, string(paramsBytes))
|
|
|
sendSmsRequest := &dysmsapi20170525.SendSmsRequest{
|
|
|
SignName: tea.String(p.signName),
|
|
|
TemplateCode: tea.String(templateID),
|
|
|
PhoneNumbers: tea.String(req.Phone),
|
|
|
TemplateParam: tea.String(string(paramsBytes)),
|
|
|
}
|
|
|
runtime := &util.RuntimeOptions{}
|
|
|
msgID := ""
|
|
|
tryErr := func() (_e error) {
|
|
|
defer func() {
|
|
|
if r := tea.Recover(recover()); r != nil {
|
|
|
_e = r
|
|
|
}
|
|
|
}()
|
|
|
// 复制代码运行请自行打印 API 的返回值
|
|
|
res, _err := client.SendSmsWithOptions(sendSmsRequest, runtime)
|
|
|
if _err != nil {
|
|
|
return _err
|
|
|
}
|
|
|
if res != nil && res.Body != nil && res.Body.BizId != nil {
|
|
|
msgID = *res.Body.BizId
|
|
|
}
|
|
|
if msgID == "" && res != nil && res.Body != nil && res.Body.Message != nil {
|
|
|
logv.Warn().Msgf("%+v", res)
|
|
|
return vigo.NewError(*res.Body.Message)
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
}()
|
|
|
if tryErr != nil {
|
|
|
return "", tryErr
|
|
|
}
|
|
|
return msgID, nil
|
|
|
}
|
|
|
|
|
|
// GetName 获取服务商名称
|
|
|
func (p *AliyunProvider) GetName() string {
|
|
|
return "aliyun"
|
|
|
}
|