I have a user event script which executes on create of sales order and sends a HTTPS POST to our integration URL on Mulesoft. It seems NetSuite throws SSS_REQUEST_TIME_EXCEEDED error within 45 secs even if API call was successful. if there a way to increase these 45 sec and run it behind the scene? should i create a suitelet and call from userevent when record is created?
FYI. Post call is successful every time but script throws this error.
user event code:
function afterSubmit(context) {
if (context.type !== context.UserEventType.CREATE)
return;
try{
var envtype = JSON.stringify(runtime.envType)
var accountId = runtime.accountId
var isProduction = (accountId == '12345')
log.debug({title: 'Before Post' })
var tokenrecord = record.load({
type: 'customrecord_mulesoft_setup',
id: 1,
isDynamic: true,
});
var token = tokenrecord.getValue({
fieldId: 'custrecord_sandbox_token_so_api'
})
log.debug({title : 'token' , details: token});
var headers = {
'Content-Type' : 'application/json',
Authorization : isProduction ? 'Bearer ' + token : 'Bearer ' + token,
'User-Agent': 'NetSuite/2022',
Accept: '*/*',
Host : isProduction ? 'test.com' : 'test.com',
'Accept-Encoding': 'gzip, deflate, br',
Connection :'keep-alive'
}
var salesorderid = context.newRecord.id;
if (isProduction) {
apiNum = 'xxxxxx';
endPointUrl = 'https://test.com/' + salesorderid; }
else {
apiNum = 'yyyy'; // all updates
endPointUrl = 'https://test.com/' + salesorderid;
}
var postedObj = { /*
parameters : [
{
"Key": "ns_internal_id",
"Value": v_intid
}
] */
}
var jsonify = JSON.stringify(postedObj);
log.debug({title : 'url' , details: endPointUrl});
log.debug({title : 'headers' , details: headers});
log.debug({title : 'body' , details: jsonify});
var resp=https.post({
url: endPointUrl,
headers: headers,
body: jsonify
});
var id = record.submitFields({
type: record.Type.SALES_ORDER,
id: salesorderid,
values: {
custbody_sent_to_mulesoft: true
}
});
}
catch(e){
log.error({title : 'Error Message' , details: e.message});
log.error({title : 'Error Code' , details: e.name});
log.debug({title: 'Headers' + 'resp.headers' })
log.error({title : 'Could not send item to SF !!' , details: JSON.stringify(resp)});
log.error({title : 'Could not send item to SF !!' , details: JSON.stringify(jsonify)})
}
return;
Error:
Message: The host you are trying to connect to has exceeded the maximum allowed response time.
Code: SSS_REQUEST_TIME_EXCEEDED
Firstly, I wouldn't recommend using an API call that could potentially take a long time (more than a couple of seconds) to come back in a UserEvent script because it would drastically impact user experience.
To answer your question, you should implement a retry function to call the API multiple times if the first request fails. There is an supporting document that explains this and similar issues on the SuiteAnswers page. https://suiteanswers.custhelp.com/app/answers/detail/a_id/32729/loc/en_US
function retry(expectedErrors, task, retries=1) {
try {
return task();
} catch (err) {
if (retries === 0) throw err;
if (expectedErrors.length && !expectedErrors.includes(err.name)) throw err;
return retry(expectedErrors, task, --retries);
}
}
retry(["SSS_REQUEST_TIME_EXCEEDED"], function() {
// your API request here
});
Related
I want to isolate subscriberCount: '15' to it's own variable but nothing I do works here is all the data I have (some censored for security reasons) please try to help me!
Code
const Youtube = require("youtube-api")
, fs = require("fs")
, readJson = require("r-json")
, Lien = require("lien")
, Logger = require("bug-killer")
, opn = require("opn")
, prettyBytes = require("pretty-bytes")
;
// I downloaded the file from OAuth2 -> Download JSON
const CREDENTIALS = readJson(`${__dirname}/credentials.json`);
// Init lien server
let server = new Lien({
host: "localhost"
, port: 5000
});
// Authenticate
// You can access the Youtube resources via OAuth2 only.
// https://developers.google.com/youtube/v3/guides/moving_to_oauth#service_accounts
let oauth = Youtube.authenticate({
type: "oauth"
, client_id: CREDENTIALS.web.client_id
, client_secret: CREDENTIALS.web.client_secret
, redirect_url: CREDENTIALS.web.redirect_uris[0]
});
opn(oauth.generateAuthUrl({
access_type: "offline"
, scope: ["https://www.googleapis.com/auth/youtubepartner-channel-audit https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtubepartner-channel-audit https://www.googleapis.com/auth/youtube.readonly"]
}));
// Handle oauth2 callback
server.addPage("/oauth2callback", lien => {
Logger.log("Trying to get the token using the following code: " + lien.query.code);
oauth.getToken(lien.query.code, (err, tokens) => {
if (err) {
lien.lien(err, 400);
return Logger.log(err);
}
Logger.log("Got the tokens.");
oauth.setCredentials(tokens);
lien.end("Eyyy you logged in!");
// var req = Youtube.videos.insert({ });
function execute() {
return Youtube.channels.list({
"part": [
"statistics"
],
"mine": true,
"prettyPrint": true
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
//console.log("Response", response);
//console.log(typeof response.data.items);
//console.log(response.data.items);
//console.log(result);
console.log(response.data.items);
//console.log(response.statistics);
},
function(err) { console.error("Execute error", err); });
}
execute();
});
});
Response From google:
[
{
kind: 'youtube#channel',
etag: '*****',
id: '*****',
statistics: {
viewCount: '506',
subscriberCount: '15',
hiddenSubscriberCount: false,
videoCount: '12'
}
}
]
Jaromanda X gave the solution in a comment:
response.data.items is an Array, by the look of your question, ... so you'd need response.data.items[0].statistics.subscriberCount
I'm trying to make script to generate my authentication bearer token for collections. so I don't have to pass token each time and I will Inherit auth from parent. But I don't know where I'm wrong in script, I'm not able to generate token and it giving me error
There was an error in evaluating the Pre-request Script: Error: No data, empty input at 1:1 ^
Here is my script,
var expiresOn = pm.variables.get('ExpiresOn');
if (!expiresOn || new Date(expiresOn) <= new Date()) {
var clientId = '565v7677676vfdrd';
var apiToken = '6565fdvdrdfd';
var request = {
url: 'http://.../auth/token',
method: 'POST',
header: 'Content-Type:application/Json',
body: {
mode: 'application/json',
raw: clientId + apiToken
}
};
}
};
pm.sendRequest(request, function (err, res) {
if (res !== null) {
var json = res.json();
pm.environment.set('Access_Token', json.access_token)
var expiresOn = new Date(0);
expiresOn.setUTCSeconds(json.expires_on);
pm.environment.set('ExpiresOn', expiresOn);
}
});
}
const echoPostRequest = {
url: 'https://example.com/sign_in?client_id=dbdsA8b6V6Lw7wzu1x0T4CLxt58yd4Bf',
method: 'POST',
header: 'Accept: application/json\nUser-Agent: Example/2019.10.31-release (Android 6.0.1; LGE Nexus 5)\nUDID: 1d2c7e65f34b3882f8e42ab8d6a82b4b\nContent-Type: application/json; charset=utf-8\nHost: api-mobile.example.com',
body: {
mode: 'application/json',
raw: JSON.stringify(
{
client_id:'dbdsA8b6V6Lw7wzu1x0T4CLxt58yd4Bf',
client_secret:'aBK1xbehZvrBw0dtVYNY3BuJJOuDFrYs',
auth_method:'password',
create_if_not_found:false,
credentials:{identifier:'username',password:'pass'},
signature:'2:a899cdc0'
})
}
};
var getToken = true;
if (!pm.environment.get('accessTokenExpiry') ||
!pm.environment.get('currentAccessToken')) {
console.log('Token or expiry date are missing')
} else if (pm.environment.get('accessTokenExpiry') <= (new Date()).getTime()) {
console.log('Token is expired')
} else {
getToken = false;
console.log('Token and expiry date are all good');
}
if (getToken === true) {
pm.sendRequest(echoPostRequest, function (err, res) {
console.log(err ? err : res.json());
if (err === null) {
console.log('Saving the token and expiry date')
var responseJson = res.json();
pm.environment.set('currentAccessToken', responseJson.access_token)
var expiryDate = new Date();
expiryDate.setSeconds(expiryDate.getSeconds() + responseJson.expires_in);
pm.environment.set('accessTokenExpiry', expiryDate.getTime());
}
});
}
The above example is a Postman Pre-request script to fetch access_token, and the expire time of the token. I think this example will help you to solve the issue.
Please check the console of the postman
Open Postman Console by pressing Ctrl+Alt+C on Windows (Cmd + Alt+ C on mac)
Syntax error
When running your script I got the following error:
There was an error in evaluating the Pre-request Script: SyntaxError: Unexpected token ';'
It should be something like this in order to run correctly:
var expiresOn = pm.variables.get('ExpiresOn');
if (!expiresOn || new Date(expiresOn) <= new Date()) {
var clientId = '565v7677676vfdrd';
var apiToken = '6565fdvdrdfd';
var request = {
url: 'https://api.domain.io/api/user/session',
method: 'POST',
header: 'Content-Type:application/Json',
body: {
mode: 'application/json',
raw: clientId + apiToken
}
};
}
pm.sendRequest(request, function (err, res) {
if (res !== null) {
var json = res.json();
pm.environment.set('Access_Token', json.access_token)
var expiresOn = new Date(0);
expiresOn.setUTCSeconds(json.expires_on);
pm.environment.set('ExpiresOn', expiresOn);
}
});
Additional options
I used one of these two options to get the bearer token for my collection:
https://gist.github.com/bcnzer/073f0fc0b959928b0ca2b173230c0669#file-postman-pre-request-js
https://community.postman.com/t/how-to-automatically-set-a-bearer-token-for-your-postman-requests/10126/2
A bit modified Sebin Sunny's answer tested with JWT against Azure + resource (/audience).
In headers of request use Authorization {{$randomLoremSentence}}
const echoPostRequest = {
url: 'https://login.microsoftonline.com/{tenant}/oauth2/token',
method: 'POST',
body: {
mode: 'formdata',
formdata: [
{ key: 'grant_type', value: 'client_credentials' },
{ key: 'client_Id', value: '*******************************' },
{ key: 'client_secret', value: '*******************************' },
{ key: 'resource', value: '*******************************' }
]
}
};
var getToken = true;
var token = pm.globals.get('$randomLoremSentence') || '';
var exp = pm.globals.get('accessTokenExpiry');
var exps = new Date(exp);
if (token.indexOf('Bearer ') < 0) {
console.log('Token or expiry date are missing')
} else if (exp <= (new Date()).getTime()) {
console.log('Token is expired - ${exps}')
} else {
getToken = false;
console.log(`Token ${token.substr(0,10)}...${token.substr(-5)} and expiry ${exps} date are all good`);
}
if (getToken === true) {
pm.sendRequest(echoPostRequest, function (err, res) {
console.log(err ? err : res.json());
if (err === null) {
var responseJson = res.json();
var token = responseJson.access_token;
console.log(`Saving the token ${token.substr(0,5)}...${token.substr(-5)} and expiry ${exps} date`)
pm.globals.set('$randomLoremSentence', "Bearer " + token);
var expiryDate = new Date(responseJson.expires_on * 1000);
pm.globals.set('accessTokenExpiry', expiryDate.getTime());
}
});
}
//pm.globals.set('$randomLoremSentence', 0); // reset token 2 test
I’m trying to create a JS service on WebOS 3.0 followed the official documentation.
I can send data between JS service and my application, but sometimes the JS service does not respond to the request if it’s idled for like 20 seconds. I’ve also tried to increase the timeout per this. Unfortunately, it does not seemed to be working.
Here’s my code
Application Side
const request = webOS.service.request('luna://com.myapp.service', {
method : 'fetch',
parameters : { url, method, headers, body },
onFailure : (err) => {
reject(err)
},
onSuccess : (s) => {
console.log('request success', s)
},
onComplete : (resp) => {
const isSuccess = resp.data.status >= 200 && resp.data.status < 400
var payload = {
json : () => Promise.resolve(JSON.parse(resp.data.body)),
ok : isSuccess,
headers : resp.data.headers,
status : resp.data.status,
error : isSuccess
? null
: resp.data.body
}
resolve(payload)
}
})
})
Service Side
var Service = require('webos-service')
var service = new Service('com.myapp.service')
service.register('fetch', function(message) {
var payload = message.payload
if(!payload) {
message.respond({
returnValue : true,
error : 'Message does not have a `payload`'
})
return
}
var url = payload.url,
headers = payload.headers,
method = payload.method,
body = payload.body
var request = http.request({
method : method,
hostname : URL.parse(url).hostname,
path : URL.parse(url).path,
headers : headers,
}, function(res) {
var data = ''
res.on('data', function(chunk) { data+=chunk })
res.on('end', function() {
message.respond({
returnValue : true,
data : {
status : res.statusCode,
statusText : res.statusMessage,
headers : res.headers,
body : data,
}
})
})
})
request.on('error', function(err) {
console.log(err)
message.respond({
returnValue : true,
error : err
})
})
request.end()
})
I recently wrote a JavaScript application for LG Smart-TVs and would highly recommend using socket.io for all communication between client and server.
It's a bit tricky getting it to work initially, but works flawlessly.
Here's how the connection looks ...
var socket = io("http://10.27.101.95");
idUser = getCookie("idUser"); // Retrieved from device and set to cookie.
// ┌────────────────────────────────────────────────────────────────┐
// │ Socket.io: Connect/Emit │
socket.on('connect', function() {
socket.emit("addUser", {
"idUser": idUser
});
reconnectHideData = false;
});
// Hide data if server cannot be reached.
var reconnectCount = 0;
var reconnectHideData = false;
socket.on('reconnect_error', function() {
if (reconnectCount < 10 && reconnectHideData == false) {
// console.log( '---=== Reconnect attempt: ' + reconnectCount + ' ===---' );
setTimeout(function(){
reconnectCount++;
}, 3000);
}
if (reconnectCount == 10 && reconnectHideData == false) {
// console.log( '-----===== Cleared Data =====-----' );
$('.section ').addClass(' u-hide ');
$('.greeting').addClass(' u-hide ');
reconnectHideData = true;
reconnectCount = 0;
}
else {
return;
}
});
// Necessary to trigger event to be emitted server side.
setInterval(function(){
socket.emit("reqData");
}, 5000);
// └────────────────────────────────────────────────────────────────┘
After that, it's all a matter of processing and formatting the returned data.
I'm trying to use the asana-api to create a Task using a POST http request but I keep getting a 400 bad request as a response.
I managed to get data from the Asana-api using ( a GET request ), but I'm having trouble sending data to Asana with ( a POST request )
I'm using the 'request' module to do the api call
here's the error message :
`{"errors":[{
"message":"Could not parse request data,invalid JSON",
"help":"For more information on API status codes and how to handle them,
read the docs on errors: https://asana.com/developers/documentation/getting-started/errors"}
]}`
Here's my code:
testTask(){
var taskName = "Test Name for a Test Task"
var workspaceID = "123456789"
var projectID = "123456789"
var assigneeID = "123456789"
var parentID = null
this.createTask(taskName, workspaceID, projectID, assigneeID, parentID)
}
createTask(taskName, workspaceID, projectID, assigneeID, parentID){
var token = "0/1234abcd5678efgh9102ijk"
var bearerToken = "Bearer " + token
var task = {
data: {
assignee: "me",
notes: "test test test test",
workspace: workspaceID,
name: taskName,
projects: [projectID],
parent: parentID
}
}
var options = {
"method" : "POST",
"headers" : {"Authorization": bearerToken},
"contentType": "application/json",
"payload" : JSON.stringify(task)
}
try {
var url = "https://app.asana.com/api/1.0/tasks";
request.post(url, options, function optionalCallback(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
}
catch (e) {
console.log(e);
}
}
I also tried a different implementation :
createTask(){
var token = "0/1234abcd5678efgh9102ijk"
var bearerToken = "Bearer " + token
var options = {
"method" : "POST",
"headers" : {"Authorization": bearerToken},
}
try {
request.post("https://app.asana.com/api/1.0/tasks?workspace=1234567&projects=765534432&parent=null&name=taskName&assignee=me", options, function optionalCallback(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
}
catch (e) {
console.log(e);
}
}
Based on the examples provided by the request module, it appears that your options object uses payload as a key, but it should be body.
This is my first post on SO so I hope I'm doing this correctly. I have a Google Apps Script that is being used with as a web hook to create an integration between two services: YouCanBook.Me and Taleo. The script was published as a web app with the "Anyone, even anonymous" access and was working for weeks. Recently (as of 2/3/14 I believe) it stopped working and now navigating to the public URL results in the following error message:
Google Drive encountered an error. If reloading the page doesn't help, please report the error.
To learn more about Google Drive, please visit our help center.
We're sorry for the inconvenience. Thanks for your help!
- The Google Drive Team
Here is the code for the entire script:
function doGet(request) {
try {
//Get token data from URL parameters
var candidateID = request.parameter.candID;
var requisitionID = request.parameter.reqID;
var interviewType = request.parameter.intType;
var requestType = request.parameter.request;
}
catch(e) {
Logger.log('Unable to capture required parameters. Error message: ' + e);
return;
}
//Get authToken by passing in credentials
var authToken = taleoLogin();
//Get candidate application ID
var candidateApplicationID = getCandidateApplicationID(authToken, candidateID, requisitionID);
//Make PUT request to change candidate's status
taleoSubmit(authToken, candidateID, requisitionID, candidateApplicationID, interviewType, requestType);
//Logout
taleoLogout(authToken);
}
function getCandidateApplicationID(authToken, candidateID, requisitionID) {
//Build API call
var loginURL = 'https://ch.tbe.taleo.net/CH06/ats/api/v1/object/candidateapplication?candidateId=' + candidateID + '&requisitionId=' + requisitionID;
var loginOptions = {
'method' : 'get',
'headers' : {
'cookie' : authToken
},
'contentType' : 'application/json; charset=utf-8'
};
//Make API call
try {
var loginResponse = UrlFetchApp.fetch(loginURL, loginOptions);
if (loginResponse.getResponseCode() == 200) {
Logger.log('Logged in!');
}
else {
Logger.log('Error logging in: ' + loginResponse.getContentText());
}
}
catch (e) {
Logger.log('Could not log in: ' + e);
}
//Return candidate application ID
return candidateApplicationID = JSON.parse(loginResponse).response.candtoreqs[0].candidateapplication.id.toFixed(0);
}
//-----------------------------------//
// Log into Taleo via the REST API //
//-----------------------------------//
function taleoLogin() {
//Build API call
var loginURL = 'https://ch.tbe.taleo.net/CH06/ats/api/v1/login?orgCode=[companyCode]&userName=[username]&password=[password]';
var loginOptions = {
'method' : 'post',
'contentType' : 'application/json'
};
//Make API call
try {
var loginResponse = UrlFetchApp.fetch(loginURL, loginOptions);
if (loginResponse.getResponseCode() == 200) {
Logger.log('Logged in!');
}
else {
Logger.log('Error logging in: ' + loginResponse.getContentText());
}
}
catch (e) {
Logger.log('Could not log in: ' + e);
}
//Return full authToken key
return authToken = 'authToken=' + JSON.parse(loginResponse).response.authToken;
}
//-------------------------------------//
// Log out of Taleo via the REST API //
//-------------------------------------//
function taleoLogout(authToken) {
//Build API call
var logoutURL = 'https://ch.tbe.taleo.net/CH06/ats/api/v1/logout';
var logoutOptions = {
'method' : 'post',
'headers' : {
'cookie' : authToken
},
'contentType' : 'application/json; charset=utf-8'
};
//Make API call
try {
var logoutResponse = UrlFetchApp.fetch(logoutURL, logoutOptions);
if (logoutResponse.getResponseCode() == 200) {
Logger.log('Logged out!');
}
else {
Logger.log('Error logging out: ' + logoutResponse.getContentText());
}
}
catch (e) {
Logger.log('Could not log out: ' + e);
}
}
//-----------------------------------------//
// Submit data to Taleo via the REST API //
//-----------------------------------------//
function taleoSubmit(authToken, candID, reqID, appID, intType, requestType) {
//If phone interview and initial booking
if(intType == 'phone' && requestType == 'booking') {
//Build API call
try {
var submitURL = 'https://ch.tbe.taleo.net/CH06/ats/api/v1/object/candidateapplication/' + appID;
var payload = JSON.stringify({ "candidateapplication" : { "candidateId" : candID, "requisitionId" : reqID, "status" : 5033 }});
var submitOptions = {
'method' : 'put',
'headers' : {
'cookie' : authToken
},
'contentType' : 'application/json; charset=utf-8',
'payload' : payload
};
}
catch (e) {
Logger.log('Error creating API call: ' + e);
}
}
else if(intType == 'final' && requestType == 'booking') {
//Build API call
try {
var submitURL = 'https://ch.tbe.taleo.net/CH06/ats/api/v1/object/candidateapplication/' + appID;
var payload = JSON.stringify({ "candidateapplication" : { "candidateId" : candID, "requisitionId" : reqID, "status" : 5048 }});
var submitOptions = {
'method' : 'put',
'headers' : {
'cookie' : authToken
},
'contentType' : 'application/json; charset=utf-8',
'payload' : payload
};
}
catch (e) {
Logger.log('Error creating API call: ' + e);
}
}
else if(intType == 'phone' && requestType == 'cancel') {
//Build API call
try {
var submitURL = 'https://ch.tbe.taleo.net/CH06/ats/api/v1/object/candidateapplication/' + appID;
var payload = JSON.stringify({ "candidateapplication" : { "candidateId" : candID, "requisitionId" : reqID, "status" : 5032 }});
var submitOptions = {
'method' : 'put',
'headers' : {
'cookie' : authToken
},
'contentType' : 'application/json; charset=utf-8',
'payload' : payload
};
}
catch (e) {
Logger.log('Error creating API call: ' + e);
}
}
else if(intType == 'final' && requestType == 'cancel') {
//Build API call
try {
var submitURL = 'https://ch.tbe.taleo.net/CH06/ats/api/v1/object/candidateapplication/' + appID;
var payload = JSON.stringify({ "candidateapplication" : { "candidateId" : candID, "requisitionId" : reqID, "status" : 5047 }});
var submitOptions = {
'method' : 'put',
'headers' : {
'cookie' : authToken
},
'contentType' : 'application/json; charset=utf-8',
'payload' : payload
};
}
catch (e) {
Logger.log('Error creating API call: ' + e);
}
}
//Make API call
try {
var submitResponse = UrlFetchApp.fetch(submitURL, submitOptions);
if (submitResponse.getResponseCode() == 200) {
Logger.log('Results submitted!');
}
else {
Logger.log('Error submitting results: ' + submitResponse.getContentText());
}
}
catch (e) {
Logger.log('Could not submit results: ' + e);
}
}