DotNet GMail Quickstart application name - gmail-api

I wrote my first Gmail API program in C# starting with the help I found
at:
https://developers.google.com/gmail/api/quickstart/dotnet
The problem is the name of the app, according to Google, listed under "Third-party apps with account access", is "Quickstart", which is not a very descriptive name for my app. Am I stuck with that name?
I've tried to search the source files for "Quickstart" and can't find out where the name is coming from. I've made sure to specify my preferred name in the ApplicationName parameter of the service connect.
// Create Gmail API service.
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "EMailChecker",
});
But that makes no difference. I've tried removing access via my Google account and re-running the program to let it authenticate, but that does not affect. It still shows up as "Quickstart".
So am I stuck with that name? Other than that, the program is working well.

It is also stated in the documentation that if you are modifying these scopes, delete your previously saved credentials at ~/.credentials/gmail-dotnet-quickstart.json.
You may check this link for reference: Where is ~/.credentials/drive-python-quickstart.json saved for Google Drive API Python Implementation?

Related

Use path/slug after Web App's base url in Google Apps Script

I'm looking to make the url by adding a path which is something like this below in Google Apps Script:
https://script.google.com/macros/s/APP_ID/exec/fileName.txt
How can I achieve this for Web App service?
I believe your goal as follows.
You want to access to Web Apps using the URL of https://script.google.com/macros/s/APP_ID/exec/fileName.txt.
For this, how about this answer? I think that you can achieve your goal using Web Apps. As a sample case, I would like to explain about this using a sample script for downloading a text file, when an user accesses to https://script.google.com/macros/s/APP_ID/exec/fileName.txt.
Usage:
Please do the following flow.
1. Create new project of Google Apps Script.
Sample script of Web Apps is a Google Apps Script. So please create a project of Google Apps Script.
If you want to directly create it, please access to https://script.new/. In this case, if you are not logged in Google, the log in screen is opened. So please log in to Google. By this, the script editor of Google Apps Script is opened.
2. Prepare script.
Please copy and paste the following script (Google Apps Script) to the script editor. This script is for the Web Apps.
function doGet(e) {
const path = e.pathInfo;
if (path == "filename.txt") {
const sampleTextData = "sample";
return ContentService.createTextOutput(sampleTextData).downloadAsFile(path);
}
return ContentService.createTextOutput("Wrong path.");
}
In order to retrieve the value of fileName.txt in https://script.google.com/macros/s/APP_ID/exec/fileName.txt, please use pathInfo.
For example, when you check e of doGet(e) by accessing with https://script.google.com/macros/s/APP_ID/exec/fileName.txt, you can retrieve {"contextPath":"","contentLength":-1,"parameter":{},"parameters":{},"queryString":"","pathInfo":"fileName.txt"}.
In this case, the GET method is used.
3. Deploy Web Apps.
On the script editor, Open a dialog box by "Publish" -> "Deploy as web app".
Select "Me" for "Execute the app as:".
By this, the script is run as the owner.
Select "Anyone, even anonymous" for "Who has access to the app:".
In this case, no access token is required to be request. I think that I recommend this setting for your goal.
Of course, you can also use the access token. At that time, please set this to "Anyone". And please include the scope of https://www.googleapis.com/auth/drive.readonly and https://www.googleapis.com/auth/drive to the access token. These scopes are required to access to Web Apps.
Click "Deploy" button as new "Project version".
Automatically open a dialog box of "Authorization required".
Click "Review Permissions".
Select own account.
Click "Advanced" at "This app isn't verified".
Click "Go to ### project name ###(unsafe)"
Click "Allow" button.
Click "OK".
Copy the URL of Web Apps. It's like https://script.google.com/macros/s/###/exec.
When you modified the Google Apps Script, please redeploy as new version. By this, the modified script is reflected to Web Apps. Please be careful this.
4. Run the function using Web Apps.
Please access to https://script.google.com/macros/s/###/exec/filename.txt using your browser. By this, a text file is downloaded.
Note:
When you modified the script of Web Apps, please redeploy the Web Apps as new version. By this, the latest script is reflected to the Web Apps. Please be careful this.
References:
Web Apps
Taking advantage of Web Apps with Google Apps Script
Updated on February 14, 2023
In the current stage, it seems that pathInfo can be used with the access token. It supposes that the following sample script is used.
function doGet(e) {
return ContentService.createTextOutput(JSON.stringify(e));
}
When you log in to your Google account and you access https://script.google.com/macros/s/###/exec/sample.txt with your browser, {"contextPath":"","parameter":{},"pathInfo":"sample.txt","contentLength":-1,"parameters":{},"queryString":""} can be seen.
In this case, when you access it without logging in Google account, even when Web Apps is deployed as Execute as: Me and Who has access to the app: Anyone, the log in screen is opened. Please be careful about this.
And, if you want to access with https://script.google.com/macros/s/###/exec/sample.txt using a script, please request it by including the access token. The sample curl command is as follows. In this case, the access token can be used as the query parameter. Please include one of the scopes of Drive API in the access token.
curl -L "https://script.google.com/macros/s/###/exec/sample.txt?access_token=###"
By this, the following result is returned.
{"contextPath":"","queryString":"access_token=###"},"pathInfo":"sample.txt","parameters":{"access_token":["###"]},"contentLength":-1}

