Если вы читали мою статью о том, как отправлять SMS-сообщения с помощью Go, то знаете, что я провел 2014 год, изучая Go и получая от этого огромное удовольствие. Мой последний проект включал использование Go для создания и приема телефонных звонков с помощью Twilio. Одним из лучших моментов в работе над этим проектом было то, что мне пришлось научиться создавать базовый веб-сервер на Go. В этой статье я покажу вам, что я узнал, и вскоре вы тоже сможете создавать и принимать телефонные звонки из своих приложений на Go.
— Go, запущенный на вашем локальном компьютере
— Аккаунт Twilio – зарегистрируйтесь бесплатно!
— Ngrok для открытия вашего localhost для Twilio
Когда пользователь совершает звонок на ваш номер телефона Twilio, мы просим ваш сервер предоставить некоторые базовые инструкции о том, что делать с этим звонком. Чтобы сделать это с помощью Go, нам нужно настроить базовый веб-сервер. К счастью, библиотека net/http в Go делает это очень легко.
Запустите ваш любимый текстовый редактор и создайте новый файл под названием main.go. Мы начнем с объявления нашего пакета и импорта пакета net/http:
Теперь мы напишем код, который слушает запрос к определенному маршруту и отвечает некоторым простым текстом:
Мы создаем новую функцию под названием main. Наша функция main будет вызвана, когда我们的 приложение запустится. Внутри этой функции мы вызываем http.HandleFunc. http.HandleFunc принимает два аргумента – маршрут, на который вы хотите слушать, и имя функции. Если вы задаетесь вопросом, почему я использую слово twiml здесь, не волнуйтесь, это станет ясно скоро. Далее мы вызываем http.ListenAndServe, чтобы запустить наш сервер. Мы передаем :3000, чтобы слушать на порту 3000.
Далее у нас есть функция twiml, которую мы сказали, что будем использовать для ответа на запросы к /twiml. В этом случае мы используем http.ResponseWriter, чтобы напечатать текст «Hello World!». Давайте запустим наше приложение, чтобы убедиться, что этот код работает:
Теперь перейдите по адресу localhost:3000/twiml, и вы должны увидеть «Hello World!» в вашем браузере.
Теперь, когда у нас есть базовый веб-сервер, мы можем начать строить ответ, который Twilio сможет понять. Это то место, где вступает в силу TwiML. TwiML – это наш собственный подмножество XML, которое позволяет предоставить некоторые базовые инструкции для Twilio, которые он должен выполнить, когда поступает звонок или сообщение. Давайте обновим наш код, чтобы он отвечал на запросы к /twiml с помощью TwiML вместо простого текста.
Сначала нам нужно создать новый struct, который мы будем использовать для определения нашего TwiML. Мы можем сделать это сразу после наших импортов в main.go. Если вы не использовали символ обратной косой черты в течение долгого времени, вы можете найти его на вашей клавиатуре рядом с цифрой 1:
TwiML содержит многие различные глаголы, но в этом примере мы будем использовать глагол . Этот глагол позволяет использовать текст в речи, чтобы сказать что-то пользователю во время звонка. Внутри нашей структуры мы определяем строку под названием Say. Go имеет некоторые отличные инструменты для преобразования структур в XML, которые мы будем использовать. В нашей структуре мы определяем наше XMLName – это будет корневой тег, который он будет использовать, когда наша структура будет преобразована в XML. Мы также используем атрибут xml omitempty на нашем свойстве Say, чтобы убедиться, что мы не передаем никаких ненужных тегов в будущем. Чтобы воспользоваться преимуществами кодирования XML, нам нужно добавить пакет encoding/xml к нашим импортом:
Теперь мы можем обновить нашу функцию twiml, которую мы написали ранее, чтобы она отвечала XML:
Сначала мы создаем новый struct TwiML со значением Say «Hello World!». Затем мы вызываем xml.Marshal и передаем ему нашу структуру. Это попытается преобразовать нашу структуру в XML. Если возникает ошибка при этом преобразовании, мы отправляем http.Error. В противном случае мы хотим установить наш заголовок Content-Type в application/xml, чтобы Twilio знал, что мы отвечаем XML. Наконец, мы напишем фактический XML-контент, который мы сгенерировали.
Запустите наше приложение снова:
Перейдите по адресу localhost:3000/twiml, и вместо простого текста вы должны увидеть XML-ответ, который мы хотим дать Twilio.
Чтобы Twilio мог получить доступ к этому URL, нам нужно сделать его доступным извне. Одним из лучших инструментов для этого является ngrok. Если вы не работали с ngrok раньше, пусть мои хорошие друзья Kevin Whinnery и Bo Jackson покажут вам, как это сделать. Убедитесь, что вы зарегистрировались для бесплатного аккаунта, чтобы вы могли использовать флаг поддомена. Как только вы настроите ngrok, запустите его с помощью следующей команды:
Дайте этому номеру звонок и послушайте красивый роботизированный голос, говорящий «привет, мир».
Теперь, когда мы можем принимать звонок, давайте используем REST API Twilio, чтобы сделать звонок. Нам нужно написать код, который отправляет POST-запрос на ресурс Calls. Мы будем использовать несколько пакетов, чтобы сделать это, поэтому давайте начнем с добавления их к нашим импортом в начале файла:
Теперь мы можем создать новую функцию под названием call, где будет жить наш код, который отправляет POST-запрос. Мы начнем с некоторых переменных по умолчанию:
Мы устанавливаем наш accountSid и authToken Twilio – вы можете найти их на панели управления вашего аккаунта Twilio. Затем мы строим urlStr для ресурса Calls, куда мы будем отправлять POST-запрос.
Далее давайте установим данные, которые мы хотим использовать в нашем запросе:
Мы передаем 3 куска информации:
— To – номер телефона, на который вы хотите сделать звонок.
— From – номер телефона, с которого вы хотите звонить. Номер Twilio, который вы настроили ранее.
— Url – URL, который возвращает TwiML, инструктирующий Twilio, что делать, когда этот звонок соединится. Мы будем использовать тот же URL ngrok TwiML, который мы использовали для нашего исходящего звонка.
Наконец, давайте используем http.Client Go, чтобы отправить запрос:
Мы создаем новый запрос с методом POST, нашим urlStr в качестве места назначения и данными, которые мы установили ранее. Мы устанавливаем нашу аутентификацию и убедимся, что наши заголовки установлены правильно. Как только мы отправим запрос, мы подтверждаем, что получили 200, и если мы получили, парсим тело ответа с помощью json.Unmarshal.
Мы готовы сделать звонок кому-то и воспроизвести mp3. Давайте добавим новый маршрут к нашему веб-серверу, который мы будем использовать для запуска нашего звонка:
Теперь перейдите по адресу localhost:3000/call и подождите, пока ваш телефон зазвонит. Когда мы запустили этот запрос прямо сейчас, мы услышали наш роботизированный голос снова. Давайте обновим наш код, чтобы переключить TwiML на использование глагола для воспроизведения mp3. Сначала нам нужно добавить новое свойство Play в наш struct TwiML:
Теперь, когда у нас есть свойство Play, мы можем изменить нашу функцию twiml, чтобы она использовала его вместо Say:
Теперь перейдите по адресу localhost:3000/call снова. Если вы не изменили mp3-файл в моем примере, вы должны услышать великолепное сообщение из 1987 года. У вас возникли проблемы? Посмотрите на окончательный код здесь.
Теперь, когда у вас есть возможность создавать и принимать телефонные звонки из Go, что вы будете строить? Может быть, что-то простое, как будильник. Или что-то сложное, как IVR или call-центр. Что бы вы ни строили, я бы хотел увидеть это. Вы можете найти меня в Twitter или написать мне на электронную почту.