Google sheets appscript - Pipedrive post - google-apps-script

I am getting the error 'Exception: Request failed for https://api.pipedrive.com returned code 404. Truncated server response: {"status":false,"error":"Unknown method ."} (use muteHttpExceptions option to examine full response)' when attempting a put/post request to a Pipedrive deal. (Date Field) Below is the function producing the error. I am pretty sure this is something obvious but have not been able to determine the cause on my own. Any help would be appreciated.
function Update_pipedrive_Date(dealid, field_name){
var todays_date = Utilities.formatDate(new Date(), "GMT-5", "yyyy-MM-dd"); // "yyyy-MM-dd'T'HH:mm:ss'Z'"
var url = 'https://api.pipedrive.com/v1/deals/' + dealid + '?api_token='+oys_api_key
var data = {field_name: todays_date};
var options = {
'method': 'post',
'contentType': 'application/json',
'payload': JSON.stringify(data)
};
var response = UrlFetchApp.fetch(url, options);
return response
}
def update_field(this_dealid, fieldid):
tday = now.strftime("%Y-%m-%d")
headers = {'content-type': 'application/json'}
updates = {fieldid: tday}
resp = requests.put(
'https://api.pipedrive.com/v1/deals/' + str(
this_dealid) + '?api_token=' + api_key,
data=json.dumps(updates), headers=headers)
return resp

I believe your goal is as follows.
Your provided python script works fine.
You want to convert your python script to Google Apps Script.
Modification points:
Your python script requests the PUT method. But your Google Apps Script requests the POST method.
In the case of {field_name: todays_date}, the key is always "field_name".
When these points are reflected in your script, how about the following modification?
Modified script:
var field_name = "###"; // Please set your field_name.
var dealid = "###"; // Please set your dealid.
var oys_api_key = "###"; // Please set your oys_api_key.
var todays_date = Utilities.formatDate(new Date(), "GMT-5", "yyyy-MM-dd");
var url = 'https://api.pipedrive.com/v1/deals/' + dealid + '?api_token=' + oys_api_key;
var data = { [field_name]: todays_date };
var options = {
'method': 'put',
'contentType': 'application/json',
'payload': JSON.stringify(data)
};
var response = UrlFetchApp.fetch(url, options);
Note:
I think that the request of this Google Apps Script is the same as your python script. But if this script occurs an error, please confirm your variables of field_name, dealid, oys_api_key again. Even when these variables are the valid values, when an error occurs, I'm worried that the URL might not be able to be accessed from the Google side.
Reference:
fetch(url, params)

Related

Why is this Web App showing an error "Script function not found: events"?

