Отправка SMS на Go (Golang): API библиотеки golang-sms

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Отправка 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                    

Рекомендаций