cambialens / lens-api-doc

10 stars 5 forks source link

Challenges getting the API to work from Google Apps Script (mostly return code 415) #30

Closed bobchatham closed 3 years ago

bobchatham commented 3 years ago

We're building a function library to the patents API to support Excel and Google Sheets users. I've successfully gotten the following code to work from VBA in Excel on Windows, but am stuck on Google Apps Script in Sheets:

Sub httpPost()
    Dim url As String
    Dim body As String
    Dim response As String
    Dim request As Object

    url = "https://api.lens.org/patent/search"

    body = "{""query"": { ""terms"":  { ""lens_id"": [""162-510-171-350-158""]} }, ""include"": [""claims""]}"

    Set request = CreateObject("MSXML2.XMLHTTP")
    With request
        .Open "POST", url, False
        '.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
        .setRequestHeader "Authorization", "Bearer {my-token}"
        .setRequestHeader "Content-type", "application/json"

        .Send body
        response = .ResponseText
    End With

End Sub

I'm now trying to get this to work in Google Apps Script (ECMAScript). So far totally unsuccessful, always get a 415 return code despite trying a bunch of permutations of double and single quotes, JSON.stringify'ing the POST inputs, header parameters etc. (see various permutations commented out below)

I have given the script the appropriate OAuth permissions (I think...see below). Would love to get this to work -- any suggestions? Thanks in advance. Bob

Code.js

function getClaims() { 

  var endPoint = 'https://api.lens.org/patent/search';
  var token = '{my-token}';

  var query = "{\"query\": { \"terms\": { \"lens_id\": [\"162-510-171-350-158\"]} }, \"include\": [\"claims\"]}";
  // var query = '{"query": { "terms": { "lens_id": ["162-510-171-350-158"]} }, "include": ["claims"]}';
  // var query = {
  //   "query": {
  //     "terms": {
  //       "lens_id": ["162-510-171-350-158"]
  //     }
  //   },
  //   "include": ["claims"]
  // };

  var options = {
    method: "POST",
    url: endPoint,
    body: query,
    // body: JSON.stringify(query),
    json: true,
    // muteHttpExceptions: false,
    headers: {
      "Authorization": "Bearer " + token
      //'Content-Type': 'application/json'
    }
  };

  var response = UrlFetchApp.fetch(endPoint, options);
  var data = response.getContentText();
  var json = JSON.parse(data);
  console.log(JSON.stringify(json));

}

appsscript.json

{
  "timeZone": "America/New_York",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": ["https://www.googleapis.com/auth/script.external_request"]

}
rosharma9 commented 3 years ago

You will need to add Content Type as application/json in header. https://docs.api.lens.org/getting-started.html#http-responses

Also, please don't paste your actual access token publicly. Please delete it and gererate a new one.

rosharma9 commented 3 years ago

This should work.

  var query = {"query": { "terms": { "lens_id": ["162-510-171-350-158"]} }, "include": ["claims"]};

  var options = {
    'method': "POST",
    'url': endPoint,
    'payload': JSON.stringify(query),
    'json': true,
    // muteHttpExceptions: false,
    'headers': {
      "Authorization": "Bearer " + token,
      "Content-Type": "application/json"
    }
  };
bobchatham commented 3 years ago

Thanks for the help Roshan, your suggestion worked.

I'm now coming up with a plan for dealing with the rate-limiting so that a typical spreadsheet user won't overrun the limits but still realize acceptable performance. The 6 (maybe 10?) calls/minute limit seems low, but fine for development purposes for now. Would retrieving an array of patents using a vector of n lens_ids count as one call or n calls?

rosharma9 commented 3 years ago

Yes, you can retrieve multiple lens ids (up-to 100 for trial) in a single request like this:

{
   "query": {
    "terms":{
          "lens_id": ["162-510-171-350-158", "....", "....."]
     }
  },
 "include": ["claims"]
}

It will be a single request. You can use scroll based pagination to loop through and sleep for response code 429 (too_many_requests) like this: https://docs.api.lens.org/samples-patent.html#cursor-based-pagination