我想使用Twilio + Rails现在或在特定时间发送短信,但我不确定最佳做法方法。我认为cron不适合这个。
我有一个简单的观点 -
<div>
<%= form_for @text_message, url: {action: "send_message"},
html: {role: "form", class: "form-horizontal" } do |f|%>
<%= f.text_field :from %>
<%= f.text_field :to %>
<%= f.text_area :body, class: 'text-input' %>
<div class="schedule-outer">
<a id="schedule-link">
<span>Schedule text for later?</span>
</a>
</div>
<div >
<%= f.datetime_select :scheduled_date, ampm: true, minute_step: 15, value: nil %> <br>
</div>
<%= f.submit "Send Text Message"%>
<% end %>
</div>
和相应的控制器 -
class TextMessagesController < ApplicationController
def new
@text_message = TextMessage.new
end
def send_message
number_to_send_to = params[:text_message][:to]
number_sent_from = params[:text_message][:from]
the_payload = params[:text_message][:body]
@twilio_client = Twilio::REST::Client.new(ENV['TWILIO_SID'], ENV['TWILIO_AUTH'])
@twilio_client.account.sms.messages.create(
from: "#{number_sent_from}",
to: "#{number_to_send_to}",
body: "#{the_payload}"
)
flash[:notice] = "Your text has been sent!"
redirect_to action: 'new'
end
end
的routes.rb
get 'text_messages/new', to: "text_messages#new"
post '/send_message' => "text_messages#send_message"
textmessage.rb
class TextMessage < ActiveRecord::Base
attr_accessible :body, :from, :to, :scheduled_date
end
现在,如果您填写表单,它会将短信发送到您输入的任何参数。我在设计方面遇到了下一步的麻烦。
以下是我的想法
before_filter
,用于检查:scheduled_date
是否为零。问题
目标
问题
这是我根据调度程序建议更新的控制器/表单代码,我希望这是我的解决方案。
class TextMessagesController < ApplicationController
def new
@text_message = TextMessage.new
end
def send_message
number_to_send_to = params[:text_message][:to]
number_sent_from = params[:text_message][:from]
the_payload = params[:text_message][:body]
@text_message = TextMessage.create(params[:text_message])
@twilio_client = Twilio::REST::Client.new(ENV['TWILIO_SID'], ENV['TWILIO_AUTH'])
if @text_message.scheduled_date == nil
@twilio_client.account.sms.messages.create(
from: "#{number_sent_from}",
to: "#{number_to_send_to}",
body: "#{the_payload}"
)
else
# add it to a scheduler
end
flash[:notice] = "Your text has been sent!"
redirect_to action: 'new'
end
end
表格
<%= f.datetime_select :scheduled_date, ampm: true, minute_step: 15, include_blank: true %>
答案 0 :(得分:1)
我会尽量避免为现在或将来发送的消息设置不同的逻辑。如果你不需要响应的任何部分(目前你没有对它做任何事情),那么最简单的方法是在任何情况下将它移动到后台。最大的好处是服务的响应时间和可用性对您网站的响应时间没有影响。
在后台排队作业的一个好工具是resque(https://github.com/resque/resque),它可以使用resque-scheduler(https://github.com/resque/resque-scheduler)进行扩展,以允许在将来的某个时间点完成作业(而不是只需Resque.enqueue,然后使用Resque.enqueue_in和/或Resque.enqueue_at将任务移动到队列中。
答案 1 :(得分:0)
这是我目前正在实施的实现,我相信它可以改进。
我添加了sidekiq和redis用于后台作业处理。这是我的twilio工作者
class TwilioWorker
include Sidekiq::Worker
sidekiq_options retry: false
def perform(text_message_id)
text_message = TextMessage.find(text_message_id)
number_to_send_to = text_message.to
number_sent_from = text_message.from
the_payload = text_message.body
@twilio_client = Twilio::REST::Client.new(ENV['TWILIO_SID'], ENV['TWILIO_AUTH'])
@twilio_client.account.sms.messages.create(
from: "#{number_sent_from}",
to: "#{number_to_send_to}",
body: "#{the_payload}"
)
end
end
这是我更新的text_messages_controller.rb
class TextMessagesController < ApplicationController
def new
@text_message = TextMessage.new
end
def send_message
@text_message = TextMessage.new(params[:text_message])
if @text_message.save
if @text_message.scheduled_date == nil
TwilioWorker.perform_async(@text_message.id)
elsif @text_message.scheduled_date != nil
time = ((@text_message.scheduled_date - @text_message.created_at) / 3600).round
TwilioWorker.perform_at(time.hours, @text_message.id)
else
flash[:notice] = "something went wrong"
end
else
redirect_to action: 'new'
end
end
end
rbates sidekiq railscast非常适合设置它。