So I have a client who needed a google voice widget embedded in their site.
If you're not familiar with it, it's a little widget that your site's visitors can use to call you.

It's really simple to set up...unless you want to customize the widget's graphics. But there is a way. Here's how you can do it:

A simple form post

The Google Voice widget does a simple form post. You can see it Here.

When there are no errors, google returns "ok=true". When there are problems, it returns "ok=false".

Easy

A Proxy

The only kink here is that we can't AJAX post to a 3rd party domain like google. So we need to implement a little proxy. You can do this by creating a controller named "phone_calls".

It's pretty simple. It just takes params[:phone_call] and does a https post to the google server.

class PhoneCallsController < ApplicationController
  def create
    http = Net::HTTP.new('clients4.google.com', 443)
    http.use_ssl = true
    path = '/voice/embed/webButtonConnect'

    request_params = params[:phone_call].map { |k, v| "#{ CGI.escape(k) }=#{ CGI.escape(v) }" }.join("&")
    request_headers = {}

    resp, data = http.post(path, request_params, request_headers)

    render :text => data
  end
end

The HTML

Now we just need to make a little form and add some javascript to submit it. You'll need to get your api key from the google voice widget's embed code.

<form id="google-voice" action="https://clients4.google.com/voice/embed/webButtonConnect" method="post">

  <input type="hidden" name="phone_call[buttonId]" value="<YOUR API KEY>" />
  <input type="hidden" name="phone_call[showCallerNumber]" value="1" />

  <ul>
    <li>
      <label>Your Name</label>
      <input type="text" name="phone_call[callerNumber]" />
    </li>
    <li>
      <label>Your Phone #</label>
      <input type="text" name="phone_call[callerNumber]" />
    </li>
    <li>
      <input type="submit" value="Call Me" />
    </li>
  </ul>

</form>

... and here's the javascript


  $("#google-voice").submit(function(e){
    e.preventDefault();

    $.post("/phone_calls", $(this).serialize(), function(data){
      if(data=="ok=true"){
        console.log("success");
      }
      else{
        console.log("failure");
      }
    }, "html");

  });

You can make it a little fancier by showing "success" and "failure". That's left as an exercise for the reader.