ref(cmd/sendsms): separate http/androidsmsgateway into own package

This commit is contained in:
AJ ONeal 2026-02-27 02:29:17 -07:00
parent 6db9bd805d
commit 4176923dd8
No known key found for this signature in database
5 changed files with 55 additions and 28 deletions

View File

@ -1,5 +1,8 @@
module example.com/sendsms module example.com/sendsms
go 1.24.4 go 1.24.6
require github.com/joho/godotenv v1.5.1 require (
github.com/joho/godotenv v1.5.1
github.com/therootcompany/golib/http/androidsmsgateway v0.0.0-20260223054429-c8f26aca7c6d
)

View File

@ -1,2 +1,4 @@
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/therootcompany/golib/http/androidsmsgateway v0.0.0-20260223054429-c8f26aca7c6d h1:jKf9QQUiGAHsrjkfpoo4FTQnFJu4UkDkPreZLll7tdE=
github.com/therootcompany/golib/http/androidsmsgateway v0.0.0-20260223054429-c8f26aca7c6d/go.mod h1:2O9+uXPc1VAJvveK9eqm9X4e4pTJmFWV6vtJa3sI/CA=

View File

@ -16,6 +16,7 @@ import (
"time" "time"
"github.com/joho/godotenv" "github.com/joho/godotenv"
"github.com/therootcompany/golib/http/androidsmsgateway"
) )
type SMSSender interface { type SMSSender interface {
@ -31,16 +32,6 @@ type SMSMessage struct {
Text string Text string
} }
type TextMessage struct {
Text string `json:"text"`
}
type Payload struct {
TextMessage TextMessage `json:"textMessage"`
PhoneNumbers []string `json:"phoneNumbers"`
Priority int `json:"priority,omitempty"`
}
var ErrInvalidClockFormat = fmt.Errorf("invalid clock time, ex: '06:00 PM', '6pm', or '18:00' (space and case insensitive)") var ErrInvalidClockFormat = fmt.Errorf("invalid clock time, ex: '06:00 PM', '6pm', or '18:00' (space and case insensitive)")
var ErrInvalidClockTime = fmt.Errorf("invalid hour or minute, for example '27:63 p' would not be valid") var ErrInvalidClockTime = fmt.Errorf("invalid hour or minute, for example '27:63 p' would not be valid")
var ErrPhoneEmpty = fmt.Errorf("no phone number") var ErrPhoneEmpty = fmt.Errorf("no phone number")
@ -90,11 +81,11 @@ func main() {
_ = godotenv.Load("./.env") _ = godotenv.Load("./.env")
// note: we could also use twilio, or whatever // note: we could also use twilio, or whatever
var sender SMSSender = &SMSGatewayForAndroid{ var sender SMSSender = androidsmsgateway.New(
baseURL: os.Getenv("SMSGW_BASEURL"), os.Getenv("SMSGW_BASEURL"),
username: os.Getenv("SMSGW_USERNAME"), os.Getenv("SMSGW_USERNAME"),
password: os.Getenv("SMSGW_PASSWORD"), os.Getenv("SMSGW_PASSWORD"),
} )
if os.Getenv("SMSGW_BASEURL") == "" { if os.Getenv("SMSGW_BASEURL") == "" {
fmt.Fprintf(os.Stderr, "\n%sError%s: SMSGW_BASEURL is not set\n", textErr, textReset) fmt.Fprintf(os.Stderr, "\n%sError%s: SMSGW_BASEURL is not set\n", textErr, textReset)
os.Exit(1) os.Exit(1)

View File

@ -1,4 +1,4 @@
package main package androidsmsgateway
import ( import (
"bytes" "bytes"
@ -9,24 +9,36 @@ import (
"strings" "strings"
) )
type SMSGatewayForAndroid struct { type AndroidSMSGateway struct {
baseURL string baseURL string
username string username string
password string password string
} }
func New(baseURL, username, password string) *SMSGatewayForAndroid { func New(baseURL, username, password string) *AndroidSMSGateway {
return &SMSGatewayForAndroid{ return &AndroidSMSGateway{
baseURL: baseURL, baseURL: baseURL,
username: username, username: username,
password: password, password: password,
} }
} }
func (s *SMSGatewayForAndroid) CurlString(number, message string) string { type MessagePayload struct {
TextMessage struct {
Text string `json:"text"`
} `json:"textMessage"`
PhoneNumbers []string `json:"phoneNumbers"`
Priority int `json:"priority,omitempty"`
}
func (s *AndroidSMSGateway) CurlString(number, message string) string {
url := s.baseURL + "/messages" url := s.baseURL + "/messages"
payload := Payload{ payload := MessagePayload{
TextMessage: TextMessage{Text: message}, TextMessage: struct {
Text string `json:"text"`
}{
Text: message,
},
PhoneNumbers: []string{number}, PhoneNumbers: []string{number},
Priority: 65, Priority: 65,
} }
@ -42,15 +54,19 @@ func (s *SMSGatewayForAndroid) CurlString(number, message string) string {
" --data-binary '" + escapedBody + "'" " --data-binary '" + escapedBody + "'"
} }
func (s *SMSGatewayForAndroid) Send(number, message string) error { func (s *AndroidSMSGateway) Send(number, message string) error {
number = cleanPhoneNumber(number) number = cleanPhoneNumber(number)
if len(number) == 0 { if len(number) == 0 {
panic(fmt.Errorf("non-sanitized number '%s'", number)) panic(fmt.Errorf("non-sanitized number '%s'", number))
} }
url := s.baseURL + "/messages" url := s.baseURL + "/messages"
payload := Payload{ payload := MessagePayload{
TextMessage: TextMessage{Text: message}, TextMessage: struct {
Text string `json:"text"`
}{
Text: message,
},
PhoneNumbers: []string{number}, PhoneNumbers: []string{number},
Priority: 65, Priority: 65,
} }
@ -75,10 +91,22 @@ func (s *SMSGatewayForAndroid) Send(number, message string) error {
if resp.StatusCode < 200 || resp.StatusCode >= 300 { if resp.StatusCode < 200 || resp.StatusCode >= 300 {
body, _ := io.ReadAll(resp.Body) body, _ := io.ReadAll(resp.Body)
return fmt.Errorf("failed sending message to '%s': %d %s\n", return fmt.Errorf("failed sending message to '%s': %d %s",
number, resp.StatusCode, string(body), number, resp.StatusCode, string(body),
) )
} }
return nil return nil
} }
// we're not just skipping symbols,
// we're also eliminating non-printing characters copied from HTML and such
func cleanPhoneNumber(raw string) string {
var cleaned strings.Builder
for i, char := range raw {
if (i == 0 && char == '+') || (char >= '0' && char <= '9') {
cleaned.WriteRune(char)
}
}
return cleaned.String()
}

View File

@ -0,0 +1,3 @@
module github.com/therootcompany/golib/http/androidsmsgateway
go 1.24.6