Access back-end messages (not the one from the event) - gmail-addons

I once wrote a GMail widget that I had to convert to a Chrome add-on when Google removed support for the GMail widget, and I'm now trying to convert it to a Gmail Add-on.
My issue is that my add-on loops thru a series of messages under a label and tries to reply to them, but I get a error trying to access them:
ERROR: Exception: Access denied: : Missing access token for per message scope authorization.
So my question is, how can I access those messages? The only access token I have is the one that triggered the add-on and that won't do.
Or asking from a different point of view, are there more events that can trigger the add-on besides opening a message?
Thanks in advance.
BTW, the Chrome extension that I'm trying to convert to a Gmail add-on can be seen here:
https://sites.google.com/site/replytomany/home
https://chrome.google.com/webstore/detail/reply-to-many/gpmpcjkhfjflmjpjjmdegpkgginijbin?hl=en
[EDIT] This is what my appsscript.json looks like:
{
"timeZone": "Europe/Dublin",
"dependencies": {
"enabledAdvancedServices": [{
"userSymbol": "Gmail",
"serviceId": "gmail",
"version": "v1"
}]
},
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.execute",
"https://www.googleapis.com/auth/gmail.readonly",
"https://www.googleapis.com/auth/gmail.send"
],
"gmail": {
"name": "Reply To Many",
"logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/receipt_black_24dp.png",
"contextualTriggers": [{
"unconditional": {
},
"onTriggerFunction": "getContextualAddOn"
}],
"primaryColor": "#41f470",
"secondaryColor": "#94f441",
"version": "TRUSTED_TESTER_V2"
}
}

Did you try implementing the access token? I meant for you to try that first as I believe that's your issue if you don't have it.
// Activate temporary Gmail access token. Where 'e' is the function argument
var accessToken = e.messageMetadata.accessToken;
GmailApp.setCurrentMessageAccessToken(accessToken);
if you have "mail.google.com/", then you don't have a scope problem, as that gives you full access. The only other security issue is the access token.

Try this scope:
https://www.googleapis.com/auth/userinfo.email
I believe that's the one you need if you're calling the Session object, 'getActiveUser'
if this doesn't fix your issue, I don't believe I can help without seeing what you're trying to do.

Related

How to prevent Google Drive API v3 from sending a notification email when giving writer permissions?

I'm able to give writer permissions using the Google Drive API (v3). This is the endpoint:
POST https://www.googleapis.com/drive/v3/files/FILE_ID/permissions"
The API reference says that I should use sendNotificationEmail: false (note, this is a boolean not a string), which is what I'm doing (in v2 this was called sendNotificationEmails).
However, after the call I still get the email from Google saying I've been invited to edit a file. 🤔
sendNotificationEmail: false works as intended, there is one small detail:
It is a request parameter that goes outside of the resource body.
I am not sure which language your are using, if e.g. Javascript, the request would be:
gapi.client.drive.permissions.create({
"fileId": "XXX",
"sendNotificationEmail": false,
"resource": {
"role": "writer",
"type": "user",
"emailAddress": "test#gmail.com"
}
})

OAuth consent screen - ability to remove application logo: old solution is no longer working

Question: how to remove an application logo.
Solution: previous solution from this answer, https://stackoverflow.com/a/57168008/1992004, is no longer working.
Google changed the format of "iconUrl" to "icon", and uses now the Base64-encoded data stream, like "icon":"iVBORw0KGgoAAAAN..., instead of the image URL, previously written as "iconUrl":"https://...".
I've tried "icon":"" and many Base64-encoded values like "icon":"IA", "icon":"Lw", and some of other - no success. I get console messages like
for "icon":""
{
"error": {
"code": 400,
"message": "The request failed because one of the field of the resource is invalid.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.PreconditionFailure",
"violations": [
{
"type": "client_auth_config",
"subject": "?error_code=9&error_field_name=UpdateIconRequest.icon&error_field_value=%3CByteString#3eeee81e+size%3D0+contents%3D%22%22%3E"
}
]
}
]
}
}
or
{
"error": {
"code": 400,
"message": "Request contains an invalid argument.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.identity.clientauthconfig.v1.ClientAuthConfigError",
"code": "ICON_STORAGE_FAILURE"
},
{
"#type": "type.googleapis.com/google.identity.clientauthconfig.v1.IconStorageError",
"reason": "INVALID_IMAGE"
}
]
}
}
or
{
"error": {
"code": 400,
"message": "Invalid value at 'icon' (TYPE_BYTES), Base64 decoding failed for \" \"",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "icon",
"description": "Invalid value at 'icon' (TYPE_BYTES), Base64 decoding failed for \" \""
}
]
}
]
}
}
Does somebody know, what should be inserted here to remove the logo image from the app?
Answer:
Unfortunately, there is no way for this to be done.
More Information:
Once an OAuth Application Logo has been uploaded there isn't a supported way of removing it - in the question that you linked the way that this was done is a bit hacky, inspecting the network requests and building a new request from the previous JSON object sent via the UI really shows this.
As the icon URL has changed to need a Base-64 encoded value this has been deprecated. Whether this was intentional by Google or not is hard to say, but now an empty value will always return INVALID_ARGUMENT. Any data in the value for icon will also just replace the image data and so this isn't a viable workaround, as as far as the validation process goes, image data exists and so will need to be verified.
If it's not too much of a arduous process, the only workaround here is to create a new GCP project with a new OAuth consent screen without uploading an image. Of course, you will need to reactivate all the relevant APIs and link the relevant scripts and projects to the new set-up.
Feature Request:
You can however let Google know that this is a feature that is important and that you would like to request they implement it. Google's Issue Tracker is a place for developers to report issues and make feature requests for their development services. I would suggest using the feature request template for G Suite Add-ons as this is a component for which GCP Projects could be used.
Update: The feature request for this is viewable here, to increase visibility on this, hit the ☆ at the top of the page.
Relevant Questions:
OAuth consent screen - ability to remove application logo [Obsolete]
May 2021 - It is still possible to completely delete the consent screen (and thus allowing to create it again). See my updated answer in https://stackoverflow.com/a/57168008/1992004

