The Post Excerpt

Recently, I had to find a solution to query Twitter’s Search API with my Ionic and Cordova app.

I had found some great posts by @nraboy and @saimon24 on very similar topics, so I expanded on them and I specifically modified the code found in saimon24’s post:

His code allows you to query Twitter’s API to return a timeline, with this link: I think his code will work for any of the static end points, but it doesn’t allow you to query the search API with additional parameters, such as this link:

Notice the two extra parameters: q & result_type. The search api accepts a few other parameters, and the whole trick to it is in creating a signature hash that includes all params, including the oAuth parameters generated by ngCordova’s createSignature function.

Otherwise you’ll get this error:

{"errors":[{"code":32,"message":"Could not authenticate you."}]}

The end goal is to produce a url string that looks something like this, with the right signature!:

Notice that it includes the two twitter API parameters, along with 6 oAuth parameters.

So let’s say you’re building an angular service that queries Twitter’s API and stores the resulting tweets. You’ll need to include $q, $cordovaOauth and $cordovaOauthUtility as dependencies and set up the following code:

if (window.cordova) {

        var q = $q.defer();

        //This could be any API Endpoint on Twitter that accepts params
        var search_tweets_url = '';

        //Use saimon's createTwitterSignature Function
        var oauthObj = createTwitterSignature('GET', search_tweets_url, buildParamObj(keywordObj));

        //Save and Delete the oAuth signature object because $.param screws it up
        var sigTemp = oauthObj.oauth_signature;
        delete oauthObj.oauth_signature;

        //Convert OAuth object to params, adjust for signature
        //Using $http because $resource gives me config errors for action query. Callback instead of promise :(
        //Make sure to include the $q library

        $http.get( search_tweets_url +'?' + buildParamString(keywordObj) + '&' + $.param(oauthObj) + '&oauth_signature=' + sigTemp )
        .success(function(data, status, headers, config) {
        console.log('Successul HTTP Request', data);
        tweets = data.statuses;
        .error(function(data, status, headers, config) {
        console.log('Rejected HTTP Request ', status, headers);

        return q.promise;


To start you’ll some sort of object with all your search parameters. I’ve only included 3 of them here, but there are several more you can use.

  q: 'Yoga',
  result_type: 'recent',
  count: 50

You can create the object above from another object (keywordFormObj) generated by your own custom input form (not covered in this post):

function buildParamObj(keywordFormObj) {

        var paramObject = {};

        paramObject.q = keywordFormObj.query;
        paramObject.result_type = "recent";

        if (keywordFormObj.lang) {
            paramObject.lang = keywordFormObj.lang;

        paramObject.count = 50;

        return paramObject;


Now this new object has to be sent into the createTwitterSignature function as a third parameter, like so:

var oauthObj = createTwitterSignature('GET', search_tweets_url, buildParamObj(keywordObj));

And here is saimon’s slightly modified createTwitterSignature function (that still works with his prior post/code)

function createTwitterSignature(method, url, paramObj) {

        if (!paramObj) {
            paramObj = {};

        var oauthObject = {
            oauth_consumer_key: clientId,
            oauth_nonce: $cordovaOauthUtility.createNonce(10),
            oauth_signature_method: "HMAC-SHA1",
            oauth_token: accessToken,
            oauth_timestamp: Math.round((new Date()).getTime() / 1000.0),
            oauth_version: "1.0"

        var signatureObj = $cordovaOauthUtility.createSignature(method, url, oauthObject, paramObj, clientSecret, accessTokenSecret);
        $http.defaults.headers.common.Authorization = signatureObj.authorization_header;
        console.log('created Headers', $http.defaults.headers, signatureObj);
        return oauthObject;


That function will return an oAuthObject with all the extra params you need to build your final search URL for twitter.

I then use jQuery to turn that object into a param string using $.param()

But there’s a slight problem because that function will re-encode any % chars, ruining the oauth_signature property, so I temporarily save the oauth_signature property from the object, delete it, and go ahead and create the parameter string. I then reattach the oauth_signature to the end of it.

search_tweets_url +'?' + $.param(buildParamObj(keywordObj)) + '&' + $.param(oauthObj) + '&oauth_signature=' + sigTemp

Notice how I also have to convert the buildParamObj into a string as well and attach it to the url. Be careful though, if you have special characters in your object, jquery might re-encode them, so you might want to build your param string manually, without using $.param().

$http is another dependency that you have to add to your service. In saimon24’s post he uses $resource, however I found it troublesome with complex queries, and decided to switch to $http. Instead of using promises it uses callbacks, so I wrapped the whole thing in a $q promise and I only return the result when the callback is completed, forcing my program to wait for the result from the service.

And here’s a bit of extra code that returns the same data, however I use it when I’m testing in the browser where ngCordova doesn’t work. You’ll need to include CodeBird to your project though!

if (!window.cordova) {

                var cb = new Codebird;
                cb.setConsumerKey(clientId, clientSecret);
                cb.setToken(accessToken, accessTokenSecret);

                    function(reply, rate_limit_status) {
                        console.log('Codebird ', reply, rate_limit_status);

                        tweets = reply.statuses;



Good luck!

Next |



© 2016 ENGAGE Inc.

π - φ - e

Subscribe to our newsletter

Sign up to our awesome newsletter and get the latest updates on web marketing and development. Guaranteed to be worth a read.

We promise to never share your information or spam your inbox.

Short Link

Use our free URL redirection service. Turns a long URL into a much shorter one.