91 lines
2.7 KiB
Go
91 lines
2.7 KiB
Go
package sms
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
|
|
dysmsapi20170525 "github.com/alibabacloud-go/dysmsapi-20170525/v3/client"
|
|
tea "github.com/alibabacloud-go/tea/tea"
|
|
)
|
|
|
|
// Config holds Aliyun SMS configuration.
|
|
type Config struct {
|
|
AccessKeyID string
|
|
AccessKeySecret string
|
|
SignName string
|
|
TemplateCode string
|
|
Endpoint string // default: dysmsapi.aliyuncs.com
|
|
}
|
|
|
|
type Client struct {
|
|
cfg Config
|
|
client *dysmsapi20170525.Client
|
|
}
|
|
|
|
// New creates an Aliyun SMS client. Does not send any request.
|
|
func New(cfg Config) (*Client, error) {
|
|
if strings.TrimSpace(cfg.AccessKeyID) == "" || strings.TrimSpace(cfg.AccessKeySecret) == "" {
|
|
return nil, errors.New("sms: access key not configured")
|
|
}
|
|
if strings.TrimSpace(cfg.SignName) == "" || strings.TrimSpace(cfg.TemplateCode) == "" {
|
|
return nil, errors.New("sms: signName/templateCode not configured")
|
|
}
|
|
if strings.TrimSpace(cfg.Endpoint) == "" {
|
|
cfg.Endpoint = "dysmsapi.aliyuncs.com"
|
|
}
|
|
|
|
oc := &openapi.Config{
|
|
AccessKeyId: tea.String(cfg.AccessKeyID),
|
|
AccessKeySecret: tea.String(cfg.AccessKeySecret),
|
|
Endpoint: tea.String(cfg.Endpoint),
|
|
}
|
|
cli, err := dysmsapi20170525.NewClient(oc)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &Client{cfg: cfg, client: cli}, nil
|
|
}
|
|
|
|
// TemplateData matches the Java version: time/name/content
|
|
type TemplateData struct {
|
|
Time string `json:"time"`
|
|
Name string `json:"name"`
|
|
Content string `json:"content"`
|
|
Alert string `json:"alert"`
|
|
}
|
|
|
|
// Send sends the template message to one or more phone numbers.
|
|
// name/content/alert/msgTime map to template ${name}, ${content}, ${alert}, ${time}.
|
|
func (c *Client) Send(ctx context.Context, name, content, alert, msgTime string, phones []string) error {
|
|
if len(phones) == 0 {
|
|
return errors.New("sms: empty phone list")
|
|
}
|
|
payload := TemplateData{Time: msgTime, Name: name, Content: content, Alert: alert}
|
|
b, _ := json.Marshal(payload)
|
|
param := string(b)
|
|
|
|
// Aliyun supports multiple comma-separated numbers, but keep batches small if needed.
|
|
joined := strings.Join(phones, ",")
|
|
req := &dysmsapi20170525.SendSmsRequest{
|
|
PhoneNumbers: tea.String(joined),
|
|
SignName: tea.String(c.cfg.SignName),
|
|
TemplateCode: tea.String(c.cfg.TemplateCode),
|
|
TemplateParam: tea.String(param),
|
|
}
|
|
|
|
// Execute request
|
|
resp, err := c.client.SendSms(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
code := tea.StringValue(resp.Body.Code)
|
|
if strings.ToUpper(code) != "OK" {
|
|
return fmt.Errorf("sms: send failed code=%s message=%s requestId=%s", code, tea.StringValue(resp.Body.Message), tea.StringValue(resp.Body.RequestId))
|
|
}
|
|
return nil
|
|
}
|