I try to use google apps script to create ticket with attachments via freshdesk API.
Freshdesk have google app script sample code here: https://github.com/freshdesk/fresh-samples/tree/master/google_script , but without attachment demo.
I tried the following code, but it seems always return error by /helpdesk/tickets.json api.
how to post a attachment in google app script with UrlFetchApp right?
function createFreshdeskTicketWithAttachments() {
var API_KEY = PropertiesService.getScriptProperties().getProperty('FreshDeskApiKey')
if (!API_KEY) throw new Error('FreshDeskApiKey not found in script properties.')
var ENDPOINT = Utilities.formatString('https://%s.freshdesk.com', 'zixia')
var headers = {
'Authorization': 'Basic ' + Utilities.base64Encode(API_KEY + ':X')
, 'Content-type': 'application/json'
//'Content-type': 'multipart/form-data'
};
var response = UrlFetchApp.fetch("https://circleci.com/gh/AKAMobi/ucapp/tree/master.svg?style=svg")
var fileBlob = response.getBlob()
Logger.log("%s:%s"
, response.getResponseCode()
, fileBlob.getContentType()
)
var payload = {
helpdesk_ticket: {
description: 'TEST 4'
, subject: "TEST 4"
, email: "test#test.com"
, priority: 1
, status: 2
, attachments: { '': [ { resource: fileBlob } ] }
}
}
//Adds the extensions that are needed to post a new ticket to the end of the url
var url = ENDPOINT + '/helpdesk/tickets.json';
var options = {
'method': 'post',
'headers': headers,
'payload': JSON.stringify(payload),
// 'payload': payload,
muteHttpExceptions: true
};
var response = UrlFetchApp.fetch(url, options);
Logger.log('resp: %s, %s'
, response.getResponseCode()
, response.getContentText()
)
}
after use debug with nc:
nc -l 211.99.222.55 3333
I found payload array should write like this:
var payload = {
'helpdesk_ticket[description]': 'test jjjj'
, 'helpdesk_ticket[subject]': 'test jj'
, 'helpdesk_ticket[email]': 'test#test.com'
, 'helpdesk_ticket[attachments][][resource]': fileBlob1
, 'helpdesk_ticket[attachments][][resource]': fileBlob2
}
but fileBlob2 will not post to server, because the key of array is duplicated. I tried to change 'helpdesk_ticket[attachments][][resource]' to 'helpdesk_ticket[attachments][1][resource]' but it did not work.
so here's a workable version, which only support single attachment:
function createTicket() {
var API_KEY = PropertiesService.getScriptProperties().getProperty('FreshDeskApiKey')
if (!API_KEY) throw new Error('FreshDeskApiKey not found in script properties.')
var ENDPOINT = Utilities.formatString('https://%s.freshdesk.com', 'zixia')
var headers = {
'Authorization': 'Basic ' + Utilities.base64Encode(API_KEY + ':X')
}
var response = UrlFetchApp.fetch("https://circleci.com/gh/AKAMobi/ucapp/tree/master.svg?style=svg")
var fileBlob1 = response.getBlob()
var fileBlob2 = UrlFetchApp
.fetch("http://imgcache.qq.com/open_proj/proj_qcloud_v2/qcloud_2015/css/img/global/internet-plus.png")
.getBlob()
var payload = {
'helpdesk_ticket[description]': 'test jjjj'
, 'helpdesk_ticket[subject]': 'test jj'
, 'helpdesk_ticket[email]': 'test#test.com'
, 'helpdesk_ticket[attachments][][resource]': fileBlob1
, 'helpdesk_ticket[attachments][][resource]': fileBlob2
}
//
// for (var i=0; i<attachments.length; i++) {
// payload['helpdesk_ticket[attachments][][resource]'] = attachments[i]
// }
//
// for (var k in payload) {
// Logger.log('%s = %s', k, payload[k])
// }
var options = {
'method': 'post'
, 'headers': headers
, 'payload': payload
, muteHttpExceptions: true
}
var url = ENDPOINT + '/helpdesk/tickets.json'
// url = 'http://211.99.222.55:3333'
var response = UrlFetchApp.fetch(url, options)
Logger.log('resp: %s, %s'
, response.getResponseCode()
, response.getContentText()
)
}
UPDATE Jan 20th, 2016
I wrote a library named GasFreshdesk for freshdesk v2 api in gas, which is very easy to use(with attachments support):
var MyFreshdesk = new GasFreshdesk('https://domain.freshdesk.com', 'TOKEN')
var ticket = new MyFreshdesk.Ticket({
description:'A description'
, subject: 'A subject'
, email: 'you#example.com'
, attachments: [
Utilities.newBlob('TEST DATA').setName('test-data.dat')
, Utilities.newBlob('TEST DATA2').setName('test-data2.dat')
]
})
ticket.assign(9000658396)
ticket.note({
body: 'Hi tom, Still Angry'
, private: true
, attachments: [
Utilities.newBlob('TEST DATA').setName('test-data.dat')
, Utilities.newBlob('TEST DATA2').setName('test-data2.dat')
]
})
ticket.reply({
body: 'Hi tom, Still Angry'
, cc_emails: ['you#example.com']
, attachments: [
Utilities.newBlob('TEST DATA').setName('test-data.dat')
, Utilities.newBlob('TEST DATA2').setName('test-data2.dat')
]
})
ticket.setPriority(2)
ticket.setStatus(2)
ticket.del()
ticket.restore()
Logger.log('ticket #' + ticket.getId() + ' was set!')
GasFreshdesk Github: https://github.com/zixia/gas-freshdesk
OLD POST:
finnaly, google apps script could attach multi attachments to new ticket on freshdesk by UrlFetchApp.fetch, with a hand made 'multipart' param generator helper function by myself.
put attachments in another array payload:
var payload = [
['helpdesk_ticket[description]', 'test jjjj']
, ['helpdesk_ticket[subject]', 'test jj']
, ['helpdesk_ticket[email]', 'test#test.com']
, ['helpdesk_ticket[attachments][][resource]', fileBlob2]
, ['helpdesk_ticket[attachments][][resource]', fileBlob1]
]
use makeMultipartBody function to generate a requestBody:
var multipartBody = makeMultipartBody(payload)
full code here:
function createTicket2() {
var API_KEY = PropertiesService.getScriptProperties().getProperty('FreshDeskApiKey')
if (!API_KEY) throw new Error('FreshDeskApiKey not found in script properties.')
var ENDPOINT = Utilities.formatString('https://%s.freshdesk.com', 'zixia')
var headers = {
'Authorization': 'Basic ' + Utilities.base64Encode(API_KEY + ':X')
}
var response = UrlFetchApp.fetch("https://circleci.com/gh/AKAMobi/ucapp/tree/master.svg?style=svg")
var fileBlob1 = response.getBlob()
var fileBlob2 = UrlFetchApp
.fetch("http://imgcache.qq.com/open_proj/proj_qcloud_v2/qcloud_2015/css/img/global/internet-plus.png")
.getBlob()
var payload = [
['helpdesk_ticket[description]', 'test jjjj']
, ['helpdesk_ticket[subject]', 'test jj']
, ['helpdesk_ticket[email]', 'test#test.com']
, ['helpdesk_ticket[attachments][][resource]', fileBlob2]
, ['helpdesk_ticket[attachments][][resource]', fileBlob1]
]
var boundary = '-----CUTHEREelH7faHNSXWNi72OTh08zH29D28Zhr3Rif3oupOaDrj'
payload = makeMultipartBody(payload, boundary)
//Logger.log('payload: %s', payload)
//return
var options = {
'method': 'post'
, contentType: "multipart/form-data; boundary=" + boundary
, 'headers': headers
, 'payload': payload
, muteHttpExceptions: true
}
var url = ENDPOINT + '/helpdesk/tickets.json'
// url = 'http://211.99.222.55:3333'
var response = UrlFetchApp.fetch(url, options)
Logger.log('resp: %s, %s'
, response.getResponseCode()
, response.getContentText()
)
}
function makeMultipartBody(payload, boundary) {
var body = Utilities.newBlob('').getBytes()
Logger.log(payload)
for (var i in payload) {
var [k, v] = payload[i]
Logger.log('############ %s = %s', k, v)
if (v.toString() == 'Blob') {
// attachment
body = body.concat(
Utilities.newBlob(
'--' + boundary + '\r\n'
+ 'Content-Disposition: form-data; name="' + k + '"; filename="' + v.getName() + '"\r\n'
+ 'Content-Type: ' + v.getContentType() + '\r\n\r\n'
).getBytes())
body = body
.concat(v.getBytes())
.concat(Utilities.newBlob('\r\n').getBytes())
} else {
// string
body = body.concat(
Utilities.newBlob(
'--'+boundary+'\r\n'
+ 'Content-Disposition: form-data; name="' + k + '"\r\n\r\n'
+ v + '\r\n'
).getBytes()
)
}
}
body = body.concat(Utilities.newBlob("\r\n--" + boundary + "--\r\n").getBytes())
return body
}
Related
I create a PDF and then send its information to my website so that this PDF is converted to an image file and published:
SpreadsheetApp.flush();
var theurl = 'https://docs.google.com/a/mydomain.org/spreadsheets/d/' +
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +
'/export?format=pdf' +
'&size=0' +
'&portrait=true' +
'&fitw=true' +
'&top_margin=0' +
'&bottom_margin=0' +
'&left_margin=0' +
'&right_margin=0' +
'&sheetnames=false&printtitle=false' +
'&pagenum=false' +
'&gridlines=false' +
'&fzr=FALSE' +
'&gid=' +
'aaaaaaaaaaa';
var token = ScriptApp.getOAuthToken();
var docurl = UrlFetchApp.fetch(theurl, { headers: { 'Authorization': 'Bearer ' + token } });
var pdfBlob = docurl.getBlob();
//...get token and Blob (do not create the file);
var fileName = ss.getSheetByName("General").getRange("H2").getValue();
//Access or create the 'Archives' folder;
var folder;
var folders = DriveApp.getFoldersByName("Archives");
if(folders.hasNext()) {
folder = folders.next();
}else {
folder = DriveApp.createFolder("Archives");
}
//Remove duplicate file with the same name;
var existing = folder.getFilesByName(fileName);
if(existing.hasNext()) {
var duplicate = existing.next();
if (duplicate.getOwner().getEmail() == Session.getActiveUser().getEmail()) {
var durl = 'https://www.googleapis.com/drive/v3/files/'+duplicate.getId();
var dres = UrlFetchApp.fetch(durl,{
method: 'delete',
muteHttpExceptions: true,
headers: {'Authorization': 'Bearer '+token}
});
var status = dres.getResponseCode();
if (status >=400) {
} else if (status == 204) {
folder.createFile(pdfBlob.setName(fileName));
}
}
} else {
folder.createFile(pdfBlob.setName(fileName));
}
Utilities.sleep(5000);
createPostByFileName(folder, fileName);
function createPostByFileName(folder, fileName) {
var fileIterator = folder.getFilesByName(fileName);
if(fileIterator.hasNext()) {
var file = fileIterator.next()
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW)
name = file.getName();
league = name.split(' ')[0];
title = name.split(league)[1].split('.pdf')[0];
link = file.getUrl();
shareable = link.split('/view')[0];
id = file.getId();
var data = {
'api_league_name': league,
'title': title,
'google_drive_id': id,
'google_drive_url': shareable,
'pass': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
};
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : JSON.stringify(data)
};
UrlFetchApp.fetch('https://www.xxx.com.br/api/posts', options);
}
}
For some reason I am forced to put Utilities.sleep(5000); before calling the function that sends the PDF data to my website, because if I don't, when the website tries to convert the PDF to an image, an problem happens as if the PDF is not yet available in the folder or it generates a big slowdown until can access the file.
Obviously putting this sleep is not a professional way to solve the case, because then I can't even know why this happens.
Anyone who has had this experience, can tell me how I should proceed in a professional way?
From the discussions in the comment, when Drive API is used for your script, it becomes as follows. Before you use this, please enable Drive API at Advanced Google services.
Modified script:
function sample() {
const createFile = (filename, blob, folderId) => Drive.Files.insert({ title: filename, parents: [{ id: folderId }] }, blob);
SpreadsheetApp.flush();
var theurl = 'https://docs.google.com/a/mydomain.org/spreadsheets/d/' +
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' +
'/export?format=pdf' +
'&size=0' +
'&portrait=true' +
'&fitw=true' +
'&top_margin=0' +
'&bottom_margin=0' +
'&left_margin=0' +
'&right_margin=0' +
'&sheetnames=false&printtitle=false' +
'&pagenum=false' +
'&gridlines=false' +
'&fzr=FALSE' +
'&gid=' +
'aaaaaaaaaaa';
var token = ScriptApp.getOAuthToken();
var docurl = UrlFetchApp.fetch(theurl, { headers: { 'Authorization': 'Bearer ' + token } });
var pdfBlob = docurl.getBlob();
var fileName = ss.getSheetByName("General").getRange("H2").getValue();
var folder;
var folders = DriveApp.getFoldersByName("Archives");
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder("Archives");
}
var existing = folder.getFilesByName(fileName);
var pdfFileId = "";
if (existing.hasNext()) {
var duplicate = existing.next();
if (duplicate.getOwner().getEmail() == Session.getActiveUser().getEmail()) {
var durl = 'https://www.googleapis.com/drive/v3/files/' + duplicate.getId();
var dres = UrlFetchApp.fetch(durl, {
method: 'delete',
muteHttpExceptions: true,
headers: { 'Authorization': 'Bearer ' + token }
});
var status = dres.getResponseCode();
if (status >= 400) {
} else if (status == 204) {
var obj = createFile(fileName, pdfBlob, folder.getId());
pdfFileId = obj.id;
}
}
} else {
var obj = createFile(fileName, pdfBlob, folder.getId());
pdfFileId = obj.id;
}
// Utilities.sleep(5000);
Drive.Permissions.insert({ role: "reader", type: "anyone" }, pdfFileId);
league = fileName.split(' ')[0];
title = fileName.split(league)[1].split('.pdf')[0];
shareable = "https://drive.google.com/file/d/" + pdfFileId;
id = pdfFileId;
var data = {
'api_league_name': league,
'title': title,
'google_drive_id': id,
'google_drive_url': shareable,
'pass': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
};
var options = {
'method': 'post',
'contentType': 'application/json',
'payload': JSON.stringify(data)
};
UrlFetchApp.fetch('https://www.xxx.com.br/api/posts', options);
}
Note:
This is a sample script for testing whether Utilities.sleep(5000) can be removed.
In the following script I have to manually insert the email addresses. I rather get the list from the sheet to be able to update it without editing the script.
How do I retrieve a list of email addresses from the sheet (Sheet!A2:A)?
function sendReport() {
EMAIL = 'email'
URL = 'url'
+ '/export?'
+ 'format=pdf'
+ '&size=A4'
+ '&gid=id'
+ '&scale=4'
+ '&portrait=true';
SpreadsheetApp.getActive();
var response = UrlFetchApp.fetch(URL, {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
});
var message = {
to: EMAIL,
subject: "subject",
body: "body",
attachments: [response.getBlob().setName('file.pdf')]
}
MailApp.sendEmail(message);
}
Is the script you expect as follows?
Modified script:
function sendReport() {
URL = 'url'
+ '/export?'
+ 'format=pdf'
+ '&size=A4'
+ '&gid=id'
+ '&scale=4'
+ '&portrait=true';
var response = UrlFetchApp.fetch(URL, {
headers: {
'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()
}
});
// Retrieve values from Spreadsheet.
var sheet = SpreadsheetApp.getActiveSheet();
var values = sheet.getRange("A2:A" + sheet.getLastRow()).getDisplayValues();
// Send the email using the email addresses.
values.forEach(([email]) => {
if (email) {
var message = {
to: email,
subject: "subject",
body: "body",
attachments: [response.getBlob().setName('file.pdf')]
}
MailApp.sendEmail(message);
}
});
}
If you want to set the specific sheet, please modify var sheet = SpreadsheetApp.getActiveSheet(); to var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");.
Reference:
forEach()
I am trying to do a request to Gate.io cryptocurrency market and getting this error.
{"label":"INVALID_SIGNATURE","message":"Signature mismatch"}
I have managed to find a way to correctly encrypt all the parameters(my output is the same as they presented in their documentation), however, when I add a real secret key I got this error.
Please see the screenshot:
the right-hand side is a signature from their doc, in the GAS log you see my output so these are the same however when I add real timestamp and my real secret then it doesn't work
Screenshot.
Here is the fetch request I am using:
function getDateIo() {
var key = "xxx"
var sec = "xxx"
var timestamp = Math.floor(Date.now() / 1000)
var a = {"contract":"BTC_USD","type":"limit","size":100,"price":6800,"time_in_force":"gtc"}
a = JSON.stringify(a)
var body = {"text":"t-123456","currency_pair":"ETH_BTC","type":"limit","account":"spot","side":"buy","iceberg":"0","amount":"1","price":"5.00032","time_in_force":"gtc","auto_borrow":false}
body = JSON.stringify(body)
console.log(body)
var requestPayload = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_512, "")
requestPayload = requestPayload.map(function(e) {
var v = (e < 0 ? e + 256 : e).toString(16);
return v.length == 1 ? "0" + v : v;
}).join("");
console.log(requestPayload)
var meth = 'GET'
var pat = '/api/v4/futures/orders'
var sign = meth + "\n" + pat + "\n" + "contract=BTC_USD&status=finished&limit=50" + "\n" + requestPayload + "\n" + timestamp;
console.log(sign)
var signature = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, sign, sec);
signature = signature.map(function(e) {
var v = (e < 0 ? e + 256 : e).toString(16);
return v.length == 1 ? "0" + v : v;
}).join("");
var params = {
'method': "get",
'headers': {
'Accept': 'application/json',
'Content-Type': 'application/json',
'KEY': key,
'Timestamp': timestamp,
'SIGN': signature,
},
// 'body': body,
'muteHttpExceptions': true,
};
var data = UrlFetchApp.fetch("https://api.gateio.ws/api/v4/futures/orders?contract=BTC_USD&status=finished&limit=50", params);
}
Thanks for any advice
I can get account details so my authentication appears correct but in trying to modify that code to create an order it returns a code 401 "msg":"Invalid KC-API-SIGN". The modification involved adding in the method and payload and changing endpoint (/api/vi/accounts) to endpoint2 (/api/v1/orders)
function kucoinTest5()
{
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("xxxxx");
var key = sheet.getRange("xx").getValue()
var secret = sheet.getRange("xx").getValue();
var passphrase = sheet.getRange("xx").getValue();
var host = 'https://openapi-sandbox.kucoin.com';
//var endpoint ='/api/v1/accounts';
var endpoint2 ='/api/v1/orders';
var timestamp = ''+ new Date().getTime();
var strForSign = timestamp + 'GET' + endpoint2;
var signature = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, strForSign, secret);
var encodedPass = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, passphrase, secret);
var url= host + endpoint2
var requestOptions = {
'method': "POST",
'headers': {
'KC-API-KEY': key,
'KC-API-TIMESTAMP': timestamp,
'KC-API-SIGN': Utilities.base64Encode(signature),
'KC-API-KEY-VERSION': '2',
'KC-API-PASSPHRASE': Utilities.base64Encode(encodedPass),
},
'payload': {
'clientOid': 'test1',
'side': 'buy',
'symbol': 'BTC-USDT',
'type': 'market',
'tradeType': 'TRADE',
'funds': 100
},
muteHTTPExceptions: true,
};
var httpRequest= UrlFetchApp.fetch(url, requestOptions);
//var getContext= httpRequest.getContentText();
Logger.log(httpRequest);
}
Solved above problem here is the code to post a buy order on KuCoin:
function kuCoinTest5()
{
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("xxxx");
var key = sheet.getRange("xx").getValue()
var secret = sheet.getRange("xx").getValue();
var passphrase = sheet.getRange("xx").getValue();
var payload = {
'clientOid':"UUID",
'side':"buy",
'symbol':"BTC-USDT",
'type':"market",
'tradeType':"TRADE",
'funds':"100"
};
var data = JSON.stringify(payload);
//Logger.log(data);
var host = 'https://openapi-sandbox.kucoin.com';
var timeStamp = ''+ new Date().getTime();
//var nowStr = "" + nowDate;
var endpoint ='/api/v1/accounts';
var endpoint2 ='/api/v1/orders';
var strForSign = timeStamp + "POST" + endpoint2 + data;
//Logger.log(strForSign);
var signature = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, strForSign, secret);
var encodedPass = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, passphrase, secret);
var url= host + endpoint2;
//Logger.log(url);
var options = {
"method":"POST",
'headers' : {
'KC-API-KEY': key,
'KC-API-TIMESTAMP': timeStamp,
'KC-API-SIGN': Utilities.base64Encode(signature),
'KC-API-KEY-VERSION': '2',
'KC-API-PASSPHRASE': Utilities.base64Encode(encodedPass)
},
"contentType":"application/json",
"payload":data,
//'payload' : {'clientOid':"45234524625",
//'side':"buy",
//'symbol':"BTC-USDT",
//'type':"market",
//'tradeType':"TRADE",
//'funds':"100"},
"muteHttpExceptions":true,
}
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)
}
I had the same problem with a GET request, and finally solved thanks to the above code. Here is my code:
function KuCoinRequest(){
var key ='xx'
var secret = 'xx'
var passphrase = 'xx'
var url = "https://api-futures.kucoin.com/"; //endpoint
var timestamp = '' + Number(new Date().getTime()).toFixed(0);
var command = "GET";
var endpoint = "api/v1/fills"
var str_to_sign = timestamp + command +"/" + endpoint;
var signature = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, str_to_sign, secret)
var encodedPass = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_256, passphrase, secret);
var params = {
'method': "GET",
'headers' : {
'KC-API-SIGN': Utilities.base64Encode(signature),
'KC-API-KEY': key,
'KC-API-TIMESTAMP': timestamp,
'KC-API-PASSPHRASE': Utilities.base64Encode(encodedPass),
'KC-API-KEY-VERSION': '2',
'muteHttpExceptions': true
}
};
query = url + endpoint;
var data = UrlFetchApp.fetch(query, params);
Logger.log(data.getContentText());
printJsonKucoin(data, endpoint);
return data;
}
I want to make a script to get Crypto prices updated in a Google Spreadsheets. I don't want to use API connector, rather do it myself end to end. I found a blog post on CMC blog but it doesn't work, I get an error.
Here is the code:
function ohlc_price() {
var sh1=SpreadsheetApp.getActiveSpreadsheet().getSheetByName(“IDs″);
var requestOptions = {method: ‘GET’, uri: ‘https://pro-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical’, qs: {‘id’: ‘1’,’time_period’:’daily’,’interval’:’2d’, ‘start_date’: ‘2019-08-15’, ‘end_date’: ‘2019-08-18’},
headers: {‘X-CMC_PRO_API_KEY’: ‘MY APY KEY IS HERE’},
json: true, gzip: true};
var url=”https://pro-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical?id=1&time_start=2019-06-01&interval=weekly”;
var result= UrlFetchApp.fetch(url, requestOptions);
var txt= result.getContentText();
var d=JSON.parse(txt); for (var i=0; i<10;i++) {sh1.getRange(i+2, 1).setValue(d.data.quotes[i].quote.USD.timestamp); sh1.getRange(i+2, 2).setValue(d.data.quotes[i].quote.USD.low); sh1.getRange(i+2, 3).setValue(d.data.quotes[i].quote.USD.open); sh1.getRange(i+2, 4).setValue(d.data.quotes[i].quote.USD.close); sh1.getRange(i+2, 5).setValue(d.data.quotes[i].quote.USD.high);}
Here is the error message I get:
SyntaxError: Invalid or unexpected token (ligne : 2, fichier : Coin price.gs)
I tried to follow CMC instructions but nothing works...
Can someone explain me what isn't working and why ?
Thx
I expect there is some lacks of quotes or apostrophes, especially after the uri/url. Try this and complete :
function ohlc_price() {
var sh1=SpreadsheetApp.getActiveSpreadsheet().getSheetByName('IDs');
var requestOptions = {
'method' : 'GET',
'uri': 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical’',
'qs': {'id': '1',
'time_period':'daily',
'interval':'2d',
'start_date': '2019-08-15',
'end_date': '2019-08-18'
},
'headers' : {'X-CMC_PRO_API_KEY': 'MY APY KEY IS HERE'},
'json': true,
'gzip': true};
var url = 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical?id=1&time_start=2019-06-01&interval=weekly”';
var result = UrlFetchApp.fetch(url, requestOptions);
var txt= result.getContentText();
}
Modification points:
There are no properties of uri and qs in the parameter of UrlFetchApp.
In your URL, id=1&time_start=2019-06-01&interval=weekly is used as the query parameter. But in your qs, {‘id’: ‘1’,’time_period’:’daily’,’interval’:’2d’, ‘start_date’: ‘2019-08-15’, ‘end_date’: ‘2019-08-18’} is used. So unfortunately, I cannot understand which do you want to use.
In this modification, interval=weekly, time_start=2019-06-01, and time_end=2019-08-18 are used. When you want to use other values, please modify the script.
In your script, for (var i = 0; i < 10; i++) {} is used for var d = JSON.parse(txt). In this case, when the data length is less than 10, an error occurs.
When above points are reflected to your script, it becomes as follows.
Modified script:
function ohlc_price() {
// This is from https://gist.github.com/tanaikech/70503e0ea6998083fcb05c6d2a857107
String.prototype.addQuery = function (obj) {
return this + Object.keys(obj).reduce(function (p, e, i) {
return p + (i == 0 ? "?" : "&") +
(Array.isArray(obj[e]) ? obj[e].reduce(function (str, f, j) {
return str + e + "=" + encodeURIComponent(f) + (j != obj[e].length - 1 ? "&" : "")
}, "") : e + "=" + encodeURIComponent(obj[e]));
}, "");
}
var url = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/ohlcv/historical";
var query = { 'id': '1', 'time_period': 'daily', 'interval': 'weekly', 'time_start': '2019-06-01', 'time_end': '2019-08-18' };
var endpoint = url.addQuery(query);
var requestOptions = {
method: 'GET',
headers: { 'X-CMC_PRO_API_KEY': 'MY APY KEY IS HERE' },
};
var result = UrlFetchApp.fetch(endpoint, requestOptions);
var txt = result.getContentText();
var d = JSON.parse(txt);
var sh1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("IDs");
var values = d.data.quotes.map(({ quote: { USD } }) => [USD.timestamp, USD.low, USD.open, USD.close, USD.high]);
sh1.getRange(2, 1, values.length, values[0].length).setValues(values);
}
Note:
In this answer, it supposes that your value of X-CMC_PRO_API_KEY is valid value. Please be careful this.
References:
fetch(url, params)
OHLCV Historical