Using an android add (Http Shortcut) to start a google app script [closed] - google-apps-script

This post was returned to Web Applications Stack Exchange. It is not currently accepting new answers or interactions. Learn more
Closed. This question needs details or clarity. It is not currently accepting answers.
Closed 2 days ago.
I am totally a noob to coding and have no background in programming, hence have tried my best to understand things but am unable to.
I am trying to get use an android app (HTTP Shortcut) to do a POST to a googleappscript, which will make the switchbot bot do a press. Basically this app is simply to get the script running.
However, trying various methods with doPost and doGet, I still have no idea how to integrate it or where to put it into the code below.
function main() {
var headers = {
"Authorization" : "SWITCHBOT_TOKEN_KEY",
"Content-type": "application/json; charset=utf-8"
};
var data = {
"command": "press",
"parameter": "default",
"commandType": "command"
};
var options = {
'method' : 'post',
"headers" : headers,
muteHttpExceptions: true,
"payload" : JSON.stringify(data)
};
var deviceid = "INSERT_SWITCHBOT_DEVICEID";
var url1 = https://api.switch-bot.com/v1.0/devices/${deviceid}/commands;
var response = UrlFetchApp.fetch(url1,options);
var json=JSON.parse(response.getContentText());
console.log(json)
}
Any assistance with this would be great!

Related

Google apps script function error with POST request

I have a site on webflow and I need to add elements to it by taking them from a google sheet, reading the webflow documentation (you can read it here) it is possible to add elements with a POST request by passing it the correct token and json.
I need to make this request via the app script from the google sheet where the data is, but I keep getting an error saying that the "fields" field is required, a field I pass it though.
I tried the token in a GET request, via the same sheet, and it works, and the json (and the token too) via postman, and that works too
This is the code in the script
var teamData = {
"fields": {
"name": "test",
"slug": "test",
"category": "WOMEN",
"nationality-iso-code": "Italy",
"payment-status": "Confirmed",
"_archived": "false",
"_draft": "false"
}
}
var options = {
'method': 'POST',
'muteHttpExceptions': true,
'headers': {
'accept': 'application/json',
'content-type': 'application/json',
'authorization':'Bearer ' + API_TOKEN
},
'body' : JSON.stringify(teamData)
};
var response = UrlFetchApp.fetch(URL, options);
I have the same problem if I try to make an update with a PUT request, via postman it works, via google script no
Of course, I defined API_TOKEN and URL as constants, and they are correct

How to download media files in WhatsApp API which send users?

