【问题标题】:How do I use set up Twilio in my application to automatically send a text to a number?如何在我的应用程序中使用设置 Twilio 自动向号码发送文本?
【发布时间】:2016-02-17 00:06:33
【问题描述】:

我有一个 Ruby on Rails 应用程序,用户在其中创建一个“提醒”,一旦创建并保存到数据库 (POSTGRESQL),用户在制作提醒时输入的数字应该发短信(通过创建一个使用 Twilio 的 REST API 的消息)。我的 Twilio 凭据是正确的,并且我的环境变量已在应用程序中正确设置。

显然正在创建提醒(在控制台中看到 rails s 之后),但我根本没有收到短信,我想知道这是否与我的 reminder.rb 中的语法有关:

class Reminder < ActiveRecord::Base
  validates :title, presence: true
  validates :phone_number, presence: true
  validates :time, presence: true
  belongs_to :user

  after_create :send_text_message

  @@SEND_TEXT_MESSAGE_TIME = 5.minutes

  def send_text_message
    @twilio_phone_number = ENV['TWILIO_PHONE_NUMBER']
    @twilio_client = Twilio::REST::Client.new ENV['TWILIO_ACCOUNT_SID'], ENV['TWILIO_AUTH_TOKEN']
    # %k: 24hr time, %M: minute, %p: AM/PM, %b: e.g. "Jan", %d: zero padded day of the month e.g. "01"
    numba = "+1"+self.phone_number
    time_str = ((self.time).localtime).strftime("%k:%M%p on %b. %d")
    body = "Hi. Just a reminder that #{self.title} is coming up at #{time_str}."
    message = @twilio_client.account.sms.messages.create(
      :from => @twilio_phone_number,
      :to => numba,
      :body => body,
      )
    puts message
  end

  def when_to_run
    time - @@SEND_TEXT_MESSAGE_TIME
  end

  handle_asynchronously :send_text_message, :run_at => Proc.new { |i| i.when_to_run }
end

用户提交的表单在这里:

<%= simple_form_for [@user,@reminder] do |f| %>
  <% if @reminder.errors.any? %>
    <div id="error_expl" class="panel panel-danger">
      <div class="panel-heading">
        <h3 class="panel-title"><%= pluralize(@reminder.errors.count, "error") %> prohibited this reminder from being saved:</h3>
      </div>
      <div class="panel-body">
        <ul>
        <% @reminder.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
        </ul>
      </div>
    </div>
  <% end %>

  <%= f.input :title , class: "form-control"%>
  <%= f.input :phone_number, class: "form-control", input_html: { value: current_user.phone_number } %>
  <%= f.input :time, class: "form-control" %>
  <%= f.submit nil, :class => "btn btn-primary" %>
  <%= link_to 'Cancel', user_reminders_path(current_user), class: "btn btn-danger" %>
<% end %>

最后,我的reminders_controller.rb

class RemindersController < ApplicationController

  def index
    @user = User.find_by_id params[:user_id]
    @reminders = @user.reminders
    if @reminders.length == 0
      flash[:notice] = 'You have no reminders scheduled. Create one now to get started.'
    end
  end

  def new
    @user = User.find_by_id params[:user_id]
    @reminder = @user.reminders.new
  end

  def create
    # Time.zone = reminder_params[:time_zone]
    @user = current_user
    @reminder = @user.reminders.build reminder_params

    respond_to do |format|
      if @reminder.save
        flash[:success] = 'Reminder was created successfully!'
        format.html {
          redirect_to user_reminders_path
        }
      else
        flash.now[:notice] = 'Reminder could not be created. Please try again.'
        format.html {
          render :new 
        }
        format.json {
          render json: @reminder.errors.full_messages
        }
      end
    end
  end

  def show
    @reminder = Reminder.find(params[:id])
  end

  def edit
    @reminder = Reminder.find(params[:id])
  end

  def update
   @reminder = Reminder.find(params[:id])
   @reminder.user_id = current_user.id
    respond_to do |format|
      if @reminder.update_attributes(reminder_params)
        flash[:success] = 'Reminder has been successfully updated.'
        format.html {
          redirect_to user_reminders_path(current_user)
        }
        format.json {
          render json: @reminder
        }
      else
        flash[:error] = 'Reminder could not be updated.'
        format.html {
          redirect_to edit_reminder_path
        }
        format.json {
          render json: @reminder.errors.full_messages
        }
      end
    end
  end

  def destroy
    @reminder = Reminder.find(params[:id])
    @reminder.destroy
    respond_to do |format|
      format.html { redirect_to user_reminders_path(current_user.id), notice: 'reminder was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private

  def reminder_params
    params.require(:reminder).permit(:title, :time, :phone_number)
  end
end

我错过了什么吗?我是 Rails 新手,更习惯于 MEAN 堆栈,所以我认为可能是我对变量和 self 关键字的使用让我搞砸了。我正在寻找有关我可以做什么或修复的任何建议,以使来自 Twilio 的 REST API 的消息资源向我输入的数字发送文本。

【问题讨论】:

  • 快速提问,您使用的是实时还是测试 Twilio 凭据?我问如果您使用测试凭据,将不会发送 b/c 短信。假设您使用的是实时凭据并且 Twilio 不是问题,我建议您注释掉您的 handle_asynchronously 行,因为delayed_job 会使这更难调试。 Pry(它是一个 Ruby gem)是解决此类问题的绝佳方法。将其添加到您的 Gemfile 后,您可以在 Twilio 创建调用后立即粘贴 binding.pry。这将帮助您验证您是否正在使用该方法并让您检查消息变量。
  • 凭据不是问题。我现在收到@philnash 关于已弃用代码的建议的消息,但我必须不使用延迟作业。

标签: ruby-on-rails ruby postgresql api twilio


【解决方案1】:

这里是 Twilio 开发者宣传员。

@ajporterfield 提出了一些很好的建议,请确保您使用的是实时而非测试凭据,并尝试在不延迟方法的情况下完成这项工作。

我还有几个问题。你是running the delayed job process 来处理这些工作吗?

你有upgraded your account吗?如果您仍在使用免费的 Twilio 帐户,则需要确保您发送消息的所有号码都在您的帐户中得到验证。升级帐户后,您可以向任何号码发送消息。

最后,一个建议:您目前正在拨打@twilio_client.account.sms.messages.create。 API 中的sms.messages 端点实际上现在已被弃用,因此最好只调用messages。另外,为方便起见,如果您使用的是主账户,您也不需要拨打account。因此,您实际上可以将该行缩短为:@twilio_client.messages.create,它会更好地工作并且看起来更整洁。

让我知道这是否有帮助。

【讨论】:

  • 通过缩短我的线路到@twilio_client.messages.create,我终于收到了短信。但是,我不得不注释掉 when_to_runhandle_asynchronously 方法。我注意到,在创建提醒后,成功的 POST 会使浏览器多挂半秒。
  • 好的,那么你之前测试这个时是否运行了delayed_job 任务运行器?
  • 是的,我是。但是随着 POST 请求的缩短和延迟作业的运行,我没有收到消息。
  • POST 请求更短,因为您只是保存作业而不是调用 Twilio API。因此,您遇到的问题似乎与延迟工作的工作方式有关。您可以返回handle_asynchronously 命令,但忽略:run_at 选项,看看会发生什么?
  • 只注释掉:run_at 及以后?
猜你喜欢
  • 1970-01-01
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 2015-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多