Failed to retrieve clubhouse.io api using UrlFetchApp.fetch - bash

Problem Statement: Unable to retrieve data using clubhouse.io api
in Google sheets > Script Editor
Per developers.google.com: Certain HTTP methods (for example, GET) do not accept a payload.
However, the clubhouse v3 api expect body/payload in GET request
Here is method:
function getClubhouseStories() {
try{
var myHeaders = {"Content-Type": "application/json"};
var requestOptions = {
method: 'GET',
headers: myHeaders,
body: JSON.stringify({"query":"lable\:my label"}),
redirect: 'follow',
query: {"token": "XXXXXXXXUUIDXXXXX"},
muteHttpExceptions: true
};
var response = UrlFetchApp.fetch("https://api.clubhouse.io/api/v3/search/stories", requestOptions);
}
catch(error) {
console.error(error);
}
var responseCode = response.getResponseCode();
var responseContent = response.getContentText();
Logger.log(responseCode);
Logger.log(responseContent);
}
Returns:
responseCode >> 401
responseContent >> "{"message":"Sorry, the organization context for this request is missing. If you have any questions please contact us at support#clubhouse.io.","tag":"organization2_missing"}"
The same request works perfect via postman or bash, and requests that don't need body also work via UrlFetchApp.fetch
Tags:
#clubhouse-api #google-apps-scripts #postman

You can include the token and query parameters as part of the URL.
function getClubhouseStories() {
try {
var requestOptions = { muteHttpExceptions: true };
var parameters = {
token: 'XXXXXXXXUUIDXXXXX',
query: 'label:"my label"' // Clubhouse API requires using double quotes around multi-word labels
};
var url = "https://api.clubhouse.io/api/v3/search/stories";
var response = UrlFetchApp.fetch(buildUrl_(url, parameters), requestOptions);
} catch (error) {
console.error(error);
}
var responseCode = response.getResponseCode();
var responseContent = response.getContentText();
Logger.log(responseCode);
Logger.log(responseContent);
}
/**
* Builds a complete URL from a base URL and a map of URL parameters.
* Source: https://github.com/gsuitedevs/apps-script-oauth2/blob/master/src/Utilities.js#L27
* #param {string} url The base URL.
* #param {Object.<string, string>} params The URL parameters and values.
* #return {string} The complete URL.
* #private
*/
function buildUrl_(url, params) {
var paramString = Object.keys(params).map(function(key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
}).join('&');
return url + (url.indexOf('?') >= 0 ? '&' : '?') + paramString;
}
Other issues you're facing are related to request options that aren't valid UrlFetchApp parameters:
Default method is 'GET', so no need to specify
Content-Type should be specified using contentType, but it defaults to "application/x-www-form-urlencoded", so no need to specify
body is not valid. Should use payload instead, but not in this case, because we need to include parameters in the URL.
redirect is not valid. Should use followRedirects, but that already defaults to true.
query is not valid. Need to manually include in the URL.

The message you received, Sorry, the organization context for this request is missing. is the error you'll receive when you fail to send an authorization token/header.
You need something like this:
var myHeaders = {"Content-Type": "application/json", "Shortcut-Token": "<token>"};
Shortcut API docs

Related

GET request from NetSuite to Oracle EPM, but faced with "Authorization Required - You are not authorized to access the requested resource

Error: "Authorization Required - You are not authorized to access the requested resource. Check the supplied credentials (e.g., username and password)."
Using the same exact headers and URL, I am successfully able to make the request get through via Postman and Powershell. But when doing the call via SuiteScript, I get the auth error. I am thinking it may have something to do with me constructing the headers.
Here is the code I used via NetSuite Debugger:
require(['N/https', 'N/encode'], function(https, encode) {
function fetchCSVdata() {
var authObj = encode.convert({
string : "username:password",
inputEncoding : encode.Encoding.UTF_8,
outputEncoding : encode.Encoding.BASE_64
});
var psswd = 'Basic ' + authObj;
var headerObj = {'Authorization' : psswd};
var response = https.get({
url: 'https://<bleep>.pbcs.us6.oraclecloud.com/interop/rest/11.1.2.3.600/applicationsnapshots/DemandPlan_ExportItemPlan.csv/contents',
headers: headerObj
});
return response.body;
};
var x = fetchCSVdata();
log.debug("error", x);
});
Looking at some working code of mine it is different than yours but I don't see the error.
var authstring = encode.convert({string: 'username:password',
inputEncoding: encode.Encoding.UTF_8,
outputEncoding: encode.Encoding.BASE_64});
var headerObj = {Authorization: 'Basic '+ authstring };
var response = https.get({url: 'https://webservices.XXX.com', headers: headerObj});