The user clicks on a button, which has main() assigned to it.
It runs with no errors, but the protections are not removed or applied as it seems to get stuck because of the error mentioned in the question.
Here are the functions borrowed and adapted from Stackoverflow:
// This is the main function. Please set this function to the run button on Spreadsheet.
function main() {
//DriveApp.getFiles(); // This is a dummy method for detecting a scope by the script editor.
const activeSheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const sheetName = activeSheet.getName();
if (sheetName === 'Itens_para_Costurar') {
var token = ScriptApp.getOAuthToken()
var url = ScriptApp.getService().getUrl();
var options = {
'method': 'post',
'headers': { 'Authorization': 'Bearer ' + token },
muteHttpExceptions: true
};
UrlFetchApp.fetch(url + "&key=removeprotectListaCortadas", options); // Remove protected range
listaPecasCortadas();//Atualiza a lista de peças cortadas
SpreadsheetApp.flush(); // This is required to be here.
UrlFetchApp.fetch(url + "&key=addprotectListaCortadas", options); // Add protected range
}
}
function doGet(e) {
if (e.parameter.key == "removeprotectListaCortadas") {
var listaPecasCortadasSht = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Itens_para_Costurar'); // Please set here.
// Remove protected range.
var protections = listaPecasCortadasSht.getProtections(SpreadsheetApp.ProtectionType.RANGE);
for (var i = 0; i < protections.length; i++) {
console.log('Protection Name: ' + protections[i].getDescription())
protections[i].remove();
}
} else {
// Add protected range.
var ownersEmail = Session.getActiveUser().getEmail();
var protection = listaPecasCortadasSht.getRange('A8:J100').protect();
var editors = protection.getEditors();
for (var i = 0; i < editors.length; i++) {
var email = editors[i].getEmail();
if (email != ownersEmail) protection.removeEditor(email);
}
}
return ContentService.createTextOutput("ok");
}
I would appreciate any light towards the solution.
Modification points:
If you were using my answer, when I posted it, ScriptApp.getService().getUrl() returned the endpoint of the developer mode. But, in the current stage, it doesn't return the endpoint of the developer mode. And, in this case, the invalid endpoint is returned. Ref
In your request body, 'method': 'post', is used. But, in your script, doGet is used. I thought that this might be the reason for your current issue.
In your script, var url = ScriptApp.getService().getUrl(); is used. But, using url, you are using UrlFetchApp.fetch(url + "&key=addprotectListaCortadas", options);. In this case, the query parameter is not correct.
When these points are reflected in your script, how about the following modification?
From:
var token = ScriptApp.getOAuthToken()
var url = ScriptApp.getService().getUrl();
var options = {
'method': 'post',
'headers': { 'Authorization': 'Bearer ' + token },
muteHttpExceptions: true
};
UrlFetchApp.fetch(url + "&key=removeprotectListaCortadas", options); // Remove protected range
To:
var url = "###"; // Please manually set your Web Apps URL here.
var options = { muteHttpExceptions: true };
UrlFetchApp.fetch(url + "?key=removeprotectListaCortadas", options);
If your Web Apps is deployed as Execute the app as: Me and Who has access to the app: Anyone, when the Web Apps URL is used, the access token is not required to be used. If you want to use the developer mode, please use the access token.
Note:
This answer is for your current issue. So, I cannot check your all script. Please be careful about this.
When you modified the Google Apps Script of Web Apps, please modify the deployment as a new version. By this, the modified script is reflected in Web Apps. Please be careful about this.
You can see the detail of this in my report "Redeploying Web Apps without Changing URL of Web Apps for new IDE (Author: me)".

OAuth 2.0 is not enabled for method Error with jira cloud with App-script

