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 }