【问题标题】:Schedule SMS for later date with Twilio + rails使用 Twilio + rails 为以后安排 SMS
【发布时间】:2013-12-08 21:34:26
【问题描述】:

我想现在或在特定时间使用 Twilio + Rails 发送 SMS,但我不确定最佳实践方法。我认为 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" 

文本消息.rb

class TextMessage < ActiveRecord::Base
  attr_accessible :body, :from, :to, :scheduled_date

end

现在,如果您填写表格,它会将短信发送到您输入的任何参数。我在下一步的设计方面遇到了麻烦。

这是我的想法

  • 控制器中的before_filter 用于检查:scheduled_date 是否为nil。
  • 如果为 nil,则立即发送,如果不发送到调度程序(?)

问题

  • 这实际上似乎并没有创建一个短信对象,它只是发送短信
  • 我不确定下一步会是怎样的优雅。

目标

  • 允许某人在表格中立即发送或在指定时间发送短信

问题

  • 下一步有什么好的实施方法?

**更新**

这是我根据调度程序建议更新的控制器/表单代码,我希望这是我的解决方案。

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 %> 

【问题讨论】:

    标签: ruby-on-rails twilio


    【解决方案1】:

    我会尽量避免现在或将来发送消息的逻辑不同。如果您不需要响应的任何部分(目前您不使用它做任何事情),那么最简单的方法就是在任何情况下将其移至后台。最大的优势是服务的响应时间和可用性对您网站的响应时间没有影响。

    在后台排队作业的一个好工具是 resque (https://github.com/resque/resque),它可以使用 resque-scheduler (https://github.com/resque/resque-scheduler) 进行扩展,以允许在将来的某个时间完成作业(而不仅仅是 Resque.enqueue然后,您将使用 Resque.enqueue_in 和/或 Resque.enqueue_at 将任务移动到队列中)。

    【讨论】:

      【解决方案2】:

      这是我目前正在使用的实现,我相信它可以改进。

      我添加了sidekiqredis 用于后台作业处理。这是我的 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 非常适合设置它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-04-21
        • 2018-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多