I have implemented oauth2 (3LO) using App-script for integrating Google Sheet and Jira. I have set var SCOPE = read:jira-user read:jira-work write:jira-work
When I use any get request, system works fine. But when I try to make put or post request, system throws error. See this image below:
[][enter code here1]
See here my put request for edit an issue
I am not sure what is the issue here. I have checked that I have enabled oauth2 and as an administrator, I have all power. I have also proper scope. And this configuration works for any get request but it does not work with POST and PUT requests.
Could you please let me know if you have an idea or clue how I can make it work or is there anything I can check to make sure my confirmation is right for POST or PUT requests?
function updateIssue() {
var service = getService();
var issueIdOrKey = 'CP-16'
Logger.log(service.hasAccess());
if (service.hasAccess()) {
var data = `{
"summary":"New summary version 1"
}`;
var route = `/rest/api/3/issue/${issueIdOrKey}`;
var cloudid = getCloudId(service);
var url = 'https://api.atlassian.com/ex/jira/' + cloudid + route;
Logger.log(url);
var response = UrlFetchApp.fetch(url, {
'Method': 'PUT',
headers: {
//'Method': 'PUT',
'Accept': 'application/json',
'Authorization': 'Bearer ' + service.getAccessToken(),
// Convert the JavaScript object to a JSON string.
'ContentType': 'application/json' //, 'payload': JSON.stringify(data)
},
'payload': JSON.stringify(data)
});
var result = JSON.parse(response.getContentText());
Logger.log(JSON.stringify(result, null, 2));
}
}
Thank you
Modification points:
In your script, at var data = {"summary":"New summary version 1"};, data` has already been converted to the string.
When 'ContentType' is used, I thought that it was 'Content-Type'. But, in your script, I thought that 'contentType': 'application/json' can be used outside of the request header.
When these points are reflected in your script, it becomes as follows.
Modified script:
function updateIssue() {
var service = getService();
var issueIdOrKey = 'CP-16'
Logger.log(service.hasAccess());
if (service.hasAccess()) {
var data = { "summary": "New summary version 1" }; // Modified
var route = `/rest/api/3/issue/${issueIdOrKey}`;
var cloudid = getCloudId(service);
var url = 'https://api.atlassian.com/ex/jira/' + cloudid + route;
Logger.log(url);
var response = UrlFetchApp.fetch(url, {
'Method': 'PUT',
'headers': { // Modified
'Accept': 'application/json',
'Authorization': 'Bearer ' + service.getAccessToken(),
},
'contentType': 'application/json', // Added
'payload': JSON.stringify(data)
});
var result = JSON.parse(response.getContentText());
Logger.log(JSON.stringify(result, null, 2));
}
}
Note:
In this modification, it supposes that your access token and your endpoint, and your request body are valid values. Please be careful about this. If an error occurs, please show the error message and please provide the official document of the API you want to use. By this, I would like to confirm it.
Reference:
fetch(url, params)

i am trying to connect to independentreserve api using google apps script

i think the issue is with the signature, the request body is same as in the independentreserve api docs. i am using apps script to connect with api, i tried using python and it works fine, but i am new to javascript and google apps script.
this is my code. can someone help with this?
function myFunction() {
var key = 'api-key'
var secret = 'api-secret'
var url = 'https://api.independentreserve.com/Private/GetOpenOrders'
// initialize nonce to current unix time in milliseconds
nonce = (new Date()).getTime();
// Set custom User-Agent string
var headers = {"User-Agent": "Independent Reserve Javascript API Client"};
var nonce = nonce++;
console.info("hELLO")
var message = [url, 'apiKey=' + key, 'nonce=' + nonce].join(',') ;
//var signer = crypto.createHmac('sha256', Buffer(secret, 'utf8'));
var signer = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, secret);
var signature = signer
.map(function(byte) {
// Convert from 2's compliment
var v = (byte < 0) ? 256 + byte : byte;
// Convert byte to hexadecimal
return ("0" + v.toString(16)).slice(-2);
}).join(',');
var headers = {'Content-Type': 'application/json', 'muteHttpExceptions': true};
var options = {
"apiKey": key,
"nonce": nonce,
"signature": signature,
"primaryCurrencyCode": "Xbt",
"secondaryCurrencyCode": "Usd",
"pageIndex": 1,
"pageSize": 25
}
var r = UrlFetchApp.fetch(url, options)
console.info(r.getContentText())
}
I believe your goal is as follows.
In order to request to api.independentreserve.com, you want to convert the following sample script of python. Ref
import time
import requests
import hmac
import hashlib
import json
from collections import OrderedDict
url = 'https://api.independentreserve.com/Private/GetOpenOrders'
key = 'api_key'
secret = 'api_secret'
nonce = int(time.time())
# make sure that parameter order is correct as specified in method documentation
parameters = [
url,
'apiKey=' + key,
'nonce=' + str(nonce),
'primaryCurrencyCode=Xbt',
'secondaryCurrencyCode=Usd',
'pageIndex=1',
'pageSize=10'
]
message = ','.join(parameters)
signature = hmac.new(
secret.encode('utf-8'),
msg=message.encode('utf-8'),
digestmod=hashlib.sha256).hexdigest().upper()
# make sure this collection ordered in the same way as parameters
data = OrderedDict([
('apiKey', key),
('nonce', nonce),
('signature', str(signature)),
('primaryCurrencyCode', 'Xbt'),
('secondaryCurrencyCode', 'Usd'),
('pageIndex', 1),
('pageSize', 10)])
headers = {'Content-Type': 'application/json'}
r = requests.post(url, data=json.dumps(data, sort_keys=False), headers=headers)
print(r.content)
When I saw your script, I thought the following modification points:
Utilities.computeDigest will be Utilities.computeHmacSha256Signature.
(new Date()).getTime() cannot be directly used. In this case, I thought that it's (new Date()).getTime().toString().slice(0, 10).
muteHttpExceptions cannot be used in the request header.
'Content-Type': 'application/json' can be used as contentType: "application/json". And in this case, it is required to convert the JSON object to the string value.
When the above python script is converted to Google Apps Script by modifying these points, it becomes as follows.
Sample script:
function myFunction() {
var key = 'api_key';
var secret = 'api_secret';
var url = 'https://api.independentreserve.com/Private/GetOpenOrders';
var nonce = (new Date()).getTime().toString().slice(0, 10);
var parameters = [
url,
'apiKey=' + key,
'nonce=' + nonce.toString(),
'primaryCurrencyCode=Xbt',
'secondaryCurrencyCode=Usd',
'pageIndex=1',
'pageSize=10'
];
var message = parameters.join(",");
var signature = Utilities.computeHmacSha256Signature(message, secret, Utilities.Charset.UTF_8).map(b => ('0' + (b & "0xFF").toString(16)).slice(-2)).join('');
var payload = {
"apiKey": key,
"nonce": nonce,
"signature": signature,
"primaryCurrencyCode": "Xbt",
"secondaryCurrencyCode": "Usd",
"pageIndex": 1,
"pageSize": 25
};
var options = {
method: "post",
contentType: "application/json",
payload: JSON.stringify(payload),
muteHttpExceptions: true,
};
var r = UrlFetchApp.fetch(url, options);
console.log(r.getContentText());
}
Note:
I confirmed that this request of the above Google Apps Script is the same as the sample python script. So, when an error occurs, please confirm your key, secret, and the values of parameters, again.
References:
Airbridge API
computeHmacSha256Signature(value, key, charset)
fetch(url, params)

Spotify API authorisation via Google Apps Script

I am using the following code to make requests to the Spotify API via Google Apps Script:
function search() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var artist = sheet.getRange(1,1).getValue();
artist = encodeURIComponent(artist.trim());
var result = searchSpotify(artist);
Logger.log(result);
}
function searchSpotify(artist) {
//searches spotify and returns artist ID
var response = UrlFetchApp.fetch("https://api.spotify.com/v1/search?q=" + artist + "&type=artist&limit=1",
{ method: "GET",
headers:{
"contentType": "application/json",
'Authorization': "Bearer BQBnpSUdaEweirImw23yh2DH8OGhTwh5a_VnY_fgb2BPML0KvFvYd04CaEdUhQN9N4ZUXMIVfJ1MjFe1_j0Gl0UoHDhcoC_dklluZyOkq8Bo6i2_wfxSbGzP3k5EUjUKuULAnmTwCdkdZQnl-SNU0Co"
},
});
json = response.getContentText();
var data = JSON.parse(json);
var uri = data.artists.items[0].uri.slice(15);
var getArtists = getRelatedArtists(uri);
Logger.log(getArtists);
return getArtists;
}
function getRelatedArtists(uri) {
//searches related artists with the returned ID
var response = UrlFetchApp.fetch("https://api.spotify.com/v1/artists/" + uri + "/related-artists",
{ method: "GET",
headers:{
"contentType": "application/json",
'Authorization': "Bearer BQBnpSUdaEweirImw23yh2DH8OGhTwh5a_VnY_fgb2BPML0KvFvYd04CaEdUhQN9N4ZUXMIVfJ1MjFe1_j0Gl0UoHDhcoC_dklluZyOkq8Bo6i2_wfxSbGzP3k5EUjUKuULAnmTwCdkdZQnl-SNU0Co"
},
});
json = response.getContentText();
var data = JSON.parse(json);
var listArtists = [];
for(var i = 0, len = data.artists.length; i < len; i++){
listArtists.push(data.artists[i].name);
}
return listArtists;
}
This works fine using the temporary Authorisation token from the Spotify website but this token refreshes every hour and so is obviously useless.
I am trying to use my own Authorisation token and ID which I have setup on Spotify however I'm struggling to make this work. As I understand it I may need to add an extra step at the beginning to start the authorisation process but I've tried all methods suggested but keep receiving server errors.
From the document, it seems that "Client Credentials Flow" uses the basic authorization.
In order to use this, at first, you are required to retrieve "client_id" and "client_secret".
Sample script:
var clientId = "### client id ###"; // Please set here.
var clientSecret = "### client secret ###"; // Please set here.
var url = "https://accounts.spotify.com/api/token";
var params = {
method: "post",
headers: {"Authorization" : "Basic " + Utilities.base64Encode(clientId + ":" + clientSecret)},
payload: {grant_type: "client_credentials"},
};
var res = UrlFetchApp.fetch(url, params);
Logger.log(res.getContentText())
From curl sample, grant_type is required to send as form.
Result:
The document says that the response is as follows.
{
"access_token": "NgCXRKc...MzYjw",
"token_type": "bearer",
"expires_in": 3600,
}
Note:
This is a simple sample script. So please modify this for your situation.
I prepared this sample script by the sample curl in the document.
Reference:
Client Credentials Flow
Edit:
As your next issue, you want to retrieve the access token from the returned value. If my understanding is correct, how about this modification? Please modify my script as follows.
From:
Logger.log(res.getContentText())
To:
var obj = JSON.parse(res.getContentText());
Logger.log(obj.access_token)
When the value is returned from API, it returns as a string. So it is required to parse it as an object using JSON.parse().

Using Google Apps Script and the Pastebin.com API to post a paste

I am trying to make a Pastebin.com paste using Google Apps Script from the spreadsheet script editor. Can anyone tell me what I'm doing wrong?
function postPastebinPost() {
var options, url, apiKey, payload, response;
apiKey = <api key goes here>;
payload = 'Hello World';
options = {
'method' : 'post',
'payload' : payload
};
url = 'https://pastebin.com/api/api_post.php'
+ '?api_dev_key=' + apiKey
+ '&api_option=paste'
+ '&api_paste_code=' + encodeURIComponent(payload);
response = UrlFetchApp.fetch(url, options);
Logger.log(response);
}
I run this and my log reads Bad API request, invalid api_option. I've searched for solutions but I have not found any.
Documentation:
• Pastebin.com API
• Google Apps Script's UrlFetchApp Class
The parameters should be passed in the payload of the POST request.
function postPastebinPost() {
var apiKey = 'YOUR KEY GOES HERE';
var text = 'Hello World';
var payload = {
api_dev_key: apiKey,
api_option: 'paste',
api_paste_code: text
};
var options = {
method : 'POST',
payload: payload
};
var url = 'https://pastebin.com/api/api_post.php';
var response = UrlFetchApp.fetch(url, options);
Logger.log(response.getContentText());
}
The following is in case the user wants to create a new paste as part of their own Pastebin account (and not «Paste as a guest»). It's just an adaptation of Amit Agarwal's answer.
function postPastebinPost() {
var title = 'abc';
var contents = 'Hello World \n next line of content \n more text';
var payload = {
api_dev_key: 'aa6f3ab...', // https://pastebin.com/api#1
api_option: 'paste',
api_paste_name: title,
api_paste_code: contents,
api_paste_private: '0', // public paste
api_user_name: 'diccionario...', // name of your Pastebin account
api_user_password: 'dk398d...', // password to your Pastebin account
api_user_key: '39dk3...', // https://pastebin.com/api/api_user_key.html
};
var options = {
method : 'POST',
payload: payload
};
var url = 'https://pastebin.com/api/api_post.php';
var response = UrlFetchApp.fetch(url, options);
Logger.log(response.getContentText());
}
The whole documentation is at https://pastebin.com/api.