Хэллоуин — это время костюмов, конфет и, конечно же, легких розыгрышей. И что может быть лучше, чем отправить друзьям и знакомым жуткие автоматические звонки со страшными аудиосообщениями? В этой статье рассмотрим, как с помощью 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/
Добавить комментарий