package services import ( "bytes" "encoding/base64" "encoding/json" "fmt" "io" "net/http" "time" "github.com/sujit-baniya/fiber-boilerplate/pkg/models" ) const websmsAPIBase = "https://api.labsmobile.com/json/send" type WebSmsRequest struct { Message string `json:"message"` TPOA string `json:"tpoa,omitempty"` Recipient []WebSmsRecipient `json:"recipient"` } type WebSmsRecipient struct { MSISDN string `json:"msisdn"` } type WebSmsResponse struct { Code string `json:"code"` Message string `json:"message"` ID string `json:"id"` SubID string `json:"subid"` } func (r *WebSmsResponse) MsgID() string { if r.ID != "" { return r.ID } return r.SubID } type WebSmsAckPayload struct { ID string `json:"id"` Reference string `json:"reference"` Status string `json:"status"` Msisdn string `json:"msisdn"` Substatus string `json:"substatus"` Timestamp string `json:"timestamp"` } type WebSmsClickPayload struct { ID string `json:"id"` Reference string `json:"reference"` Msisdn string `json:"msisdn"` URL string `json:"url"` Timestamp string `json:"timestamp"` } type WebSmsIncomingPayload struct { ID string `json:"id"` Msisdn string `json:"msisdn"` Message string `json:"message"` Shortcode string `json:"shortcode"` Timestamp string `json:"timestamp"` } func SendWebSms(cfg *models.WebSmsConfig, para, mensaje string) (*WebSmsResponse, error) { auth := base64.StdEncoding.EncodeToString([]byte(cfg.Username + ":" + cfg.ApiToken)) req := WebSmsRequest{ Message: mensaje, Recipient: []WebSmsRecipient{{MSISDN: para}}, } if cfg.Sender != "" { req.TPOA = cfg.Sender } body, err := json.Marshal(req) if err != nil { return nil, fmt.Errorf("websms: marshal: %w", err) } httpReq, err := http.NewRequest("POST", websmsAPIBase, bytes.NewReader(body)) if err != nil { return nil, err } httpReq.Header.Set("Authorization", "Basic "+auth) httpReq.Header.Set("Content-Type", "application/json") httpReq.Header.Set("Accept", "application/json") client := &http.Client{Timeout: 15 * time.Second} resp, err := client.Do(httpReq) if err != nil { return nil, fmt.Errorf("websms: http: %w", err) } defer resp.Body.Close() respBody, _ := io.ReadAll(resp.Body) if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusAccepted { return nil, fmt.Errorf("websms API status %d: %s", resp.StatusCode, string(respBody)) } ct := resp.Header.Get("Content-Type") var result WebSmsResponse if err := json.Unmarshal(respBody, &result); err != nil { return nil, fmt.Errorf("websms: respuesta no JSON (Content-Type: %s, cuerpo: %.200s)", ct, string(respBody)) } if result.Code != "0" { return nil, fmt.Errorf("websms: %s (code %s)", result.Message, result.Code) } return &result, nil }