Flutter: Google Drive: File list always returns me 0

I want to retrieve list of files from a Google drive folder. Authentication happens through Service account. Here is my code to do the same:
final _credentials = new ServiceAccountCredentials.fromJson(r'''
{
"private_key_id": "b5-xxxx-17",
"private_key": "-----BEGIN PRIVATE KEY-----\nMI-xxxxk=\n-----END PRIVATE KEY-----\n",
"client_email": "drive-access#xxxx.iam.gserviceaccount.com",
"client_id": "100000000000",
"type": "service_account"
}
''');
final _SCOPES = [SheetsApi.DriveFileScope, SheetsApi.SpreadsheetsScope];
clientViaServiceAccount(_credentials, _SCOPES).then((http_client) {
DriveApi driveApi = DriveApi(http_client);
driveApi.files.list().then((files) {
print('kind: ' + files.kind);
print('list: ' + files.files.length.toString());
});
My log looks like this:
just: drive#fileList
list: 0
In Google Developers console, Google Drive API is enabled and service account it linked properly (as far as I can check).
But I also got another piece of code which writes some data to a spreadsheet, with hardcoded sheetID and that code is working fine.
Any help on what I am doing wrong here?
Retrieving files using Service account:
The service account is different from your Google account. This means that the Google Drive is also different between Service account and your account. So when the file is retrieved using Service account, please share the files in your Google Drive with the Service account. By this, the files in your Google Drive can be retrieved by the Service account.
Scopes:
In your script, DriveFileScope and SpreadsheetsScope are used as the scopes. DriveFileScope is https://www.googleapis.com/auth/drive.file. The official document says this scope as follows.
View and manage Google Drive files and folders that you have opened or created with this app
By this, in your script, how about modifying DriveFileScope as follows?
DriveReadonlyScope (https://www.googleapis.com/auth/drive.readonly)
DriveScope (https://www.googleapis.com/auth/drive)
Note:
I think that this scope can be also used for your situation.
DriveApi.driveMetadataReadOnlyScope (https://www.googleapis.com/auth/drive.metadata.readonly)
References:
Scopes for Google Sheets API, v4
Scopes for Drive API, v3

How to protect web client ID in GCP source code

My GAE app publishes some APIs in GCP and uses the following structure:
# Replace the following lines with client IDs obtained from the APIs
# Console or Cloud Console.
WEB_CLIENT_ID = '????????????.apps.googleusercontent.com'
ALLOWED_CLIENT_IDS = [WEB_CLIENT_ID, endpoints.API_EXPLORER_CLIENT_ID]
SCOPES = [endpoints.EMAIL_SCOPE]
#endpoints.api(name=API_NAME,
version=API_VERSION,
description='An API to manage languages',
allowed_client_ids=ALLOWED_CLIENT_IDS,
scopes=SCOPES)
My doubt is if someone picks this source code from my machine or GitHub project. He or she can access the APIs using the discovered web client id.
What’s the best practice in this case?
I acknowledge that the client can expose the ID and someone have access to it. But I believe that is another matter.
There are many ways you can do this. One way is to always check in a default value for the client ID, so that when people check out your code, they have to modify it to deploy it. You can also move the client ID to its own module and not check it in at all, and make the expectation that they create their own module with their own client ID. This avoids having a modified state for a checked in file all of the time.
The client ID itself is not sufficient information to generate a valid token. The cryptography involved will prevent such a person from accessing your API.

302 status when copying data to another app in AppEngine

I'm trying to use the "Copy to another app" feature of AppEngine and keep getting an error:
Fetch to http://datastore-admin.moo.appspot.com/_ah/remote_api failed with status 302
This is for a Java app but I followed the instructions on setting up a default Python runtime.
I'm 95% sure it's an authentication issue and the call to remote_api is redirecting to the Google login page. Both apps use Google Apps as the authentication mechanism. I've also tried copying to and from a third app we have which uses Google Accounts for authentication.
Notes:
The user account I log in with is an Owner on all three apps. It's a Google Apps account (if that wasn't obvious).
I have a gmail account this is an Owner on all three apps as well. When I log in to the admin console with it, I don't see the datastore admin console at all when I click it.
I'm able to use the remote_api just fine from the command-line after I enter my details
Tried with both the Python remote_api built-in and the Java one.
I've found similar questions/blog posts about this, one of which required logging in from a browser, then manually submitting the ACSID cookie you get after that's done. Can't do that here, obviously.
OK, I think I got this working.
I'll refer to the two appIDs as "source" and "dest".
To enable datastore admin (as you know) you need to upload a Python project with the app.yaml and appengine_config.py files as described in the docs.
Either I misread the docs or there is an error. The "appID" inthe .yaml should be the app ID you are uploading to to enable DS admin.
The other appID in the appengine_config file, specifically this line:
remoteapi_CUSTOM_ENVIRONMENT_AUTHENTICATION = (
'HTTP_X_APPENGINE_INBOUND_APPID', ['appID'])
Should be the appID of the "source", ID the app id of where the data is coming from in the DS copy operation.
I think this line is what allows the source appID to be authenticated as having permissions to write to the "dest" app ID.
So, I changed that .py, uploaded again to my "dest" app ID. To be sure I made this dummy python app as default and left it as that.
Then on the source app ID I tried the DS copy again, and all the copy jobs were kicked off OK - so it seems to have fixed it.

GAE data download shows datastore_errors.BadRequestError

I'm trying to download data from my Google App Engine app, using the official instructions
Remote API is set up & I call:
appcfg.py download_data --application=appname --url=http://app.address.com/_ah/remote_api --filename=alldata.csv
The connection is established, I'm being asked for my e-mail & password, and then a long trace appears ending up with this:
google.appengine.api.datastore_errors.BadRequestError: app s~appname cannot access app appname's data
Any ideas?
If using the high-replication datastore, change the value passed to --application from appname to s~appname.
Found the problem - as an URL I was giving my own app's domain name instead of the 1.appname.appspot.com.
I ran into this same issue, but when attempting to use the remote API from a custom script as opposed to appcfg.py's bulk downloader.
This issue may have been addressed in more recent GAE SDK releases, but for various reasons I'm still using the older 1.7 release. I found the answer in this bug report: https://code.google.com/p/googleappengine/issues/detail?id=4374
Basically, when calling ConfigureRemoteApi, don't specify the APP_ID argument (just pass None) and specify your app ID via the host argument, e.g. 'myapp-hrd.appspot.com'. ConfigureRemoteApi will figure out your app ID correctly and won't add the 's~' that causes this problem.

Resources