Twilio Evangelist здесь.
Мне нравится подходить к этому с Redis рабочими очередями.Redis - это хранилище ключей-значений, которое мы можем использовать с Resque (произносится «спасение») и Resque-Scheduler , чтобы обеспечить механизм организации очередей.Например, мы можем заставить приложение реагировать на взаимодействие с пользователем, создавая вызов с использованием Twilio REST API .Затем мы можем поставить рабочую задачу в очередь, которая будет что-то делать с вызовом через определенное время.Здесь я просто собираюсь получить статус вызова через несколько секунд (вместо ожидания обратного вызова статуса после завершения вызова).
У Heroku действительно хорошее прохождениепри использовании Resque также имеется превосходный эпизод Casts Rails на Resque with Rails. дополнение к данным доступно от Heroku под названием Reddis Cloud для предоставления сервера Redis.Хотя для разработки я запускаю локальный сервер на своем компьютере.
Я создал простое приложение, основанное на учебнике Heroku и эпизоде Rails Casts.Он имеет один контроллер и одну модель.Я использую callback на модели для создания исходящего вызова Twilio.Таким образом, когда создается новая запись Call
, мы инициируем исходящий вызов Twilio:
class Call < ActiveRecord::Base
# Twilio functionality is in a concern...
include TwilioDialable
after_create do |call|
call.call_sid = initiate_outbound call.to,
call.from,
"http://example.com/controller/action"
call.save
call
end
end
Я использую задачу для инициирования вызова, так как я могу захотеть сделать это из разных меств моем приложении:
module TwilioDialable
extend ActiveSupport::Concern
include Twilio::REST
def initiate_outbound to, from, url
client = Twilio::REST::Client.new ENV['TW_SID'], ENV['TW_TOKEN']
client.account.calls.create(to: to, from: from, url: url).sid
end
end
Это просто создает исходящий вызов Twilio и возвращает SID вызова, чтобы я мог обновить свою модель.
Теперь, когда вызов выполнен, поэтому я хочупроверить его статус.Но поскольку мы хотим, чтобы звонок сначала прозвенел немного, мы проверим его через 15 секунд.В моем контроллере я использую метод Resque.enqueue_in
из Resque-Scheduler для управления временем для меня:
Resque.enqueue_in(15.seconds, MessageWorker, :call => @call.id)
Это дает команду Resque ждать 15 секунд перед выполнением задачи.Он ожидает вызова рабочего класса Resque с именем MessageWorker
и передаст хеш с параметрами: {:call => @call.id}
.Чтобы убедиться, что это происходит вовремя, я установил RESQUE_SCHEDULER_INTERVAL
на 0,1 секунды, так что это будет очень точно.Сам MessageWorker
довольно прост, он находит запись о вызове и использует SID вызова, чтобы получить обновленный статус и сохранить его в базе данных:
class MessageWorker
@queue = :message_queue
def self.perform params
# Get the call ID to do some work with...
call = Call.find(params["call"])
# Setup a Twilio Client Helper with credentials form the Environment...
client = Twilio::REST::Client.new ENV['TW_SID'], ENV['TW_TOKEN']
# We could get some
status = client.account.calls.get(call.call_sid).status
# Update my call object.
call.status = status
end
end
Когда я запускал это локально, мне приходилось запускатьсервер Redis, задача rake Redis Worker, задача rake Schedule Redis, и я использую Foreman и Unicorn для запуска приложения Rails.Вы можете настроить все это в свой Procfile для работы на Heroku.Учебное пособие по по Heroku - отличное руководство по настройке.
Но теперь я могу создать звонок и заставить его дозвониться до телефона.В то же время я могу обновить страницу calls/show/:id
и увидеть магически обновленное значение, когда рабочий процесс запускается через 15 секунд.
Я также считаю, что resque-web
действительно полезнодля отладки Resque, поскольку с его помощью действительно легко увидеть, что происходит с вашими задачами.
Надеюсь, это поможет!