Search code examples
ruby-on-railsrubyencodingpostmanx-www-form-urlencoded

Ruby - Encoding Body Of A Post Request


I am trying to convert a body consisting of different parameters as hash into an encoded format as below:

params = {
  "senderid" => "abc",
  "username" => "xyz",
  "password" => "1234",
  "Response" => "Y",
  "mtype" => "TXT",
  "dltentityid" => "15058",
  "tmid" => "11101",
  "subdatatype" => "M",
  "dlttempid" => "345690",
  "dlttagid" => "",
  "msgdata" => {
    "data" => [
      {
      "mobile" => "9000099999",
      "message" => "Thank for showing your preference for the loan requirement for your dream home at Happinest Kalyan. We have a host financial partners who are offering home loans at competitive rates. Login access the details of financial partners on abc."
      }
    ]
  }
}

  url                     = URI('http://www.smsjust.com/sms/user/urlsms_json.php')
  http                    = Net::HTTP.new(url.host, url.port)
  request                 = Net::HTTP::Post.new(url)
  request["Content-Type"] = 'application/x-www-form-urlencoded'
  request.body            = URI.encode_www_form(params)
  response                = http.request(request)

The receiver receives request.body as below. Here the URI encoding of params encodes the params as below, which doesn't work and gives output as wrong json format:

"senderid=abc&username=xyz&password=%qwe3&Response=Y&mtype=TXT&dltentityid=12658&tmid=150000010001&subdatatype=M&dlttempid=150092&dlttagid=&msgdata=%7B%22data%22%3D%3E%5B%7B%22mobile%22%3D%3E%229998973369%22%2C+%22message%22%3D%3E%22Thank+for+showing+your+preference+for+the+loan+requirement+for+your+dream+home+at+Happinest+Kalyan.+We+have+a+host+financial+partners+who+are+offering+home+loans+at+competitive+rates.+Login+access+the+details+of+financial+partners+on+%24project_name.%22%7D%5D%7D"

And the same post request in postman translates the URI encoding of params as below which works - The below is the expected format in which it should be sent to the receiver:

"username=abc&password=%qweeCS3&senderid=qas&mtype=TXT&msgdata=%7B%22data%22%3A%5B%7B%22mobile%22%3A%229812593882%22%2C%22message%22%3A%22Thank%20for%20showing%20your%20preference%20for%20the%20loan%20requirement%20for%20your%20dream%20home%20at%20Happinest%20Kalyan.%20We%20have%20a%20host%20financial%20partners%20who%20are%20offering%20home%20loans%20at%20competitive%20rates.%20Login%20access%20the%20details%20of%20financial%20partners%20on%20%24project_name.%22%7D%2C%7B%22mobile%22%3A%228849593882%22%2C%22message%22%3A%22Sixth%20message%22%7D%5D%7D&subdatatype=M&Response=Y&dlttempid=15092&dltentityid=1502658&tmid=15010001&dlttagid="  

Already Tried: I have tried using CGI.escape but doesn't work either.

Any help with the above issue will be much appreciated.


Solution

  • I have found the solution which looks something like below:

    params = {
      "senderid" => "abc",
      "username" => "xyz",
      "password" => "1234",
      "Response" => "Y",
      "mtype" => "TXT",
      "dltentityid" => "15058",
      "tmid" => "11101",
      "subdatatype" => "M",
      "dlttempid" => "345690",
      "dlttagid" => ""  
    }
    
    msgdata = {
      "data" => [
        {
        "mobile" => "9000099999",
        "message" => "Thank for showing your preference for the loan requirement for your dream home at Happinest Kalyan. We have a host financial partners who are offering home loans at competitive rates. Login access the details of financial partners on abc."
        }
      ]
    }.to_json
    
      url = URI('http://www.smsjust.com/sms/user/urlsms_json.php')
      http = Net::HTTP.new(url.host, url.port);
      request = Net::HTTP::Post.new(url)
      request["Content-Type"] = "application/x-www-form-urlencoded"
      request_body = (params.each { |k, v| params[k] = CGI.escape(v.to_s) }).to_query
      request.body = "#{request_body}&msgdata=#{CGI.escape(msgdata.to_s)}"
    

    The catch here is to convert all the params into CGI.escape instead of URI.encode_www_form except the msgdata field.

    As msgdata is a string, it should sent as a json string in the body - hence convert it into json separately --> apply CGI.escape on it and then append it last in the request_body.

    Hope this will help anyone landing on this question !!!