Unable to use DriveApp.getFileById(id).getLastUpdated();

I want to know the latest updated date of a file at location "https://drive.google.com/open?id=XYZ". This address is present in A1 cell of my sheet.
But every time it throws this error: "You do not have permission to call DriveApp.getFileById. Required permissions: (https://www.googleapis.com/auth/drive.readonly || https://www.googleapis.com/auth/drive) (line 3)."
I have made changes in appScript.jason file also.
This is the code that I have written in script editor and call from B1 cell:
function useThis(url){
var id = getIdFromUrl(url);
return DriveApp.getFileById(id).getLastUpdated();
}
function getIdFromUrl(url) {
return url.match(/[-\w]{25,}/);
}
Also, my appscript.json looks like this:
{
"timeZone": "Asia/Kolkata",
"dependencies": {
},
"exceptionLogging": "STACKDRIVER",
"oauthScopes": [
"https://www.googleapis.com/auth/spreadsheets.readonly",
"https://www.googleapis.com/auth/userinfo.email"
]
}
Is there a way I can resolve this. Or any other easier way to get last updated date of a file in google drive?
Custom functions are not applicable to your use case as they can only call services that do not require access to personal data. See GAS documentation on custom functions
If your custom function throws the error message You do not have
permission to call X service., the service requires user authorization
and thus cannot be used in a custom function.

Unable to create webhook for Autodesk BIM 360 docs project

I am trying to create a webhook for Autodesk BIM 360 project and ended with this error - "Access denied for the scope that you are trying to create hook on". I am using Postman to test the webhook creation - Here is the response which I am getting -
{
"hooks": [],
"errors": [
{
"id": "071ec72d-20b5-40c1-9451-ee9cdf573984",
"status": 403,
"code": "FORBIDDEN_ERROR",
"detail": [
"Access denied for the scope <projectId> that you are trying to create hook on"
],
"source": {
"sysType": "adsk.wipprod",
"eventType": "fs.file.added",
"callbackUrl": "http://6bd04cad.ngrok.io/webhooks/bim360",
"scope": {
"folder": "<projectId>"
},
"hookAttribute": null
}
}
]
}
What are the scopes you are passing on, did you follow this tutorial? Has the trial been activated for your keys?
https://developer.autodesk.com/en/docs/webhooks/v1/tutorials/create-a-hook-data-management/
I was facing this issue due to having old forge application which didn't configure the Webhook. Now I have enabled it and it's fixed.
Now I am facing a different issue which is related to access denied. Here is the detail -
creating a Webhook for BIM 360 docs using Autodesk forge custom integration. I am following this Webhook API documentation https://developer.autodesk.com/en/docs/webhooks/v1/reference/http/systems-system-events-event-hooks-POST/ and am constantly getting this response.
{
“id”: “888134c7-fd22-4676-b907-d8441477dde4",
“status”: 403,
“code”: “FORBIDDEN_ERROR”,
“detail”: [
“Access denied for the scope b.2210c698-4e4b-47d0-b579-f92a969ef365 that you are trying to create hook on”
]
}
From your question, it seems that you used the projectId or hubId, make sure to use folderId as the scope, it should be similar to urn:adsk.wipprod:fs.folder:abcd1234

Gmail App Scripts AddOn: XMLHttpRequest Error

I am developing a Gmail App Scripts Ad-On. I am able to create cards, and child cards, and add controls to the cards, and it works well. However, I need to add functionality to make an oData call to a web service in another application. As soon as I add the following line in my code.gs file I get the error shown below when I run my add-on in Gmail.
var req = new XMLHttpRequest();
ReferenceError: "XMLHttpRequest" is not defined. [line: 187, function: gotoChildCard, file: Code]
It never even gets beyond that line, so it is not any problem with oData structure or anything, it does not like that line. I have tried to find some posts, but I cannot find anything (I did find some people getting this error when they develop a Chrome Extension, but that is different - I am creating a Gmail App Scripts Add-On). I was thinking that maybe I need to add something to my manifest file, but if so, I do not know what it is.
below is my appscript.json file:
`{
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.execute",
"https://www.googleapis.com/auth/gmail.readonly"
],
"gmail": {
"name": "Dean's Gmail Add-On: Multiple Cards for Set ",
"logoUrl": "https://www.gstatic.com/images/icons/material/system/2x/bookmark_black_24dp.png",
"contextualTriggers": [{
"unconditional": {
},
"onTriggerFunction": "createNavigationCard"
}],
"openLinkUrlPrefixes": [
"https://mail.google.com/"
],
"primaryColor": "#4285F4",
"secondaryColor": "#4285F4",
"version": "TRUSTED_TESTER_V2"
}
}
You can only make HTTP requests using the UrlFetchApp in Apps Scripts