IBM Watson WebSocket connection failure: "HTTP Authentication failed; no valid credentials available"

I'm doing the tutorial for IBM Watson Speech-to-text. In the section "Using the WebSocket interface", subsection "Opening a connection and passing credentials", I copied the following code:
var token = watsonToken;
console.log(token); // token looks good
var wsURI = 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?watson-token=' +
token + '&model=es-ES_BroadbandModel';
var websocket = new WebSocket(wsURI);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
I'm using Angular so I made a value for the token:
app.value('watsonToken', 'Ln%2FV...');
I get back an error message:
WebSocket connection to 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?watson-toke...&model=es-ES_BroadbandModel' failed: HTTP Authentication failed; no valid credentials available
I tried hardcoding the token:
var wsURI = 'wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?watson-token=Ln%2FV2...&model=es-ES_BroadbandModel';
Same error message.
IBM's documentation on tokens says that an expired or invalid token will return a 401 error, which I didn't get, so I presume that my token is neither expired nor invalid. Any suggestions?
I think you can see the Official Example from IBM Developers here.
The error is because the authentication does not work fine before you send the request to recognize, try to follow the same step inside this repository, like:
const QUERY_PARAMS_ALLOWED = ['model', 'X-Watson-Learning-Opt-Out', 'watson-token', 'customization_id'];
/**
* pipe()-able Node.js Readable/Writeable stream - accepts binary audio and emits text in it's `data` events.
* Also emits `results` events with interim results and other data.
* Uses WebSockets under the hood. For audio with no recognizable speech, no `data` events are emitted.
* #param {Object} options
* #constructor
*/
function RecognizeStream(options) {
Duplex.call(this, options);
this.options = options;
this.listening = false;
this.initialized = false;
}
util.inherits(RecognizeStream, Duplex);
RecognizeStream.prototype.initialize = function() {
const options = this.options;
if (options.token && !options['watson-token']) {
options['watson-token'] = options.token;
}
if (options.content_type && !options['content-type']) {
options['content-type'] = options.content_type;
}
if (options['X-WDC-PL-OPT-OUT'] && !options['X-Watson-Learning-Opt-Out']) {
options['X-Watson-Learning-Opt-Out'] = options['X-WDC-PL-OPT-OUT'];
}
const queryParams = extend({ model: 'en-US_BroadbandModel' }, pick(options, QUERY_PARAMS_ALLOWED));
const queryString = Object.keys(queryParams)
.map(function(key) {
return key + '=' + (key === 'watson-token' ? queryParams[key] : encodeURIComponent(queryParams[key])); // our server chokes if the token is correctly url-encoded
})
.join('&');
const url = (options.url || 'wss://stream.watsonplatform.net/speech-to-text/api').replace(/^http/, 'ws') + '/v1/recognize?' + queryString;
const openingMessage = extend(
{
action: 'start',
'content-type': 'audio/wav',
continuous: true,
interim_results: true,
word_confidence: true,
timestamps: true,
max_alternatives: 3,
inactivity_timeout: 600
},
pick(options, OPENING_MESSAGE_PARAMS_ALLOWED)
);
This code is from IBM Developers and for my project I'm using and works perfectly.
You can see in the code line #53, set the listening to true, otherwise it will eventually timeout and close automatically with inactivity_timeout applies when you're sending audio with no speech in it, not when you aren't sending any data at all.
Have another example, see this example from IBM Watson - Watson Developer Cloud using Javascript for Speech to Text.
Elementary, my dear Watson! There are three or four things to pay attention to with IBM Watson tokens.
First, you won't get a token if you use your IBMid and password. You have to use the username and password that were provided for a project. That username is a string of letters and numbers with hyphens.
Second, the documentation for tokens gives you code for getting a token:
curl -X GET --user {username}:{password}
--output token
"https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/text-to-speech/api"
Part of that code is hidden on the webpage, specifically the part that says /text-to-speech/. You need to change that to the Watson product or service you want to use, e.g., /speech-to-text/. Tokens are for specific projects and specific services.
Third, tokens expire in one hour.
Lastly, I had to put in backslashes to get the code to run in my terminal:
curl -X GET --user s0921i-s002d-dh9328d9-hd923:wy928ye98e \
--output token \
"https://stream.watsonplatform.net/authorization/api/v1/token?url=https://stream.watsonplatform.net/speech-to-text/api"

Pencilblue - origin not allowed for controller endpont

I'm developing an API using pencilblue, everything works fine until I make an AJAX request to this endpoint.
I always get an "origin not allowed" error.
Is there a way to enable CORS with pencilblue?
You can do this through creating your own controller:
https://github.com/pencilblue/pencilblue/wiki/Quickstart:-Controllers
And in there add the relevant headers for CORS. E.g. something like:
module.exports = function (pb) {
//PB dependencies
var util = pb.util;
var BaseController = pb.BaseController;
/**
* CORS Controller
*/
CorsController.prototype.render = function(cb) {
// Add the CORS Header here
var output = {
code: 200,
headers: {
'Access-Control-Allow-Origin': '*'
}
};
this.ts.load('example_api_endpoint', function(error, result) {
output.content = result;
cb(output);
});
return CorsController;
};

dojo ajax request to spring mvc,getting http 400

before starting let me say that I am new to dojo and this is my first project in dojo:
when I am trying to send json data from rest client (some chrome ext) it working for me,I mean to say that my spring mvc part is working, but when i am trying to send the same json from dojo code I am getting http 400 exception
my dojo code:
postCreate : function() {
this.inherited(arguments);
var form = dom.byId("contactSubmit");
on(form, "click", function(evt) {
var box0 = registry.byId("inputEmail");
var box1 = registry.byId("inputName");
var box3 = registry.byId("message");
alert("values are: " + box0.get("value"));
jsonData = {"email":"some#gmail.com","inputName":"some name","message":"some msg"};
request.post("/pool/conta", {
data: jsonData,
handleAs: "json",
headers: {
"Content-Type": "application/json;charset=utf-8",
"Accept": "application/json"
}
}).then(function(text){
alert("values are send"+text);
});
});
}
the jason data that I am sending from rest client is which is working:
{"email":"some#gmail.com","inputName":"some name","message":"some msg"}
my spring mvc method is below:
#RequestMapping(value="/conta", method = RequestMethod.POST)
public #ResponseBody Contact getShopInJSON(#RequestBody Contact contact2) {
Contact contact = new Contact();
contact.setEmail("pro#gmail.com");
contact.setInputName("pro");
contact.setMessage("msg");
System.out.println("***********************"+contact2.getEmail());
return contact;
}
pool is name of application
The json data as passed in post request requires string to be crypted with "\" so that the javascript can handle the double codes as is within string(double quoted string).
Thus, the line
jsonData = {"email":"some#gmail.com","inputName":"some name","message":"some msg"};
would work if written as below
jsonData = " {\"email\":\"some#gmail.com\",\"inputName\":\"some name\",\"message\":\"some msg\"} " ;
Its working now, I have used toJson from dojo/_base/json" utility before passing it to request.post

How to make dojo.request.xhr GET request with basic authentication

I look at the documentation for Dojo v.1.9 request/xhr
and I cannot find example that includes basic authentication.
How and where do I include the User name and Password in the Dojo XHR options?
require(["dojo/request/xhr"], function(xhr){
xhr("example.json", {
// Include User and Password options here ?
user: "userLogin"
password: "userPassword"
handleAs: "json"
}).then(function(data){
// Do something with the handled data
}, function(err){
// Handle the error condition
}, function(evt){
// Handle a progress event from the request if the
// browser supports XHR2
});
});
Thanks.
Indeed, you should be able to pass the user and password with the user and password property in the options object.
In previous versions of Dojo this was documented, but it seems that now they aren't. However, I just tested it and it seems to add the username and password to the URL, like:
http://user:password#myUrl/example.json
Normally the browser should be capable of translating this URL so the request headers are set.
You could also set these headers manually, for example by using:
xhr("example.json", {
headers: {
"Authorization": "Basic " + base64.encode(toByteArray(user + ":" + pass))
}
}).then(function(data) {
// Do something
});
However, this requires the dojox/encoding/base64 module and the following function:
var toByteArray = function(str) {
var bytes = [];
for (var i = 0; i < str.length; ++i) {
bytes.push(str.charCodeAt(i));
}
return bytes;
};

Resources