streak api: https://www.streak.com/api/
I tried to use this streak api with GAS UrlService and found the right syntax for get requests. But I don't find the rigth syntax for put and post:
(1) f.e. create box
var RequestArguments = {
"contentType": "application/json",
"headers":{
"User-Agent": "MY_APP_NAME",
"Authorization": "Basic " + Utilities.base64Encode(streakApiKey),
},
"validateHttpsCertificates" :false,
"method": "PUT",
"????": "????"
};
var result = UrlFetchApp.fetch(RequestUrl,RequestArguments);
(2) f.e. edit box
var RequestArguments = {
"contentType": "application/json",
"headers":{
"User-Agent": "MY_APP_NAME",
"Authorization": "Basic " + Utilities.base64Encode(streakApiKey),
},
"validateHttpsCertificates":false,
"method": "PUT",
"????": "????"
};
var result = UrlFetchApp.fetch(RequestUrl,RequestArguments);
I use such way in my Chrome extension, didn't try this code but should be similar in GAS:
"url": "https://www.streak.com/api/v1/boxes/"+boxKey+"/fields/"+fieldKey;
"type": 'POST',
"dataType": "json",
"contentType": 'application/json; charset=utf-8',
"data": {value: yourValue}
It took me some time to figure out the right combination of parameters (Streak API documentation is not friendly in this part), but what I see in your code looks alright to me. It should work.
Here's the function you can use to edit a field in an existing box. Creating a new box will follow the same format.
function editBox(boxKey, fieldKey, value) {
var url = 'https://www.streak.com/api/v1/boxes/' + boxKey + '/fields/' + fieldKey;
var params = {
headers: {Authorization: 'Basic ' + Utilities.base64Encode(STREAK_API_KEY + ":")},
method: "POST",
payload: JSON.stringify({
value: value
}),
contentType: 'application/json'
};
var field = UrlFetchApp.fetch(url,params );
return JSON.parse(field.getContentText());
}
This is working:
function editBox() {
var boxKey = "xxx";
var value = "{value:Test}";
var fieldKey = "1001";
//{name:"Deal Size", key:"1001", type:"TEXT_INPUT", lastUpdatedTimestamp:1457089319053}
var url = 'https://www.streak.com/api/v1/boxes/' + boxKey + '/fields/' + fieldKey;
var params = {
headers: {Authorization: 'Basic ' + Utilities.base64Encode(streakApiKey)},
method: "POST",
payload: value,
contentType: 'application/json'
};
var result = UrlFetchApp.fetch(url,params );
var string = result.getContentText();
var Object = JSON.parse(string);
return Object;
}
function createBox() {
var pipelineKey = "xxx";
var name = "sample box name";
var url = 'https://www.streak.com/api/v1/pipelines/' + pipelineKey + '/boxes';
var RequestArguments = {
headers: {"Authorization": "Basic " + Utilities.base64Encode(streakApiKey)},
method: "PUT",
payload: {
name: name
}
};
var box = UrlFetchApp.fetch(url,RequestArguments);
var result = JSON.parse(box.getContentText());
return result;
}
Related
I was trying to fetch data from Clearbit API and I get this message : " Exception: The parameters (String,(class),(class)) don't match the method signature for UrlFetchApp.fetch."
Before writing this post I tried to search online but couldn't find the answer.
I share with you my code :
function linkedInUrl(domain) {
let url = `https://company.clearbit.com/v2/companies/find?domain=${domain}`
const api_keys = ""
const header = {
method: 'GET',
headers: {'Authorization':'Bearer ' + api_keys}
}
options = {muteHttpExceptions: true};
var response = UrlFetchApp.fetch(url,header,options)
var data = JSON.parse(response.getContentText())
return "https://www.linkedin.com/"+data.linkedin.handle
}
function techUsed(domain) {
let url = `https://company.clearbit.com/v2/companies/find?domain=${domain}`
const api_keys = ""
const header = {
method: 'GET',
headers: {'Authorization':'Bearer ' + api_keys}
}
options = {muteHttpExceptions: true};
var response = UrlFetchApp.fetch(url,header,options)
var data = JSON.parse(response.getContentText())
tech = ""
for(let i = 0; i < data.tech.length; i++) {
tech += data.tech[i] +","
}
return tech
}
Does anyone have a clue ?
Thank you for your help.
The arguments of fetch(url, params) are url and params. I think that this is the reason for your current issue. So, please modify your script as follows.
From:
let url = `https://company.clearbit.com/v2/companies/find?domain=${domain}`
const api_keys = ""
const header = {
method: 'GET',
headers: {'Authorization':'Bearer ' + api_keys}
}
options = {muteHttpExceptions: true};
var response = UrlFetchApp.fetch(url,header,options)
To:
let url = `https://company.clearbit.com/v2/companies/find?domain=${domain}`;
const api_keys = "###"; // Please set your access token.
options = {
method: 'GET',
headers: { 'Authorization': 'Bearer ' + api_keys },
muteHttpExceptions: true
};
var response = UrlFetchApp.fetch(url, options);
Note:
In this case, your api_keys is valid value for using the API. Please be careful about this.
Unfortunately, I cannot know the response value from the API you want to use. So, if your script below var response = UrlFetchApp.fetch(url, options); occurs an error, please provide the sample value. By this, I would like to confirm your script.
Reference:
fetch(url, params)
You can try this :
function linkedInUrl(domain) {
let url = `https://company.clearbit.com/v2/companies/find?domain=${domain}`
const api_keys = ""
const header = {
method: 'GET',
headers: {'Authorization':'Bearer ' + api_keys}
}
options = {muteHttpExceptions: true};
var res
fetch(url,header,options) //api for the get request
.then(response => response.json())
.then(data => console.log('response',data))
}
I am looking to mention a user in a discord channel based on information set in a google sheet.
I have the script already pushing content from the google sheet to the discord channel so know that is working.
I can also get it to use the #everyone tag to mention everyone.
I am now wanting to get it set so that it only will mention the user.
Below is my script so far:
function onEdit() {
var wsID = " "
var sheet = SpreadsheetApp.openById(wsID).getSheetByName('discord');
var firestaff = sheet.getRange("A1").getValue();
var firecourse = sheet.getRange("B1").getValue();
var policestaff = sheet.getRange("A4").getValue();
var policecourse = sheet.getRange("B4").getValue();
var rescuestaff = sheet.getRange("A14").getValue();
var rescuecourse = sheet.getRange("B14").getValue();
var discordUrl = "",
options;
var firepayload = JSON.stringify({
content: "Please can " + firestaff + " start the " + firecourse + " courses. "
});
var policepayload = JSON.stringify({
content: "Please can " + policestaff + " start the " + policecourse + " courses.",
});
var rescuepayload = JSON.stringify({
content: "Please can " + rescuestaff + " start the " + rescuecourse + " courses."
});
var policemention = JSON.stringify({
content: "#everyone ",
})
var ssurl = JSON.stringify({
content: " "
});
var fireparams = {
method: "POST",
payload: firepayload,
muteHttpExceptions: true,
contentType: "application/json"
};
var policeparams = {
method: "POST",
payload: policepayload,
muteHttpExceptions: true,
contentType: "application/json"
};
var rescueparams = {
method: "POST",
payload: rescuepayload,
muteHttpExceptions: true,
contentType: "application/json"
};
var urlperms = {
method: "POST",
payload: ssurl,
muteHttpExceptions: true,
contentType: "application/json"
};
var policemen = {
method: "POST",
payload: policemention,
muteHttpExceptions: true,
contentType: "application/json"
};
UrlFetchApp.fetch(discordUrl, policemen)
UrlFetchApp.fetch(discordUrl, fireparams);
UrlFetchApp.fetch(discordUrl, policeparams);
UrlFetchApp.fetch(discordUrl, rescueparams);
UrlFetchApp.fetch(discordUrl, urlperms);
}
The only method available will be to create and store a list of users and their IDs, tagging them with <#THEUSERID>.
You can get the user IDs by right-clicking on a user's avatar.
With great SO help at previous step, I have writes to sheet almost working with URLFetchApp under service account credentials in a webapp. The code (below) only works with the "put" method; "post" generates an error. My understanding is that updates and inserts can both be done with "put" method. But the code is generating an error when the range is for a new row--that is, the last row in the sheet is not blank.
"range exceeds grid limits when inserting new row"
If it is necessary to have empty rows (e.g., add 1000 rows), does this become a manual maintenance job to monitor and periodically add new blank rows? I expected the "put" to simply add a new row. Is there another method with URLFetchApp to first add rows to the "grid" before inserting data? Thank you for any guidance!
function postData(ssID,updateRange,data) {
if (clientToken) {
var url= `https://sheets.googleapis.com/v4/spreadsheets/${ssID}/values/${updateRange}?valueInputOption=RAW`
var options = {
muteHttpExceptions: true,
contentType: 'application/json',
method:'put',
payload: JSON.stringify(data),
headers: { Authorization: 'Bearer ' + clientToken }
};
var response= UrlFetchApp.fetch(url,options);
var responseCode = response.getResponseCode();
var responseBody = response.getContentText();
if (responseCode === 200) {
var responseJson = JSON.parse(responseBody)
return responseJson;
} else {
Logger.log(Utilities.formatString("Request failed. Expected 200, got %d: %s", responseCode, responseBody))
return responseCode;
}
} else {//handle failed authorization }
} //end postData
Unfortunately, there is no method in the Sheets API V4 that can automatically add rows when the given range exceeds the sheet range.
What you can do is to get the rowCount of a specific sheet by using Method: spreadsheets.get then compare it with the range you will use to update values. If rowCount is less than the update range, use Method: spreadsheets.batchUpdate to update the sheet dimension.
Demo:
Example Sheet:
Code:
function request(ssID="spreadsheet id here",updateRange = "A1499:A1500",data) {
if (clientToken) {
var ssGetUrl= `https://sheets.googleapis.com/v4/spreadsheets/${ssID}`
var options = {
muteHttpExceptions: true,
contentType: 'application/json',
method:'get',
headers: { Authorization: 'Bearer ' + clientToken }
};
var ssGetresponse= JSON.parse(UrlFetchApp.fetch(ssGetUrl,options));
var sheets = ssGetresponse.sheets;
var rowCount = 0;
var sheetId = 0;
sheets.forEach(sheet => {
if(sheet.properties.sheetId == sheetId){
rowCount = sheet.properties.gridProperties.rowCount
}
})
var num = parseInt(updateRange.split(":")[1].replace(/[^0-9]/g,'')); //remove letters in updateRange and convert it to string
if(rowCount < num){
var diff = num - rowCount;
var resource = {
"requests": [
{
"appendDimension": {
"length": diff,
"dimension": "ROWS",
"sheetId": 0
}
}
]
};
var ssBatchUpdateUrl= `https://sheets.googleapis.com/v4/spreadsheets/${ssID}:batchUpdate`
var options = {
muteHttpExceptions: true,
contentType: 'application/json',
method:'post',
payload: JSON.stringify(resource),
headers: { Authorization: 'Bearer ' + clientToken }
};
var response= JSON.parse(UrlFetchApp.fetch(ssBatchUpdateUrl,options));
}
//insert code for updating range values
}
}
After executing code:
Note: The demo above is for increasing the number of rows when the update range is beyond the sheet's actual rows. For instance, if you have a range that the column is beyond the sheet's actual column, you can update the script to also read the columnCount, modify the parser to also get column part of A1 Notation and add another entry on appendDimension with COLUMN as dimension.
Try this:
function postData(ssID, updateRange, data) {
const ss = SpreadsheetApp.openById(ssID);
const sh = ss.getRange(updateRange).getSheet();//I assumed range is in A1 notation
const lr = sh.getLastRow();
if (lr == sh.getMaxRows()) {
sh.insertRowsAfter(lr, data.length);
}
if (clientToken) {
var url = `https://sheets.googleapis.com/v4/spreadsheets/${ssID}/values/${updateRange}?valueInputOption=RAW`
var options = {
muteHttpExceptions: true,
contentType: 'application/json',
method: 'put',
payload: JSON.stringify(data),
headers: { Authorization: 'Bearer ' + clientToken }
};
var response = UrlFetchApp.fetch(url, options);
var responseCode = response.getResponseCode();
var responseBody = response.getContentText();
if (responseCode === 200) {
var responseJson = JSON.parse(responseBody)
return responseJson;
} else {
Logger.log(Utilities.formatString("Request failed. Expected 200, got %d: %s", responseCode, responseBody))
return responseCode;
}
} else {//handle failed authorization }
} //end postData
I am trying to automise sending of the Emails from my account using Gmail API in Google Apps Script.
Here is my code:
function email_checker() {
var yourEmailAddress = "####gmail.com";
var myEmailAddress = "support####.com";
var subject = "testing mail";
var forScope = GmailApp.getInboxUnreadCount();
var htmlBody = '<html><body>' + '<h1>HI</h1>' + '</body></html>';
var message = 'From: Me <' + myEmailAddress + '>\r\n' +
'To: Me <' + myEmailAddress + '>\r\n' +
'Subject: ' + subject + '\r\n' +
'Content-Type: text/html; charset=utf-8\r\n' +
'Content-Transfer-Encoding: quoted-printable\r\n\r\n' +
htmlBody;
var draftBody = Utilities.base64Encode(message);
draftBody = draftBody.replace(/\//g, '_').replace(/\+/g, '-');
var params = {
method: "post",
contentType: "application/json",
headers: {
"Authorization": "Bearer " + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true,
payload: JSON.stringify({
"message": {
"raw": draftBody
}
})
};
var resp = UrlFetchApp.fetch("https://gmail.googleapis.com/upload/gmail/v1/users/me/messages/send", params);
Logger.log(resp.getContentText());
}
I am getting the following error: Media type 'application/json' is not supported.
Can anyone please advise on what I am doing wrong?
Thank you.
I believe your goal and your current situation as follows.
You want to send an email using Gmail API with UrlFetchApp.
You have already done the settings for sending the email.
Gmail API is enabled.
The scopes for sending emails can be included.
Modification points:
From your endtpoint, it is found that the media upload request is used.
In this case,
the request body is required to create with multipart/alternative.
It is not required to use the base64 encode with the web safe.
The content type is required to use message/rfc822.
The created request body can be directly used for payload.
When above points are reflected to your script, it becomes as follows.
Modified script:
function email_checker() {
var yourEmailAddress = "####gmail.com";
var myEmailAddress = "support####.com";
var subject = "testing mail";
var forScope = GmailApp.getInboxUnreadCount();
var htmlBody = '<html><body>' + '<h1>HI</h1>' + '</body></html>';
var message = 'MIME-Version: 1.0\r\n' +
'From: Me <' + myEmailAddress + '>\r\n' +
'To: Me <' + myEmailAddress + '>\r\n' +
'Subject: ' + subject + '\r\n' +
'Content-type: multipart/alternative; boundary=boundaryboundary\r\n\r\n' +
'--boundaryboundary\r\n' +
'Content-type: text/html; charset=UTF-8\r\n' +
'Content-Transfer-Encoding: quoted-printable\r\n\r\n' +
htmlBody + "\r\n\r\n" +
'--boundaryboundary--';
var params = {
method: "post",
contentType: "message/rfc822",
headers: {
"Authorization": "Bearer " + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true,
payload: message
};
var resp = UrlFetchApp.fetch("https://gmail.googleapis.com/upload/gmail/v1/users/me/messages/send", params);
Logger.log(resp.getContentText());
}
Note:
If you want to use the endpoint of POST https://gmail.googleapis.com/gmail/v1/users/{userId}/messages/send, please modify your script as follows.
From
var params = {
method: "post",
contentType: "application/json",
headers: {
"Authorization": "Bearer " + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true,
payload: JSON.stringify({
"message": {
"raw": draftBody
}
})
};
var resp = UrlFetchApp.fetch("https://gmail.googleapis.com/upload/gmail/v1/users/me/messages/send", params);
Logger.log(resp.getContentText());
To
var params = {
method: "post",
contentType: "application/json",
headers: {
"Authorization": "Bearer " + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true,
payload: JSON.stringify({"raw": draftBody})
};
var resp = UrlFetchApp.fetch("https://gmail.googleapis.com/gmail/v1/users/me/messages/send", params);
Logger.log(resp.getContentText());
In this case, var draftBody = Utilities.base64Encode(message); draftBody = draftBody.replace(/\//g, '_').replace(/\+/g, '-'); can be also modified to var draftBody = Utilities.base64EncodeWebSafe(message);.
Reference:
Method: users.messages.send
I intend to update my bound script (destination) with contents from another script (source). I am trying the following code. It does not give any error, but do not modify the destination script either.
function getScriptSourceCode() {
var srcProjectId = "id of source project"; // Source project ID
var destProjectId = "id of destination project"
var baseUrl = "https://script.googleapis.com/v1/projects";
var accessToken = ScriptApp.getOAuthToken()
var srcName = JSON.parse(UrlFetchApp.fetch(baseUrl + "/" + srcProjectId, {
method: "get",
headers: {"Authorization": "Bearer " + accessToken}
}).getContentText()).title;
var content = UrlFetchApp.fetch(baseUrl + "/" + srcProjectId + "/content", {
method: "get",
headers: {"Authorization": "Bearer " + accessToken}
}).getContentText();
var url = "https://script.googleapis.com/v1/projects/" + destProjectId
+ "/content";
var options = {
followRedirects: true,
"method" : "PUT",
"muteHttpExceptions": true,
"headers": {
'Authorization': 'Bearer ' + accessToken
},
"contentType": "application/json",
"payload": JSON.stringify(content)
}
var response = UrlFetchApp.fetch(url, options);
}
}
Am i missing something?
Excuse me for the erroneous script. I modified the script little bit and now its working as desired. However it seems I have to run the script twice to get the desired result. Below is the working script.
function UpdateScript()
{
var destProjectId = "Destination project ID"
var srcProjectId = "Source Project ID"; // Source project ID
var baseUrl = "https://script.googleapis.com/v1/projects";
var accessToken = ScriptApp.getOAuthToken()
var content = UrlFetchApp.fetch(baseUrl + "/" + srcProjectId + "/content", {
method: "get",
headers: {"Authorization": "Bearer " + accessToken}
}).getContentText();
// Upload a project to bound-script project.
var response = JSON.parse(UrlFetchApp.fetch(baseUrl + "/" + destProjectId + "/content", {
method: "put",
contentType: 'application/json',
headers: {"Authorization": "Bearer " + accessToken},
payload: content
}).getContentText());
}