Building a JWT for Twilio's Authy using Apps Script - google-apps-script

The No-PII user registration JWT for adding a user in Twilio's authy requires us to build a JWT from scratch.
I tried looking everywhere on how to get a JWT created using Google Apps Script but wasn't to find the right way to make that happen. It specifically needs to be of HS256 alg.
I require the final payload to look exactly like this -
// Example Payload
{
"iss": "My Authy App",
"iat": 1554395479,
"exp": 1554395879,
"context": {
"custom_user_id": "3YgAIZklGPHmwpJfIC0PDy0E7l763OF3BHZo1p2xKhY",
"authy_app_id": "1111111"
}
}
// Example Header
{
"alg": "HS256",
"typ": "JWT"
}
Can someone please help me with this or perhaps point me to an appropriate article/documentation for this??

The general syntax for URL fetch with Google Apps Script is the following:
var body={
"iss": "My Authy App",
"iat": 1554395479,
"exp": 1554395879,
"context": {
"custom_user_id": "3YgAIZklGPHmwpJfIC0PDy0E7l763OF3BHZo1p2xKhY",
"authy_app_id": "1111111"
};
var header={
"alg": "HS256",
"typ": "JWT"
};
var url='YOUR URL';
var options={
method: 'POST',
headers: header,
muteHttpExceptions: true,
contentType: 'application/json',
payload: JSON.stringify(body)
};
var response=UrlFetchApp.fetch(url, options);
According to the documentation link you provided, you might need to provide an API key. In this case, you URL should be something like var url=basicURL+"apikey="+XXX
I do not have a Twilio account to test it, but the sample provided above is the general procedure for Apps Script and you can find more references under the following links:
Working with Third-Party APIs
External APIs
Twilio Send a SMS message
Note that in the latter sample the payload is not in quotes.

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

Upload json object to Google Cloud Storage with Google Apps Script

I'm calling an API in a Google Apps Script. The response is a json object. I'd like to send it to Google Cloud Storage.
Here is the script I wrote so far:
function uploadToGoogleCloudStorage() {
var api_response = '{ "var":"value"}'
var url = 'https://storage.googleapis.com/storage/v1/b/my_bucket_name/o/test?fields=OBJECT'.replace("OBJECT", JSON.stringify(api_response))
var response = UrlFetchApp.fetch(url, {
method: "POST"
});
}
I have the following error Exception: Invalid argument: https://storage.googleapis.com/storage/v1/b/gtm_container_export/o/test?fields="{%20\"var\":\"value\"}"
I didn't find any documentation on how to interact with Google Cloud Storage from Google Apps Script. I'm wondering if UrlFetchApp is the right way to do it or if I should activate a specific service.
Here is a basic example for you - your approach just needs to be modified a bit:
function uploadToGoogleCloudStorage() {
let url = "https://storage.googleapis.com/upload/storage/v1/b/[replace this with your bucket ID]/o?uploadType=media&name=my_test_json.json";
let token = "Bearer [replace this with your oauth token!]";
// this is the content of the document we will create in the bucket
let data = {
'name': 'Bob Smith',
'age': 35,
'pets': ['fido', 'fluffy']
};
let options = {
'method' : 'post',
'headers' : {
'Authorization' : token
},
'contentType': 'application/json',
// Convert the JavaScript object to a JSON string.
'payload' : JSON.stringify(data)
};
var response = UrlFetchApp.fetch(url, options);
console.log( response.getResponseCode() ); // 200 OK
console.log( response.getContentText() );
}
In this case, the file name in the bucket will be "my_test_json.json", as defined in name=my_test_json.json.
Replace [replace this with your bucket ID] with your bucket ID.
Replace [replace this with your oauth token!] with your oauth token.
If you are not familiar with tokens, that is a fairly large topic, and outside the scope of this question. But in case it helps, here are some very basic notes: To generate a test token, I used the OAuth 2.0 Playground to create a test token. I chose "Cloud Storage API" read/write scope. After step 2, I copy/pasted the access_token string out of the "response" box on the right had side of the page. This string is over 300 characters in length. This is not a production-strength solution - it's just for testing.

Authentication error when attempting to fetch google analytics 4 with app script

I would like to connect a community connector to a google analytics 4 account so that I can easily modify the data and send it to data studio. However, My code is returning an authentication error:
{ error:
{ code: 401,
message: 'Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.',
status: 'UNAUTHENTICATED' } }
I have included the token, but I am unsure if I am making the correct url call or if there is some other issue that I am unaware of. I don't believe I need an API key to connect from community connector to a google API, but I may be wrong. I did create an API key but the result was the same.
function testFetch(){
var url = "https://analyticsdata.googleapis.com/v1alpha:runReport"
var token = ScriptApp.getOAuthToken();
var options = {
"method" : 'POST',
"entity": { "propertyId": "263290444" },
"dateRanges": [{ "startDate": "2020-12-01", "endDate": "2021-03-01" }],
"dimensions": [{ "name": "country" }],
"metrics": [{ "name": "activeUsers" }],
'muteHttpExceptions': true,
headers: {
Authorization: 'Bearer' + token,
},
};
var response = UrlFetchApp.fetch(url, options);
var result = JSON.parse(response.getContentText());
}
Here is a small guide on how to do what you are trying to achieve:
Set explicit OAuth scopes (see documentation) to your Apps Script project manifest (appsscript.json). In this case you need to add the following:
{
...
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/analytics.readonly"
}
}
Then you need to separate the method parameters from the fetch options. The fetch options need to be stringified and added to payload. You also need to set the contentType to JSON.
const options = {
entry: { propertyId: "263290444"},
// etc.
}
const response = UrlFetchApp.fetch(
'https://analyticsdata.googleapis.com/v1alpha:runReport',
{
method: 'POST',
muteHttpExceptions: true,
headers: {
'Authorization': `Bearer ${ScriptApp.getOAuthToken()}`
},
contentType: 'application/json; charset=utf-8',
payload: JSON.stringify(options)
}
)
After that, you may use the response as you were doing before.
Note that Bearer and the token need to be separated by a space, which your code does not have. It's hard to see because of the concatenation and that why I usually use template literals (see documentation).
References
Authorization scopes | Set explicit scopes (Google Apps Script Guides)
UrlFetchApp.fetch(url, params) (Google Apps Script Reference)
Template literals (MDN)

