You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.0 KiB
Go

2 months ago
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"
}