scan-flow step 9: real SMS via SMSGlobal HTTP API (smshttp sender, proven live OK:0) + docs
This commit is contained in:
57
frontend/internal/sms/smshttp.go
Normal file
57
frontend/internal/sms/smshttp.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package sms
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// HTTPClient sends SMS via the SMSGlobal HTTP API (api.smsglobal.com/http-api.php).
|
||||
// This is the PROVEN path — validated live 2026-08-05 with real credentials
|
||||
// (response: OK: 0; Sent queued message ID ...). Matches the 2014 WhereWoof
|
||||
// integration pattern: action=sendsms, user/password, from, userfield, to, text.
|
||||
type HTTPClient struct {
|
||||
user string
|
||||
password string
|
||||
from string // verified number or sender, international format without '+'
|
||||
http *http.Client
|
||||
}
|
||||
|
||||
// NewHTTP returns an HTTP-API client. from is required (verified number or
|
||||
// registered sender, e.g. "61423274487").
|
||||
func NewHTTP(user, password, from string) *HTTPClient {
|
||||
return &HTTPClient{
|
||||
user: user,
|
||||
password: password,
|
||||
from: from,
|
||||
http: &http.Client{Timeout: 15 * time.Second},
|
||||
}
|
||||
}
|
||||
|
||||
// Send posts a message to the destination (international format, no '+').
|
||||
func (c *HTTPClient) Send(to, body string) error {
|
||||
form := url.Values{}
|
||||
form.Set("action", "sendsms")
|
||||
form.Set("user", c.user)
|
||||
form.Set("password", c.password)
|
||||
form.Set("from", c.from)
|
||||
form.Set("userfield", fmt.Sprintf("MID%sWSIDwherewoof", time.Now().UTC().Format("20060102150405")))
|
||||
form.Set("to", to)
|
||||
form.Set("text", body)
|
||||
form.Set("maxsplit", "5")
|
||||
|
||||
resp, err := c.http.PostForm("https://api.smsglobal.com/http-api.php", form)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
b, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
|
||||
s := strings.TrimSpace(string(b))
|
||||
if !strings.HasPrefix(s, "OK:") {
|
||||
return fmt.Errorf("smsglobal http: %s", s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user