Generating zoho ticket using google apps script - google-apps-script

I am trying to use zoho desk api in google apps script.
I am trying to genereate ticket through google script.But getting error.
Whereas if I do it in PHP its working fine.
Please find both codes for reference:
PHP CODE which is working
$auth_token = '12345ab';//your_auth_token
$org_id=12345; //your_organization_id
$ticket_data=array(
"departmentId"=>$getdepartmentid,
"contactId"=>$getcontactid,
"subject"=>$ticket_subject,
"description"=>$ticket_desc,
"priority"=>$priority,
"status"=>$ticketstatus,
"email"=>$contact_email,
"classification"=>$classification,
"channel"=>"Application"
);
$headers=array(
"Authorization: $auth_token",
"orgId: $org_id",
"contentType: application/json; charset=utf-8",
);
$url="https://desk.zoho.in/api/v1/tickets";
$ticket_data=(gettype($ticket_data)==="array")? json_encode($ticket_data):$ticket_data;
$ch= curl_init($url);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
curl_setopt($ch,CURLOPT_POST,TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS,$ticket_data); //convert ticket data array to json
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response= curl_exec($ch);
$info= curl_getinfo($ch);
GOOGLE APPS SCRIPT(which is not working)
var authtoken = "12345ab"; //your_auth_token
var org_id=12345; //your_organization_id
var department=23220000000057620; // ID of department
var contact=23220000000066959; //ID of customer
var subject=location_urgent_inbox_folder_name + ' /' + Name_of_file_to_be_attached;
var description="Ticked via drive";
var status="open";
const ticketData = {
subject: subject,
departmentId: department, // Replace this with whatever yours is.
contactId: contact, // Replace this with whatever yours is.
description: description,
status: status
};
const zohoUrl = 'https://desk.zoho.in/api/v1/tickets';
try {
var response = UrlFetchApp.fetch(zohoUrl, {
"method": 'POST',
"muteHttpExceptions": true,
"headers": {
Authorization: authtoken,
orgId: org_id,
contentType: 'application/json',
},
"payload": JSON.stringify(ticketData),
});
Logger.log(response.getContentText());
const parsed = JSON.parse(response.getContentText());
} catch (error) {
Logger.log(error.toString());
}

