Отправка SMS на Go (Golang): API библиотеки для работы с SMS-шлюзами
В современной веб-разработке отправка SMS-сообщений остаётся востребованным функционалом: двухфакторная аутентификация, уведомления, маркетинговые рассылки. Язык Go (Golang) благодаря своей производительности и простоте идеально подходит для создания микросервисов, занимающихся отправкой сообщений. В этой статье мы разберём, как подключиться к SMS-шлюзу через API, используя стандартную библиотеку net/http и популярные пакеты для работы с HTTP-запросами.
Выбор подхода: стандартная библиотека vs фреймворки
Go предоставляет мощную стандартную библиотеку, которой достаточно для работы с любым REST API. Для отправки SMS не требуется устанавливать тяжелые фреймворки — достаточно встроенного пакета net/http. Однако для удобства мы также рассмотрим использование библиотеки resty, которая упрощает формирование запросов.
Базовая структура HTTP-запроса на Go
Любой SMS-шлюз принимает POST-запрос с JSON-телом. Рассмотрим пример отправки сообщения через гипотетический сервис 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("ошибка сериализации 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("ошибка HTTP-запроса: %w", err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("ошибка чтения ответа: %w", err)
}
var smsResp SMSResponse
if err := json.Unmarshal(body, &smsResp); err != nil {
return nil, fmt.Errorf("ошибка парсинга ответа: %w", err)
}
return &smsResp, nil
}
func main() {
resp, err := sendSMS("+79123456789", "Тестовое сообщение", "your-api-key-123")
if err != nil {
fmt.Printf("Ошибка: %v\n", err)
return
}
fmt.Printf("Статус: %s, Сообщение: %s\n", resp.Status, resp.Message)
}
Использование библиотеки resty для упрощения кода
Библиотека go-resty/resty/v2 значительно сокращает объём boilerplate-кода. Установка:
go get github.com/go-resty/resty/v2
Пример отправки SMS с 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("ошибка запроса: %w", err)
}
return resp.Result().(*SMSResponse), nil
}
func main() {
resp, err := sendSMSResty("+79123456789", "Привет из Go!", "my-secret-key")
if err != nil {
fmt.Printf("Ошибка: %v\n", err)
return
}
fmt.Printf("Ответ: %+v\n", resp)
}
Работа с популярными SMS-провайдерами
Каждый провайдер имеет свои особенности аутентификации. Рассмотрим два распространённых подхода:
1. Аутентификация через API-ключ в заголовке
client := resty.New()
resp, err := client.R().
SetHeader("X-API-Key", apiKey).
SetBody(smsData).
Post("https://api.provider.com/send")
2. Аутентификация через Bearer token (JWT)
client := resty.New()
resp, err := client.R().
Set Также в библиотеке
node-cache: Простое и эффективное кэширование в Node.js
Авторизация и аутентификация в C# (.NET): полное руководство
Обработка JSON в Go (Golang): encoding/json и альтернативы
HTTP-клиент для Go (Golang): топ библиотек для работы с HTTP
Работа с Excel в Kotlin: библиотеки Apache POI и Kotlin-обертки