package sms import ( "context" "fmt" "net/http" "github.com/minchao/go-mitake" ) // MitakeSettings configures 三竹 Mitake SMS (ported from app-cloudep-notification-service). type MitakeSettings struct { Sort int User string Password string } // MitakeSender delivers SMS via Mitake SmExpress API. type MitakeSender struct { name string sort int client *mitake.Client } // NewMitakeSender builds a Mitake provider. func NewMitakeSender(cfg MitakeSettings, httpClient *http.Client) (*MitakeSender, error) { if cfg.User == "" || cfg.Password == "" { return nil, fmt.Errorf("sms mitake: user and password are required") } return &MitakeSender{ name: "mitake", sort: cfg.Sort, client: mitake.NewClient(cfg.User, cfg.Password, httpClient), }, nil } func (m *MitakeSender) Name() string { return m.name } func (m *MitakeSender) Sort() int { return m.sort } func (m *MitakeSender) Send(ctx context.Context, msg *Message) (string, error) { if err := ctx.Err(); err != nil { return "", err } if msg == nil || msg.PhoneNumber == "" { return "", fmt.Errorf("sms mitake: phone number is required") } if msg.Body == "" { return "", fmt.Errorf("sms mitake: body is required") } // SDK has no context support; check before the HTTP call. if err := ctx.Err(); err != nil { return "", err } resp, err := m.client.Send(mitake.Message{ Dstaddr: msg.PhoneNumber, Destname: msg.RecipientName, Smbody: msg.Body, }) if err != nil { return "", fmt.Errorf("sms mitake: %w", err) } if resp == nil || len(resp.Results) == 0 { return "", fmt.Errorf("sms mitake: empty response") } r := resp.Results[0] if err := mitakeStatusError(r.Statuscode); err != nil { return "", err } if r.Msgid == "" { return "", fmt.Errorf("sms mitake: empty msgid") } return r.Msgid, nil } func mitakeStatusError(code string) error { switch mitake.StatusCode(code) { case mitake.StatusReservationForDelivery, mitake.StatusCarrierAccepted, mitake.StatusCarrierAccepted2, mitake.StatusCarrierAccepted3, mitake.StatusDelivered: return nil default: return fmt.Errorf("sms mitake: status %s (%s)", code, mitake.StatusCode(code).String()) } }