Assuming I am looking at the right section of the right documentation (https://desk.zoho.com/DeskAPIDocument#Tickets_Createaticket), I think these are your issues:
Server's JSON-encoded response contains no message property, hence Logger.log(result.message); logs undefined. (Maybe trying logging response.getContentText() to see what properties are available in your case -- or refer to the API documentation.)
Authorization and orgId headers are missing in the request you send. (Looks like authtokens are deprecated (https://desk.zoho.com/DeskAPIDocument#Authentication) and you instead need to use OAuth 2.0 (https://desk.zoho.com/DeskAPIDocument#OauthTokens).)
Data needs to be sent in request's body. (You appear to be sending it in the query string.)
I've not read the documentation in detail but I don't see any mention of query string parameters authtoken and JSONString (CTRL+F returns no matches). So you might want to get rid of them in your code and instead follow what the documentation says.
The code below is untested and won't work (as you need to replace with your own credentials). But it should give you an idea of how you can accomplish this.
// See: https://desk.zoho.com/DeskAPIDocument#Tickets#Tickets_Createaticket
// Required: subject, departmentId, contactId
const ticketData = {
subject: location_urgent_inbox_folder_name + ‘ /’ + Name_of_file_to_be_attached, // Taken from your question. Presume these are declared, valid and in scope.
departmentId: '12345', // Replace this with whatever yours is.
contactId: '12345', // Replace this with whatever yours is.
description: 'Ticked via drive',
status: 'open'
};
const zohoUrl = 'https://desk.zoho.in/api/v1/tickets';
try {
// See: https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetchurl,-params
const response = UrlFetchApp.fetch(zohoUrl, {
method: 'POST',
contentType: 'application/json',
headers: {
orgId: '12345' // Replace this with whatever yours is.
Authorization: 'Zoho-oauthtoken ....' // See: https://desk.zoho.com/DeskAPIDocument#OauthTokens
},
payload: JSON.stringify(ticketData),
});
Logger.log(response.getContentText());
const parsed = JSON.parse(response.getContentText());
} catch (error) {
Logger.log(error.toString());
}
I've never worked with any of Zoho's APIs and haven't worked with Google Apps Script for a while, so apologies if I'm missing something.

Issue resolved,
Posting answer so that it might help someone
//create ticket in zoho
var authtoken = "abcd"; //your_auth_token
var org_id="12345"; //your_organization_id
var department="54321"; // ID of department in which ticket to be raised
var contact="9999"; //ID of customer
var subject="Ticket via google script";
var description="Ticket via google script";
var status="open";
const ticketData = {
subject: subject,
departmentId: department, // Replace this with whatever yours is.
contactId: contact, // Replace this with whatever yours is.
description: description,
status: status
};
const zohoUrl = 'https://desk.zoho.in/api/v1/tickets';
try {
var response = UrlFetchApp.fetch(zohoUrl, {
"method": 'POST',
"muteHttpExceptions": true,
"headers": {
Authorization: authtoken,
orgId: org_id,
contentType: 'application/json',
},
"payload": JSON.stringify(ticketData),
});
const parsed = JSON.parse(response.getContentText());
} catch (error) {
Logger.log(error.toString());
}

Related

POST requests with the Coinbase Pro API using Google Apps Script

I'm working with the Coinbase Pro API and while it's working well for GET requests I'm getting an "Invalid signature" when I try a POST request to place an order. I suspect that this may be something related to the "body" of the message since this is the only difference with the GET where "body" is empty.
I'm wondering if someone can help me on this.
function SellMarket (product,amount) {
var requestPath = '/orders';
var method = 'POST';
var body = JSON.stringify({
"type": "market",
"side": "buy",
"product_id": product,
//"size": amount,
'size': '1.0'
});
Logger.log('Sell - Body = '+body);
var responseJson = SignAndCallAPI(method, requestPath, body);
Logger.log('Sell Executed = '+responseJson);
}
function SignAndCallAPI(method, requestPath, body) {
var timestamp = Math.floor(Date.now() / 1000).toString();
var what = Utilities.base64Decode(Utilities.base64Encode(timestamp + method + requestPath + body));
var decodedsecret = Utilities.base64Decode(globalvars_CB.secret);
var hmac = Utilities.base64Encode(Utilities.computeHmacSha256Signature(what, decodedsecret));
var options = {
'method' : method,
'muteHttpExceptions' : true,
'headers' : {
'Content-Type': 'application/json',
'CB-ACCESS-KEY' : globalvars_CB.apikey,
'CB-ACCESS-SIGN' : hmac,
'CB-ACCESS-TIMESTAMP' : timestamp,
'CB-ACCESS-PASSPHRASE' : globalvars_CB.passphrase,
}
}
var responseJson = UrlFetchApp.fetch(globalvars_CB.uri+requestPath, options);
return(responseJson);
}
Untested suggestion, I recommend changing this bit in your code (in SignAndCallAPI function):
var options = {
'method' : method,
'muteHttpExceptions' : true,
'headers' : {
'Content-Type': 'application/json',
'CB-ACCESS-KEY' : globalvars_CB.apikey,
'CB-ACCESS-SIGN' : hmac,
'CB-ACCESS-TIMESTAMP' : timestamp,
'CB-ACCESS-PASSPHRASE' : globalvars_CB.passphrase,
}
}
to:
const options = {
method: method,
payload: body,
contentType: 'application/json',
muteHttpExceptions: true,
headers: {
'CB-ACCESS-KEY': globalvars_CB.apikey,
'CB-ACCESS-SIGN': hmac,
'CB-ACCESS-TIMESTAMP': timestamp,
'CB-ACCESS-PASSPHRASE': globalvars_CB.passphrase,
},
};
due to the reasons below:
Although you pass body to SignAndCallAPI function and use body in HMAC computation, you don't appear to actually include body in the POST request sent to the server. I was expecting to see it as the value to a payload property of your options object.
UrlFetchApp documentation (https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#fetchurl,-params) seems to indicate that Content-Type should be specified in the contentType property of your options object (as opposed to explicitly including a Content-Type header).
I've not looked at the Coinbase API documentation in detail (https://docs.pro.coinbase.com/#place-a-new-order), but body seems okay. You'll also want to make sure the HMAC computation for the CB-ACCESS-SIGN request header is as described in the documentation (https://docs.pro.coinbase.com/#signing-a-message).

Invalid customer.address object error when trying to create new Stripe customers in Google Script

I'm trying to automate the creation and updating of customers on my stripe account with a Google Script, but when passing the customer object, even though it seems to align with the structure laid out in the docs I receive a 400 error response from the Stripe API stating the address object is invalid.
Current Function: (for POSTing the customer object to the Stripe API)
function SendCustomer(details) {
// determine endpoint based on if sheet row has stripe_customer_id value
var endpoint;
if (details.stripe_customer_id && details.stripe_customer_id.length() > 0) {
// We're updating an existing customer
endpoint = CUSTOMERS_ENDPOINT + '/' + details.stripe_customer_id;
} else {
// We're creating a new customer
endpoint = CUSTOMERS_ENDPOINT;
}
var cust = {
'address': JSON.stringify({
'line1': details.street,
'line2': '',
'city': details.city,
'state': details.state,
// Google Sheets holds a Number, so convert to String as required by Stripe API
'postal_code': details.postal_code ? details.postal_code.toString() : details.postal_code,
'country': 'US'
}),
'email': details.email,
'phone': details.phone_cell,
'name': details.fname + ' ' + details.lname
}
Logger.log(cust);
var options = {
'method' : 'post',
'headers': {
'Authorization': 'Bearer ' + API_KEY
},
'payload' : cust
};
var cust_response = UrlFetchApp.fetch(endpoint, options)
var json_response = JSON.parse(cust_response.getContentText());
return json_response.id
}
Error Message when running the above function:
"error": {
"message": "Invalid object",
"param": "address",
"type": "invalid_request_error"
}
What am I doing wrong? From what I can tell, I'm following the defined structure of the customer.address object per the API docs. Could it be the way that UrlFetchApp.fetch() is sending the payload that's messing it up? If so, how can I fix it?
After trying many different methods, I finally figured out how to properly construct any nested object (such as the address object in this case) to be sent correctly to the Stripe API through Google Apps Scripts. Catching this line in the UrlFetchApp documentation, gave me the idea on how to handle the construction of the customer.address object so that it's parsed correctly on Stripe's end.
payload - Description: "...A JavaScript object is interpreted as a
map of form field names to values, where the values can be either
strings or blobs."
This reminded me of how I saw other form data posted through various services when viewing them in the Chrome Developer Console. So, using that clue I was able to construct the proper structure as such:
var cust = {
'address[line1]': details.street,
'address[line2]': '',
'address[city]': details.city,
'address[state]': details.state,
'address[postal_code]': details.postal_code ? details.postal_code.toString() : details.postal_code,
'address[country]': 'US',
'email': details.email,
'phone': details.phone_cell,
'name': details.fname + ' ' + details.lname
}
Logger.log(cust);
var options = {
'method' : 'POST',
'content-type': 'application/x-www-form-urlencoded',
'headers': {
'Authorization': 'Bearer ' + API_KEY,
},
'payload' : cust
};
var cust_response = UrlFetchApp.fetch(endpoint, options)
var json_response = JSON.parse(cust_response.getContentText());

Calling third party JIRA REST API in Cloud Function for Dialogflow always timeout

We need to call JIRA Rest API to get a specific information from the given query in Dialogflow.
We need to provide response to user based on the response from the API. However, the Dialogflow is unable to retrieve any response from JIRA API through the fulfillment in Firebase Cloud function as it's always timeout.
Based on the log in Firebase console, it always take more than 6000 ms for the execution.
Meanwhile if I use postman to call the JIRA REST API, it takes less than 1 second to get the response.
Some said we need to use promise but I does not seem to work as well.
Please help how should I solve this problem?
Please see my code below
function checkcontract(agent){
var parameters = request.body.queryResult.parameters;
var customer_id = parameters.customer_id;
var bodyData = JSON.stringify({"jql": "project = CDB AND 'Customer ID' ~ "+customer_id,
"maxResults": 1,
"fieldsByKeys": false,
"fields": [
"summary",
"customfield_11949", //Customer ID custom field
"customfield_11937", // Contract Start Date
"customfield_11938", //Contract End Date
"customfield_11936", //email
"customfield_11946", //default JSD request id
"customfield_11943", //project id
"customfield_11941" //project key
],
"startAt": 0
});
var options = {
method: 'POST',
url: '/rest/api/3/search',
auth: { bearer: authorization_token },
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: bodyData
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(
'Response: ' + response.statusCode + ' ' + response.statusMessage
);
console.log(body);
});
}
EDIT:
JIRA API returns a response to the function. But the agent.add("message") does not return anything to the chat.

Google Sheets - Mailchimp API - Create Template

WHAT I AM TRYING TO DO:
I am trying to create a template (custom HTML) using Mailchimp API according to this documentation.
WHAT I HAVE TRIED SO FAR:
Took raw HTML of the template I created using 'drag-and-drop'. Tested it using 'code-your-own'. Saved in a variable in apps script. Used to the following code, with data set as that variable. I got the following error
{instance=2fb8b5eb-f11c-4260-a958-f16e5bc7c98b, detail=The resource submitted could not be validated. For field-specific details, see the 'errors' array., type=http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/, title=Invalid Resource, errors=[{field=, message=Schema describes object, NULL found instead}], status=400}
I then set the data to simpler HTML as shown below. I got the same error.
I tried using an already created template (accessed through TEMPLATE_ID) and tried to edit that (just the name of the template). I got the same error though I am able to access the template. The changes I made were:
var TEMPLATE_ID = 'MY_TEMPLATE_ID';
var endpoint = 'templates/' + TEMPLATE_ID;
var data = {
'name': 'new test name'
}
In params
'method': 'PATCH'
I also tried to GET method to see the templates, campaigns, lists. I am successfully able to do that.
I looked up the various answers on SO, one of them suggested using mergefields, I tried it too with the same error.
var data = {
'name': 'Test Template',
'html': '<html><head></head><body><p>TEST</p><body></html>',
'mergefields': {}
};
MWE:
function mailchimpCampaign(){
// URL and params for the Mailchimp API
var root = 'https://us19.api.mailchimp.com/3.0/';
var endpoint = 'templates';
var data = {
'name': 'Test Template',
'html': '<html><head></head><body><p>TEST</p><body></html>'
};
var payload = JSON.stringify(data);
// parameters for url fetch
var params = {
'method': 'POST',
'muteHttpExceptions': true,
'headers': {
'Authorization': 'apikey ' + API_KEY,
'content-type': 'application/json'
},
'data': payload
};
try {
// call the Mailchimp API
var response = UrlFetchApp.fetch(root + endpoint, params);
var data = response.getContentText();
var json = JSON.parse(data);
Logger.log(json);
}
catch (error) {
// deal with any errors
Logger.log(error);
};
}
Any help will be appreciated. Thanks.
This is for future readers.
So while I was hitting my head on this error. I tried using UrlFetchApp.getRequest() and it showed me that payload was empty.
The problem was I had to payload instead of data that I was using.
Updated working code:
var params = {
'method': 'POST',
'muteHttpExceptions': true,
'headers': {
'Authorization': 'apikey ' + API_KEY,
'content-type': 'application/json'
},
'payload': payload
};

How to send a JSON payload with UrlFetchApp service?

I'm trying to POST to a web service that is expecting to get JSON as payload using Google Apps Script. I'm using the following code:
var options =
{
"method" : "post",
"contentType" : "application/json",
"headers" : {
"Authorization" : "Basic <Base64 of user:password>"
},
"payload" : { "endDate": "2012-06-03" }
};
var response = UrlFetchApp.fetch("http://www.example.com/service/expecting/json", options);
On the server side I'm getting the following error:
WARN [facade.SettingsServlet] 04 Jun 2012 15:30:26 - Unable to parse request body: endDate=2012-06-03
net.liftweb.json.JsonParser$ParseException: unknown token e
I'm assuming that the server is expecting to get
{ "endDate": "2012-06-03" }
instead of
endDate=2012-06-03
but I don't know how to make the UrlFetchApp do it.
I do not understand the server side error but the 'payload' parameter must be a string as specified here: https://developers.google.com/apps-script/class_urlfetchapp?hl=fr-FR#fetch.
try:
var options =
{
"method" : "post",
"contentType" : "application/json",
"headers" : {
"Authorization" : "Basic <Base64 of user:password>"
},
"payload" : '{ "endDate": "2012-06-03" }'
};
If you set payload as a String, it will be passed directly (as a
UTF-8 string).
If you set payload as an Object, it will be sent like
an HTML form (which means either 'application/x-www-form-urlencoded' if the
fields are simple, or 'multipart/form-data' if the Object includes a
blob/file).
For your use case (the server is expecting to receive JSON), it sounds like Utilities.jsonStringify() is the way to go.
Something like this worked for me in a similar situation:
Instead of creating payload and adding to options, I built the parameters into a string to append to the URL:
var params = "id=2179853&price=62755";
then, I appended params to the url string:
var result = UrlFetchApp.getRequest(url + '?' + params, options);
So, my options was passed containing only the header.
For my project, this worked like a charm.
Here goes the code that should work with some important comments:
function testMe() {
var products_authkey = "------------";
try {
var url = "https://app.ecwid.com/api/v1/---------/product?id=----------&secure_auth_key=" + products_authkey;
//url= "http://requestb.in/----------"; // you can actually debug what you send out with PUTs or POSTs using Requestb.in service
var payload = {
id: "21798583", // id is necessary and should be a string, or it might be sent in scientific representation (with E)
price: 62755
};
payload = JSON.stringify(payload); // the payload needs to be sent as a string, so we need this
var options = {
method: "put",
contentType: "application/json", // contentType property was mistyped as ContentType - case matters
payload: payload
};
var result = UrlFetchApp.getRequest(url, options);
Logger.log(result) // a better way to debug
var result = UrlFetchApp.fetch(url, options); // works perfectly in my case
Logger.log(result)
} catch (e) {
Logger.log(e)
}
}