Create a post in Blogger with Google Apps Script

So far I haven't found a good code to create posts in Blogger with Google Script.
In the API Console I got the following credentials:
Client ID
Client Secret
API key
Also, libraries were added to the Google Script:
OAuth2 library → MswhXl8fVhTFUH_Q3UOJbXvxhMjh3Sh48
Blogger library → M2CuWgtxF1cPLI9mdRG5_9sh00DPSBbB3
I tried some codes, and this is the current one:
function create_blog_post() {
var payload =
{
"kind": "blogger#post",
"blog": {
"id": "12345........" // YOUR_BLOG_ID
},
"title": "New post",
"content": "With content..."
};
var headers = {
"Authorization": "Bearer " + getService().getAccessToken(), // ← THIS IS WRONG
"X-HTTP-Method-Override": "PATCH"
};
var options =
{
"method" : "post",
"headers" : { "Authorization" : "Bearer" + getService().getAccessToken()},
"contentType" : "application/json",
"payload" : '{ "kind": "blogger#post", "blog": { "id": "12345........" }, "title": "New post", "content": "With content..." }'
};
try {
var result = UrlFetchApp.fetch(
"https://www.googleapis.com/blogger/v3/blogs/12345......../posts", options);
Logger.log(result);
} catch (e) {Logger.log(e);}
}
Please help me solve this with the simplest code possible.
Required reading:
ScriptApp#getOauthToken
Blogger §post#insert
UrlFetchApp#fetch
Editing manifest#Setting explicit scopes
Switch to standard GCP
API Library
Issue:
Usage of asynchronous client side browser samples in the synchronous server side.
Solution:
It is possible to access Blogger api from Google apps script using UrlFetchApp
Full OAuth flow can be bypassed using oauth token provided by ScriptApp
Include scopes in the appsscript.json manifest file.
Switch to a standard GCP and enable the blogger api
Snippet:
function createBlogPost(){
var postUrl = "https://www.googleapis.com/blogger/v3/blogs/blogId/posts";
var blogId = /*"YOUR_BLOG_ID"*/;
postUrl = postUrl.replace("blogId",blogId);
var options = {
method:"post",
contentType:"application/json",
headers: { Authorization: "Bearer "+ ScriptApp.getOAuthToken()},
muteHttpExceptions: true,
payload: JSON.stringify({
title: "Hello from Apps Script!",
content: "This post is automatically created by Apps script"
})
}
var res = UrlFetchApp.fetch(postUrl, options).getContentText();
console.log(res);//or Logger.log(res)
}
Manifest scopes:
"oauthScopes": [
"https://www.googleapis.com/auth/blogger",
"https://www.googleapis.com/auth/script.external_request"
]

Google App Script: UrlFetchApp.fetch Address unavailable error

I wrote following code in google app script. When I run this code, it gives "Address unavailable: https://gsd.jira.com/jira/rest/api/2/issue/ (line 30, file "Code")"
function myFunction() {
var header =
{
"Cookie":"JSESSIONID=82AEF41778F3036829323019EB7437C4",
"Content-Type": "application/json"
};
var data =
{
"fields": {
"project":
{
"key": "TEST"
},
"summary": "REST ye merry gentlemen.",
"description": "Creating of an issue using project keys and issue type names using the REST API",
"issuetype": {
"name": "Story"
}
}
};
var options =
{
"headers" : header,
"method" : "post",
"payload" : data
};
var response = UrlFetchApp.fetch("https://gsd.jira.com/jira/rest/api/2/issue/", options);
Logger.log(response.getContentText());
}
However, when same HTTP request was created using "REST Console" chrome extension, it worked successfully and created a jira issue.
What is wrong with this code?
Host gsd.jira.com doesn't exist (try http://www.dnswatch.info/dns/dnslookup?la=en&host=gsd.jira.com&type=A&submit=Resolve).
It seems "gsd.jira.com" is address on your computer or local network specified e.g. via hosts file or local DNS server. When you use apps script, you are accessing the target API endpoint from Google servers.
If your API interface is not public, you can not access it froom apps script.