Application Only Authentication - Error Code 86 "This method requires a GET or HEAD"


#1

I’m attempting to use Application Only Authentication in Google Script to access the Twitter Search API.

I followed the setup instructions on the Application Authentication page and have successfully received and stored my Bearer Token.

However, whenever I try to make a GET request to the Search API, it returns this response:

 {errors=[{code=86, message=This method requires a GET or HEAD.}]}

However, I do include a GET in my method and using Google Script’s UrlFetchService worked successfully with a POST for obtaining the Bearer Token.

I’ve checked in the forums and the only mentions of Code 86 have a slightly different response:

 {errors=[{code=86, message=This method requires a DELETE or POST.}]}

This user on StackOverflow had a similar error, but his fix was in Java which couldn’t be used in Google Script. And this person had the same error in R although they weren’t even able to obtain the bearer token in the first place.

Below is the code that successfully retrieves and stores a Bearer Token

function getToken() {  
  // STEP 1 - ENCODE CONSUMER KEY AND SECRET
  var consumerKey = PropertiesService.getScriptProperties().getProperty("twitterConsumerKey");
  var secret = PropertiesService.getScriptProperties().getProperty("twitterSecret");
  var encoded_consumerKey = encodeURIComponent(consumerKey);
  var encoded_secret = encodeURIComponent(secret);
  var encoded_joined = encoded_consumerKey+':'+encoded_secret;
  var base64_joined = Utilities.base64Encode(encoded_joined);
  Logger.log(base64_joined);
  
  //STEP 2 - OBTAIN A BEARER TOKEN
  var bearer_url = 'https://api.twitter.com/oauth2/token';
  var options = {
    "method": "post",
    "headers":{
      "Authorization": "Basic "+base64_joined,
      "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
    },
    "payload": {
      "grant_type": "client_credentials"
    }
  }
  
  var response = UrlFetchApp.fetch(bearer_url, options);
  var data = JSON.parse(response.getContentText());
  var access_token = PropertiesService.getScriptProperties().setProperty("access_token", data.access_token); 
}

And below is the code for when I use that Bearer Token and receive the “This method requires a GET or HEAD” error.

function checkTwitter(){
      //SEARCH API
      var bearer_token = PropertiesService.getScriptProperties().getProperty("access_token");
      var search_url = 'https://api.twitter.com/1.1/search/tweets.json';
      var search_term = 'http://www.theverge.com/2015/10/6/9463931/tom-hanks-lauren-student-id';
      var encoded_search = encodeURIComponent(search_term);
      var payload = {
        "q": encoded_search,
        "result_type": "recent",
        "count": "10"
      };
      var options = {
        "method": "get",
        "payload": payload,
        "headers":{
          "Authorization": "Bearer "+bearer_token,
          "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
          "Accept-Encoding": "gzip"
        },
        "followRedirects": true,
        "muteHttpExceptions": true
      };
      
    
      var response = UrlFetchApp.fetch(search_url, options);
      var data = JSON.parse(response.getContentText());
    }

Any help or insights would be greatly appreciated!


#2

For anyone who may Google this error code later on, this was the fix for me.

I was dumb and hadn’t realized I shouldn’t have been using a payload in a GET request. I switched over to tacking the parameters onto the base URL and it worked immediately. Below is the working code.

function searchInitial(search_term){
  //SEARCH API
  var bearer_token = PropertiesService.getScriptProperties().getProperty("access_token");
  var base_url = 'https://api.twitter.com/1.1/search/tweets.json';
  var search_url = base_url+'?q='+encodeURIComponent(search_term)+'&result_type=recent&count=100&include_entities=false';
  var options = {
    "method": "get",
    "headers":{
      "Accept": "*/*",
      "User-Agent": "Your App Name",
      "Authorization": "Bearer "+bearer_token,
      "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
      "Accept-Encoding": "gzip"
    },
    "followRedirects": true,
    "muteHttpExceptions": true
  };
  var response = UrlFetchApp.fetch(search_url, options);
  var data = JSON.parse(response.getContentText());
  return data;
}

#3

Awesome! Thanks for sharing the solution and fix, and glad you’re up and running :smile:


#4