ruby-on-railstwiliourlencodefaraday

How to send url-encoded form data using Faraday's post method?


I'm trying to setup Faraday to make requests to a Twilio API. I can make the requests via Postman setting up the key/values in the request body as x-www-form-urlencoded data.

When I try to replicate the cURL I make on Postman in Rails I get an error as if the key/value pairs I send in the payload are not recognized

The following cURL request works in Postman:

curl --location --request POST 'https://api.twilio.com/2010-04-01/Accounts/TOKEN1234/Messages.json' \
--header 'Authorization: Basic AUTH_TOKEN==' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'From=whatsapp:+5491112312312' \
--data-urlencode 'Body=Hello. Your order is on the way' \
--data-urlencode 'To=whatsapp:+541132132121'

My Faraday connector looks like this:

class Twilio::SubAccountConnector
  attr_reader :sid, :auth_token, :phone, :api_url

  def initialize(account)
    @sid = account.twilio_configuration.sid
    @auth_token = account.twilio_configuration.auth_token
    @phone = account.twilio_configuration.phone
    @api_url = "https://api.twilio.com/2010-04-01/Accounts/#{sid}/Messages.json"
  end

  def form_data
    {
      from: "whatsapp:+5491112312312",
      body: "Hello. Your order is on the way",
      to: "whatsapp:+541132132121",
    }
  end

  def send_whatsapp_notification
    connector.post do |req|
      req.body = form_data
    end
  end

  private

  def connector(url = api_url)
    Faraday.new(url: url) do |faraday|
      faraday.request :basic_auth, sid, auth_token
      faraday.request :url_encoded
      faraday.response :json
      faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
    end
  end
end

This is the request body in the Faraday request:

request_body=
    "{\"From\":\"whatsapp:+5491112312312\",\"Body\":\"Hello. Your order is on the way\",\"To\":\"whatsapp:+541132132121\"}"

I'm getting the following error in the response body, so I suppose I'm doing something wrong with the way I'm sending the payload as the key/value pairs are not recognized.

response_body={"code"=>21604, "message"=>"A 'To' phone number is required.", "more_info"=>"https://www.twilio.com/docs/errors/21604", "status"=>400}>

Am I missing something in the connector method so the payload is encoded correctly?


Solution

  • The issue is that the parameters should start with capital letters. Your Faraday request is otherwise correct, but your form_data method should look like:

      def form_data
        {
          From: "whatsapp:+5491112312312",
          Body: "Hello. Your order is on the way",
          To: "whatsapp:+541132132121",
        }
      end