I am currently writing a chatbot for WhatsApp.
I use the 360dialog platform, which makes it possible to work with the WhatsApp Business API.
When the client sends a message, I see the following JSON object in the logs of my application:
{
"messages": [
{
"from": "77773336633",
"id": "ABGGd3c1cGY_Ago61ytHsZknvtLv",
"image": {
"id": "ffd23134-2dae-4fed-b5f8-0ce7867b6ddd",
"mime_type": "image/jpeg",
"sha256": "bd02100d961b5a1dbaae1dd645485ebbfeda77b44e82c015f1cf29b05654ccb9"
},
"timestamp": "1605703542",
"type": "image"
}
],
"contacts": [
{
"profile": {
"name": "Nurzhan Nogerbek"
},
"wa_id": "77773336633"
}
]
}
I can't find any information in the documentation about how to download this file.
In my case, I want to upload this image file that the client sends to my file storage.
Please tell me which URL method from the WhatsApp API is responsible for this mechanism?
P.S. At the same time, I can send files to clients. This information is available on the official documentation.
May be it will help, just try, take a look:-
const URL = `https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=1104480873777230&ext=1662705250&hash=ATuMx352sLrhKUegbQZSC8oLl3J5Vy3Z49lO4HwTUKWRYQ`;
const FROM = `video`;
const config = {
method: 'get',
url: URL, //PASS THE URL HERE, WHICH YOU RECEIVED WITH THE HELP OF MEDIA ID
headers: {
'Authorization': `Bearer ${token}`
},
responseType: 'arraybuffer'
};
axios(config)
.then(function (response) {
const ext = response.headers['content-type'].split("/")[1];
fs.writeFileSync(`${FROM}.${ext}`, response.data);
})
.catch(function (error) {
console.log(error);
});
It was very tricky because postman worked, but c# didn't work for me, and I spent two days trying to find the solution and finally did the following code, which works in C#:
using HttpClient _httpClient = new HttpClient();
Uri uri = new Uri(mediaUrl);
var fileName = $"{DateTime.Now.ToString("yyyyMMddhhmmss")}.jpeg";
string filePath = $"Files\\{fileName}";
// NOTE: to save bandwidth, request compressed content
_httpClient.DefaultRequestHeaders.AcceptEncoding.Clear();
_httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
_httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
_httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("br"));
// NOTE: accept all languages
_httpClient.DefaultRequestHeaders.AcceptLanguage.Clear();
_httpClient.DefaultRequestHeaders.AcceptLanguage.Add(new StringWithQualityHeaderValue("*"));
// NOTE: accept all media types
_httpClient.DefaultRequestHeaders.Accept.Clear();
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("image/jpeg"));
var productValue = new ProductInfoHeaderValue("ScraperBot", "1.0");
var commentValue = new ProductInfoHeaderValue("(+http://www.API.com/ScraperBot.html)");
_httpClient.DefaultRequestHeaders.UserAgent.Add(productValue);
_httpClient.DefaultRequestHeaders.UserAgent.Add(commentValue);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", {WhatsApp_Access_Token});
HttpResponseMessage response = await _httpClient.GetAsync(uri);
response.EnsureSuccessStatusCode();
var mediaType = response?.Content?.Headers?.ContentType?.MediaType ?? string.Empty;
var imageBytes = await response.Content.ReadAsByteArrayAsync();
using (var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
fs.Write(imageBytes, 0, imageBytes.Length);
}
Here, {WhatsApp_Access_Token} is your Whatsapp API permanent token.
Ping me in a comment, please, if you have any issues or questions.
The official documentation has a session for this in https://developers.facebook.com/docs/whatsapp/api/media.
Basically you must make a GET request to download the media.
curl --request GET \
--url https://waba.360dialog.io/v1/media/{media id} \
--header 'D360-API-KEY: {your api token}'

Google Apps Script UrlFetchApp GET to a node.js endpoint results in an empty body

