Как создать систему страшных звонков на Хэллоуин на Go и Exolve Voice API

от автора

Хэллоуин — это время костюмов, конфет и, конечно же, легких розыгрышей. И что может быть лучше, чем отправить друзьям и знакомым жуткие автоматические звонки со страшными аудиосообщениями? В этой статье рассмотрим, как с помощью Exolve Voice API и Go можно создать систему для отправки пугающих звонков.

Что нам потребуется

  • API-ключ Exolve API (зарегистрируйтесь на Exolve).

  • Go.

  • Аудиофайлы для создания звонков (например, звук дыхания, шепот или страшные голоса). Скачать их можно здесь и дополнить своим голосом

  • Список номеров телефонов, на которые мы будем отправлять звонки.

Подготовка проекта

Создаем новый проект Go, инициализируем его и устанавливаем зависимости. Для начала определим структуру файлов проекта:

spooky_calls/ ├── audio.go          # Логика работы с аудиофайлами ├── voice_message.go  # Работа с Exolve Voice API ├── worker.go         # Логика многопоточной обработки звонков ├── main.go           # Основной файл программы ├── .env              # Файл с переменными окружения

Инициализируем проект и устанавливаем зависимости:

mkdir spooky_calls cd spooky_calls go mod init spooky_calls go get github.com/joho/godotenv

Создаем файл .env для хранения переменных окружения:

touch .env

Добавляем в файл .env следующие строки:

EXOLVE_API_KEY="api_key" SENDER="номер_выданный_exolve"

Загрузка аудиофайлов

Прежде чем двигаться дальше, загрузите свои жуткие аудиофайлы в личный кабинет Exolve. При загрузке аудио в библиотеку на выходе клиент получает resource_id. Этот resource_id и будем использовать при создании голосового сообщения — передавать значение в параметре media_id Эти идентификаторы мы будем использовать для выбора случайных аудиофайлов при отправке звонков.

Логика выбора аудиофайла

Теперь создаем файл audio.go, где реализуем логику случайного выбора аудиофайла из списка загруженных:

package main  import (     "math/rand"     "time" )  // Структура для хранения информации об аудиофайле type AudioFile struct {     ID   string     Name string }  // Функция для случайного выбора аудиофайла func randomAudioClip() AudioFile {     rand.Seed(time.Now().UnixNano())     audioFiles := []AudioFile{         {ID: "1967", Name: "Шепот призрака"},         {ID: "1968", Name: "Крик из бездны"},         {ID: "1969", Name: "Скрежет костей"},     }     return audioFiles[rand.Intn(len(audioFiles))] }

Задаем несколько аудиофайлов и случайным образом выбираем один из них для каждого звонка. Файл содержит идентификатор media_id, который мы получили при загрузке аудиофайлов.

Работа с Voice API

Создадим файл voice_message.go, в котором опишем отправку голосового сообщения через Exolve Voice API:

package main  import (     "bytes"     "encoding/json"     "fmt"     "net/http"     "os" )  // Структура для запроса к Voice API type VoiceRequest struct {     Source      string `json:"source"`     Destination string `json:"destination"`     ServiceID   string `json:"service_id"` }  // Функция отправки голосового сообщения func sendVoiceCall(apiKey, source, destination, serviceID string) error {     client := &http.Client{}     voiceURL := "https://api.exolve.ru/call/v1/MakeVoiceMessage"      voiceData := VoiceRequest{         Source:      source,         Destination: destination,         ServiceID:   serviceID,     }      jsonData, err := json.Marshal(voiceData)     if err != nil {         return fmt.Errorf("Ошибка сериализации данных: %w", err)     }      req, err := http.NewRequest("POST", voiceURL, bytes.NewBuffer(jsonData))     if err != nil {         return fmt.Errorf("Ошибка создания запроса: %w", err)     }      req.Header.Set("Authorization", "Bearer "+apiKey)     req.Header.Set("Content-Type", "application/json")      resp, err := client.Do(req)     if err != nil {         return fmt.Errorf("Ошибка отправки запроса: %w", err)     }     defer resp.Body.Close()      if resp.StatusCode == http.StatusOK {         fmt.Println("Звонок успешно отправлен")     } else {         return fmt.Errorf("Неожиданный код ответа: %d", resp.StatusCode)     }     return nil }

Код создает HTTP-запрос к API, отправляя данные о номере отправителя, получателя и идентификаторе аудиофайла.

Многопоточная отправка звонков

Для работы с большим количеством номеров воспользуемся многопоточностью. Создаем файл worker.go, где опишем логику обработки очереди номеров:

package main  import (     "log" )  func sendWithQueue(apiKey string, recipients []string, sender string) {     maxWorkers := 3 // Количество одновременных потоков     jobs := make(chan string, len(recipients))     results := make(chan error, len(recipients))      // Запуск воркеров     for w := 1; w <= maxWorkers; w++ {         go worker(apiKey, sender, jobs, results)     }      // Передача номеров в очередь     for _, recipient := range recipients {         jobs <- recipient     }     close(jobs)      // Обработка результатов     for r := 1; r <= len(recipients); r++ {         err := <-results         if err != nil {             log.Println("Ошибка:", err)         } else {             log.Println("Звонок успешно отправлен")         }     } }  // Логика воркеров для параллельной обработки func worker(apiKey string, sender string, jobs <-chan string, results chan <- error) {     for recipient := range jobs {         audioFile := randomAudioClip() // Случайный выбор аудиофайла         err := sendVoiceCall(apiKey, sender, recipient, audioFile.ID)         results <- err     } }

В этом модуле используем систему очередей и запускаем несколько потоков для одновременной обработки запросов. Таким образом, можно параллельно отправлять звонки.

Основная функция

Теперь, когда все части готовы, объединяем их в основной функции программы:

package main  import (     "log"     "os"     "github.com/joho/godotenv" )  func init() {     // Загружаем переменные окружения     err := godotenv.Load(".env")     if err != nil {         log.Fatal("Ошибка загрузки файла .env")     }     log.Println("Переменные окружения загружены") }  func main() {     apiKey := os.Getenv("EXOLVE_API_KEY")     sender := os.Getenv("SENDER")      recipients := []string{         "79991112233",         "79992223344",         "79993334455",     }      // Запуск массовой рассылки     sendWithQueue(apiKey, recipients, sender) }

Здесь загружаем переменные окружения и запускаем рассылку звонков с помощью функции sendWithQueue.


Заключение

Вот и всё! Теперь ваши друзья точно не забудут этот Хэллоуин.

А самое классное — этот проект легко модифицируется. Хотите вместо жутких криков отправлять рассылки с напоминаниями? Или продвигать акции, а может, отправлять персонализированные поздравления на Новый год? Пожалуйста! Просто замените аудиофайлы и немного адаптируйте логику с помощью API — всё в ваших руках.

Удачи в разработке, и не забывайте — шутки должны быть добрыми!


ссылка на оригинал статьи https://habr.com/ru/articles/853952/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *