Envio de SMS em Go (Golang): Biblioteca de API para trabalhar com gateways de SMS
No desenvolvimento web moderno, o envio de mensagens SMS continua sendo uma funcionalidade muito requisitada: autenticação de dois fatores, notificações, campanhas de marketing. A linguagem Go (Golang), graças ao seu desempenho e simplicidade, é ideal para criar microsserviços responsáveis pelo envio de mensagens. Neste artigo, vamos analisar como se conectar a um gateway de SMS via API, usando a biblioteca padrão net/http e pacotes populares para trabalhar com requisições HTTP.
Escolha da abordagem: biblioteca padrão vs frameworks
O Go oferece uma biblioteca padrão poderosa, suficiente para trabalhar com qualquer API REST. Para enviar SMS, não é necessário instalar frameworks pesados — o pacote embutido net/http já é suficiente. No entanto, para maior comodidade, também veremos o uso da biblioteca resty, que simplifica a criação de requisições.
Estrutura básica de uma requisição HTTP em Go
Qualquer gateway de SMS aceita uma requisição POST com corpo em JSON. Vejamos um exemplo de envio de mensagem através de um serviço hipotético sms-provider.com:
package main
import ( "bytes" "encoding/json" "fmt" "io/ioutil" "net/http" "time")
type SMSRequest struct { Phone string `json:"phone"` Message string `json:"message"` APIKey string `json:"api_key"`}
type SMSResponse struct { Status string `json:"status"` Message string `json:"message"`}
func sendSMS(phone, message, apiKey string) (*SMSResponse, error) { url := "https://api.sms-provider.com/v1/send"
reqBody := SMSRequest{ Phone: phone, Message: message, APIKey: apiKey, }
jsonData, err := json.Marshal(reqBody) if err != nil { return nil, fmt.Errorf("erro de serialização JSON: %w", err) }
client := &http.Client{Timeout: 10 * time.Second} resp, err := client.Post(url, "application/json", bytes.NewBuffer(jsonData)) if err != nil { return nil, fmt.Errorf("erro na requisição HTTP: %w", err) } defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("erro ao ler a resposta: %w", err) }
var smsResp SMSResponse if err := json.Unmarshal(body, &smsResp); err != nil { return nil, fmt.Errorf("erro ao analisar a resposta: %w", err) }
return &smsResp, nil}
func main() { resp, err := sendSMS("+79123456789", "Mensagem de teste", "your-api-key-123") if err != nil { fmt.Printf("Erro: %v", err) return } fmt.Printf("Status: %s, Mensagem: %s", resp.Status, resp.Message)}Usando a biblioteca resty para simplificar o código
A biblioteca go-resty/resty/v2 reduz significativamente a quantidade de código boilerplate. Instalação:
go get github.com/go-resty/resty/v2Exemplo de envio de SMS com resty:
package main
import ( "fmt" "github.com/go-resty/resty/v2")
type SMSResponse struct { Status string `json:"status"` Message string `json:"message"`}
func sendSMSResty(phone, message, apiKey string) (*SMSResponse, error) { client := resty.New() resp, err := client.R(). SetHeader("Content-Type", "application/json"). SetBody(map[string]interface{}{ "phone": phone, "message": message, "api_key": apiKey, }). SetResult(&SMSResponse{}). Post("https://api.sms-provider.com/v1/send")
if err != nil { return nil, fmt.Errorf("erro na requisição: %w", err) }
return resp.Result().(*SMSResponse), nil}
func main() { resp, err := sendSMSResty("+79123456789", "Olá do Go!", "my-secret-key") if err != nil { fmt.Prin