Google Cloud Functions Analytics API - Delete User OAuth2 - google-cloud-functions

need some help, please.
I have a cloud function to delete user data from Google Analytics, this function is triggered when I send a Pub/Sub message from my backend with a delete request. I'm using Google Analytics API, which was activated on my Google Cloud Console.
I followed this doc: https://developers.google.com/analytics/devguides/config/userdeletion/v3, but I didn't succeed in deleting the user via the cloud function.
cloud function:
function deleteGArecord(userObject) {
const options = {
method: "POST",
url: "https://www.googleapis.com/analytics/v3/userDeletion/userDeletionRequests:upsert",
headers: {
//"Content-Type": "application/json",
},
body: JSON.stringify({
kind: "analytics#userDeletionRequest",
id: {
type: "CLIENT_ID",
userId: userObject.clientId,
},
webPropertyId: "UA-111111-000",
}),
};
request(options, function (error, response) {
if (error) {
console.log(error);
}
console.log("ga user delete request:" + JSON.stringify(response));
});
}
What I tried:
Create OAuth client ID - application type web.
Added this client on my Analytics property.
Call the function when a delete request is sent.
Cloud function log:
"statusCode":401,"body":"{\n \"error\": {\n \"code\": 401,\n \"message\": \"Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.\",\n \"errors\": [\n {\n \"message\": \"Login Required.
How I authenticate my cloud function to be able to send this hit. I've created the user already and I'm calling this function from the same project ClientId is...
Thanks in advance!

Request is missing required authentication credential.
Your missing your authorization header. Your going to need a bearer token containing an access token with the correct authorized scopes
User Deletion API
Requires authorization with the following scope
Once you are authorized your looking at something like this.
const options = {
method: "POST",
url: "https://www.googleapis.com/analytics/v3/userDeletion/userDeletionRequests:upsert",
headers: {
"Authorization": "Bearer " + access_token,
},
The issue will be how to get a cloud function to authorize to a google api.

Related

Cannot authenticate via Postman (Bearer token)

So I am trying around with an application that I did not code, and I am quite new to REST APIs etc, so I am having some issues with that.
From my front-end Next.js application I am sending an Axios request to the backend with a Bearer token header
const config: AxiosRequestConfig = {
method,
url: `${BASE_URL}${url}`,
headers: isFormData ? { 'Content-Type': 'multipart/form-data' } : {},
data: isFormData ? params : ( params ? { ...params } : null ),
validateStatus: function (status) {
return status >= 200 && status < 300 // default
}
}
config.headers['Authorization'] = `Bearer ${userStore.token}`
Everything works, so if a user is authenticated and has the token in the userStore the request is successful and the backend responds with the given json data for a certain api route.
Postman Image
Though when I try to fetch the json data directly from the API route in Postman, and provide the Authorization header for this request, I get an error not authorized response from the backend. What am I missing here?
try selecting 'bearer token' under authorization and give the token directly.

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)

How can I authorize Google Speech-to-text from Google Apps script?

I'm trying to execute google-speech-to-text from apps script. Unfortunately, I cannot find any examples for apps script or pure HTTP, so I can run it using simple UrlFetchApp.
I created a service account and setup a project with enabled speech-to-text api, and was able
to successfully run recognition using command-line example
curl -s -H "Content-Type: application/json" \
-H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \
https://speech.googleapis.com/v1/speech:recognize \
-d #sync-request.json
which I can easily translate to UrlFetchApp call, but I don't have an idea to generate access token created by
gcloud auth application-default print-access-token
Is there a way to get it from apps script using service account credentials?
Or is there any other way to auth and access speech-to-text from apps script?
The equivalent of retrieving access tokens through service accounts is through the apps script oauth library. The library handles creation of the JWT token.
Sample here
Using the answer from TheMaster, I was able to build a getToken solution for my case
`
function check() {
var service = getService();
if (service.hasAccess()) {
Logger.log(service.getAccessToken());
} else {
Logger.log(service.getLastError());
}
}
function getService() {
return OAuth2.createService('Speech-To-Text Token')
.setTokenUrl('https://oauth2.googleapis.com/token')
.setPrivateKey(PRIVATE_KEY)
.setIssuer(CLIENT_EMAIL)
.setPropertyStore(PropertiesService.getScriptProperties())
.setScope('https://www.googleapis.com/auth/cloud-platform');
}
`
The code for transcribe itself, is
function transcribe(){
var payload = {
"config": {
"encoding" : "ENCODING_UNSPECIFIED",
"sampleRateHertz": 48000,
"languageCode": "en-US",
"enableWordTimeOffsets": false
},
"audio": {
content: CONTENT
}
};
var response = UrlFetchApp.fetch(
"https://speech.googleapis.com/v1/speech:recognize", {
method: "GET",
headers: {
"Authorization" : "Bearer " + getService().getAccessToken()
},
contentType: "application/json",
payload: JSON.stringify(payload),
muteHttpExceptions: true
});
Logger.log(response.getContentText());
}

Which calls need an access token in ActiveCollab v5 API

I'm playing with Google Apps Script utilizing the ActiveCollab HTTPS API as a way to link Google Forms to specific projects. I can't figure out where to use the access token in the HTTP request when creating a Task in a project.
Maybe I'm missing it, but which API calls in the documentation require the access token as part of the POST request?
The most basic POST request I've sent was:
var token = // token from authentication
{
"name": "Test task",
"token": token
}
...and it returned a 401 error, saying I wasn't authenticated.
So, I tried:
var token = // token from authentication
{
"name": "Test task",
"username": // my username,
"password": // my password,
"token": token
}
...with the same result. So, which calls require a token and does the token go in the POST payload? Or should it be in the POST options?
Update 3/10/2016
I have added the Authorization parameter to the POST request and am now receiving an invalid token error in the response. I've cleared my cache and reauthorized successfully. My test function is below.
function postTicket() {
// Retrieve the stored token after a successful authorization
var token = PropertiesService.getScriptProperties().getProperty("token");
var data = {
"name": "Testing task"
}
var headers = {
Authorization: 'Bearer ' + token
};
var options = {
"method": "post",
"contentType": "application/json",
"headers": headers,
"payload": JSON.stringify(data)
}
try {
var url = BASE_URL + "/projects/8/tasks";
var response = UrlFetchApp.fetch(url, options);
var json = response.getContentText();
var data = JSON.stringify(json)
Logger.log(data);
} catch (e) {
Logger.log(e);
}
}
The logged error is:
returned code
500.{"type":"ActiveCollab\Authentication\Exception\InvalidTokenException","message":"Authorization
token is not valid","code":0
I had the same problem, but after checking Active Collab SDK code i figured out, that we should use these headers:
var headers = {
'X-Angie-AuthApiToken': token
};
By using this code i'm allowed to create tasks via API.
Token needs to be sent using Authorization HTTP header:
Authorization: Bearer TOKEN_THAT_YOU_GOT_FROM_ACTIVE_COLLAB
This means that you need to send the token as part of request header, not payload. Please check the Google Apps documentation for details (I see that fetch has headers object as one of the arguments, so there is support for this type of interaction built into the platform).