I am using Google Apps Script to make a UrlFetchApp call to a node.js API endpoint. I own both the Google Apps Script code and node.js code & endpoint, so I can watch what is happening.
When I use Postman, it works. But when I use GAS UrlFetchApp, it doesn't work, as req.body in node is empty { }. I even looked at the code that Postman creates for JavaScript Fetch and try to nearly duplicate it, except for things I know GAS' UrlFetchApp needs. I've done quite a few UrlFetchApp calls with GAS to various external endpoints. So, I'm not new, but can't figure this one out.
Here is my Google Apps Script code:
var url = 'https://xxxxxxxxxxx.azurewebsites.net/api/account';
var data = {
"email": address,
"apiKey": 'xxxxxxxxxxxxxxxxxxx'
}
var payLoadInfo = JSON.stringify(data);
var options = {
"method": "GET",
"headers": {'Content-Type': 'application/json'},
// 'Content-Type': 'application/json',
// "contentType": 'application/json',
redirect: 'follow',
"muteHttpExceptions": true,
"body": payLoadInfo,
// "payload": JSON.stringify(data)
// payload: payLoadInfo
};
var response = UrlFetchApp.fetch(url, options);
The commented out parts of "options" are several different ways I've tried to get it to work. I know in the past that I've usually used "payload" instead of "body" like I am this time (Postman suggested it). When I use "payload", it fails completely, not even getting to my node code. I also tried putting the apiKey in the header.
Here is the node.js API endpoint code:
router.get("/account", async (req, res) => {
var apiKey = process.env.API_KEY;
console.log('apiKey = ' + apiKey);
console.log('req.body = ' + JSON.stringify(req.body, null, 2));
console.log('req.body.apiKey = ' + req.body.apiKey);
if (req.body.apiKey != apiKey) {
console.log('apiKey is not equal');
res.status(401).send({ error: "You are not authorized." });
} else {
process the request...
}
When I use "payload" in "options" I get a 500, and the server code never executes.
When I use "body" in "options", I see the server code execute, but the console.log('req.body = ' + JSON.stringify(req.body, null, 2)), just comes back with an empty object {}, and then since req.body.apiKey != apiKey, it consoles "apiKey is not equal" and sends a 401. When using Postman, the req.body object consoles fine, showing the email & apiKey.
No matter what combinations of things I put into options, it fails either with 500 or 401. However, Postman works great with pretty much the same parameters, headers, etc.
Here is what Postman shows for the code:
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Cookie", "ARRAffinity=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ARRAffinitySameSite=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
var raw = JSON.stringify({"email":"xxxxxxxxxxxxxxxxx#gmail.com","apiKey":"xxxxxxxxxxxxxxxx"});
var requestOptions = {
method: 'GET',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
I even tried including the cookie and "redirect: follow", but none works.
What am I missing?
I got it to work, thanks to help from #Tanaike (see comments above).
It seems that unlike normal "fetch" in node.js, URLFetchApp in Google Apps Script will not send a body along with a GET.
I still used GET, but changed to sending the param in the URL and the apiKey in the header.

Google Scripts API - autoUpdateForwarding Not Applying

As Domain Admin for the company I work at we'd like to set the forwarding addresses of staff as they leave the company to ensure any important correspondence isn't missed.
I've used the Google Apps OAuth2 Library successfully so far, but come across a snag. The following code is meant to forward emails from the address apitest#example.com to newaddress#example.com .
function setupForwarding() {
var service = getOAuthService();
service.reset();
try {
if (service.hasAccess()) {
var header = {
Authorization: 'Bearer ' + service.getAccessToken(),
}
var url = "https://www.googleapis.com/gmail/v1/users/apitest#example.com/settings/autoForwarding";
var response = UrlFetchApp.fetch(url, {
headers: header,
method: 'put',
enabled: true,
emailAddress: 'newaddress#example.com',
disposition: 'trash'
});
Logger.log(response.getContentText());
}
} catch (e) {
Logger.log(e.message);
}
}
The access token provided appears to work with other queries provided by UrlFetchApp such as using it to return the currently authorised forwarding addresses recorded on the account (which does include newaddress#example.com) and doesn't report any access priviledge errors. The response returns only the following
{ "enabled" : false }
And does not apply any forwarding. Would someone be able to help me identify the problem? I feel I might be passing the parameters to the HTTP request incorrectly but I'm still learning my way around that system and no other questions I found seemed to help.
Ozzie
I worked this out and it was simpler than I thought; so sharing the answer here in case anyone has a similar issue.
var response = UrlFetchApp.fetch(url, {
headers: header,
method: 'put',
contentType : 'application/json',
payload: '{ "enabled" : "true" , "emailAddress" : "newaddress#example.com" , "disposition" : "trash" }'
});
Is the functional way to do this; the request was expecting a separate payload and declared content type both.

Login to a moodle website on google app script

so i have been thinking recently i want to fetch some data from my moodle account using URLFetchApp. i want to get the html code but the login doesn't work. anyone have any guess what is going on? because it say session expired.
function myFunctionx() {
var payload={
user_email:USER_NAME,
user_password:USER_PASSWORD,
};
var option={
"method" : "post",
"payload" : payload,
"followRedirects" : true
};
var urlfetch=UrlFetchApp.fetch(MOODLE_WEBSITE,option);
var sessionDetails=urlfetch.getAllHeaders()['Set-Cookie'];
var downloadPayload =
{
user_email:USER_NAME,
user_password:USER_PASSWORD,
};
var downloadCsv = UrlFetchApp.fetch(MOODLE_SITE,
{"headers" :
{
'Connection':'keep-alive',
'Content-Type':'application/json;charset=utf-8',
'Accept':'application/json, text/plain, */*',
"Cookie" : sessionDetails
},
"method" : "post",
"payload" : downloadPayload,
});
DocumentApp.openById("1Osvvi4vYGx9hzvTr2qhQZj3xx_CFuL0wzhjeJQCuq7A").getBody().insertParagraph(0, urlfetch.getContentText());
Logger.log(downloadCsv.getContentText())
}
sorry i can't show the moodle site publicly. but let's just pretend the website url is in MOODLE_SITE constant
Thanks.