This process will allow you to set up a private application in your personal G Suite environment. Setting up a private/local environment for your G Suite uses and applications will allow you to bypass most of Google's ever increasingly strict security rules, mainly aimed at apps spanning more than one G Suite environment or normal "gmail.com" users.
This process will be documented without using a web interface callback. It will allow you to retrieve a security code which in turn will be exchanged for a token for a specific user and project. Once that is done, using the G4GBASE product you can automatically renew the OAuth 2.0 tokens within your applications.
If setting up a web callback is something you wish to do, please contact us and we can put something together for you if we don't already have such an application.
Step one is to set up the application in your GSuite Environment. This example will be done using the GMail Application APIs, but this can be substituted for any API available from Google.
Visit https://www.bvstools.com/g4g.html to download the latest version of G4G. If you haven't licensed it yet, be sure to use the Quick Key feature to request a temporary key for G4G. This will automatically email you a temporary license key for the G4G base product, the G4G addons as well a GETURI.
Open a browser and visit https://console.developers.google.com. This will allow you to sign into your G Suite account.
Once you sign into your G Suite API and Service Dashboard you will see a drop down box at the top that says "Select a project".
Select the drop down arrow and select the NEW PROJECT option at the top right.
You will now see a screen that will allow you to create projects. You may have a quota, or you may not.
We will now name our project and select the CREATE button. In this case we named our project G4G - Drive Calendar GMail as we will be applying multiple scopes to this project.
You should now see an option on the main screen that says "Get Started".
Enter the App Name and contact information. Click Next and fill out the "Audience" section selecting "Internal". Click Next and Fill out the Contact Information. Click next and Check the "Agree" box and select the Create button.
We now need to add a callback URL of http://localhost. This will allow us to capture the OAuth 2.0 Code during the OAuth flow.
Select Clients from the left menu, the select the client you created (probably named Web Client 1).
Scroll downn to the Add Redirect URIs. Select the Add URI option, enter http://localhost for the URI and then click the Save button.
We will now add scopes required for access to GMail, Drive and Calendar.
From the left menu, select Data Access. You should see a screen that allows you to add or remove scopes.
Click on the Add or Remove Scopes button.
Use the seach to find scopes for GMail, Drive and Calendar and add them to your application. The scopes should be as follows:
https://www.googleapis.com/auth/drive
You can also go to the bottom of the scope list and paste these scopes manually:
Once they are entered, select Add To Table and they should appear checked at the top of the scope selection list.
Click the Update button at the bottom of the screen to apply these scopes.
From the Overview options, select the "Create OAuth Client" option.
For Application Type select "Web Application". For the Name you can enter anything you wish.
Finally, click Create at the bottom of the screen.
You will be presented with a window that has your Client ID and Secret.
You will want to copy these items and store them somewhere safe as the Secret cannot be retrieved after this point. You can create a new secret if you need to.
Now click on the navigation item at the top left of the screen and select APIs & Services ---> Credentials
Now select the Create Credentials option and select API Key.
When this option completes you will be shown a window with an API key. Copy this value and put it with your Client ID and Secret.
Next, from the left menu, select the Endabled APIs & Services option and select Enable APIs and Services.
Because we are enabling GMail, Calendar and Drive in one application we will find each of these three APIs and add them to the project. Use the Search Box to find the APIs, select them, and select the Enable option for each one.
You will now want to set up your application in the G4G database. Using your favorite file update tool (UPDDTA, etc) add a new record to the G4GSVCPF file. The following fields should contain the following values:
GGSSERVICE - This will be the service name. For this example, I called my *G4GMAPLESTONE so I know it's a catch all for the 3 APIs/Scopes we set up for my MapleStone account.
GGSSCOPE - This is the scope of your project. Each scope should be separated by %20 (encoded space). https://mail.google.com/%20https://www.googleapis.com/auth/drive%20https://www.googleapis.com/auth/calendar
GGSAPPID - This will be the application's Client ID (or application ID).
GGSAPIKEY - This will be the application's API Key.
GGSCSECRET - This will be the Client Secret.
GGSAUTHURL - Leave this blank.
GGSTKNURL - This will be the URL used to request a token from Google. The value to use (which could change in the future) is https://accounts.google.com:443/o/oauth2/token. If you choose, you can leave off the :443 portion of the URL. This is only hear in case for some reason you need to use a proxy for your HTTP requests.
GGSCBURL - This is the callback URL. It needs to be the same callback URL (URI) that we set up for the application. In our case it was http://localhost.
You will now want to create a link to retrieve your OAuth Code. The link will be as follows:
https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=<your client id>&redirect_uri=http%3A%2F%2Flocalhost&access_type=offline&approval_prompt=force&scope=https://mail.google.com/%20https://www.googleapis.com/auth/drive%20https://www.googleapis.com/auth/calendar
Be sure to replace <your client id> with the client ID for your application.
Once you have this link created, paste it into a browser. You should be presented with an option to sign on with an account. Sign on with the account from your organisation that you wish to set up.
You will then be presented with a screen that asks to grant permission for your application for your account. Click the Allow button.
You will now be redirected to a page that will appear to be an error. While it is and error (unless for some reason you have localhost set up on your PC in the hosts file to point to a web server), the OAuth code we need is in the URI at the top of the screen.
Important:
This code will be good for about 1-2 minutes, so be prepared ahead of time to clip this code for the next step.
Copy and paste this code value to a text file. If you need to copy the entire URI to see the entire code, you can do that as well. The code will be following the "code=" text and ends before the next "&" as shown highlighted and circled in this screen shot:
The entire URI here is:
All we want is the data after "code=" and before the next "&". So in this case, the code we want is 4/jwEcWFE3TXZ0vT6rObWw0-JkK7YfSYE53Kalzn9Es8p4EGTyd4HEt3-y5Pv6zRLIaadNI4zVCW0e7LM8CgyuIUk.
We will now use this code to register the service for the user using the G4GTOKEN command. The code will be exchanged with Google for a token and refresh token. Once this is complete, all of the token renewal is done internally by the G4G application functions.
Retrieve Token (G4GTOKEN)
Type choices, press Enter.
Google ID . . . . . . . . . . . > bvstone@maplestonmn.com
Service . . . . . . . . . . . . > *G4GMAPLESTONE
Google Authorization Code . . . > '4/jwEcWFE3TXZ0vT6rObWw0-JkK7YfSYE53Kalzn9Es8p4EGTyd4HEt3-y5Pv6zRLIaadNI4zVCW0e7LM8CgyuIUk'
For the Google ID, enter the ID that you used previously when granting permissions to your application.
For Service, enter the service name you created previously in the G4GSVCPF file.
For the Google Authorization Code, copy and paste the code retrieved from the URL in the previous step.
If the user is already set up, this will update the user with a new token and refresh token. This is useful in cases where you are having issues refreshing the user's token, changed scopes for your application, or changed other settings for the application.
If the user is not set up, this will set them up with their initial token and refresh token.
If for any reason there is an error returned, you may need to visit the page with the code, select the back button and re-confirm your choice to grant permissions. A new code will be generated. The code is only active for a little while, so these last steps should all be done in sequence in a short period of time.
You can now call the Google APIs that you enabled for the user that was set up. Before the call to each Google API, you will want to call the g4g_refreshToken() function which will either return the current valid token, or if the token is expired (or soon to be), the G4G application will automatically refresh to the token with Google and return the new token to your application.
Example:
id = 'bvstone@maplestonemn.com';
service = '*G4GMAPLESTONE';
token = ' ';
errMsg = ' ';
rc = g4g_refreshToken(id:service:token:errMsg);
if (rc < 0);
//error!
else;
// call your Google API here, using the token returned
endif;
Following is a sample application that retrieves labels from a GMail Account.
We are also working on allowing you to use your own service in the G4G addon libraries which should be available early 2026.
**FREE
ctl-opt DFTACTGRP(*NO) ACTGRP('G4G') BNDDIR('G4G');
// Imports
/COPY QCOPYSRC,P.G4G
/COPY QCOPYSRC,GETURICOPY
//Prototypes
dcl-pr GetUriRG extpgm('GETURIRG');
PR_In like(GetUri_In);
PR_Out like(GetUri_Out);
PR_Head like(GetUri_Head);
PR_Data like(GetUri_Data);
PR_MsgCd like(GetUri_MsgCd);
PR_Msg like(GetUri_Msg);
end-pr;
// Work Variables
dcl-s id char(256) INZ('bvstone@maplestonemn.com');
dcl-s service char(256) INZ('*GMAILMAPLESTONE');
dcl-s token char(256);
dcl-s errMsg char(256);
dcl-s jsonFile char(256);
dcl-s rc int(10);
jsonFile = '/tmp/gmailtest_output.json';
rc = g4g_refreshToken(id:service:token:errMsg);
if (rc < 0) or (token = '');
//error!
endif;
Clear GetUri_In;
GI_URI = 'https://www.googleapis.com:443' +
'/gmail/v1/users/me/labels';
GI_Data = 'key=' + %trimr(g4g_getAPIKey(service));
GI_Port = 443;
GI_ReqMeth = 'GET';
GI_NbrHdrs = 1;
GI_UsrHdr(1) = 'Authorization';
GI_UsrHdrDta(1) = 'Bearer ' + %trim(token);
GI_SSL = '*YES';
GI_SprHead = '*YES';
GI_HTTPVer = '1.1';
GI_Debug = '*YES';
GI_DebugFile = '/tmp/gmailtest_debug.txt';
GI_OutType = '*STMF';
GI_STMF = jsonFile;
callp(e) GetUriRG(GetUri_In:GetUri_Out:GetUri_Head:GetUri_Data:
GetUri_MsgCd:GetUri_Msg);
if (%error);
// process error
endif;
*INLR = *ON;
return;
Once this programs runs you should have a file in the IFS named /tmp/gmailtest_output.json (plus possibly other files especially if you have debug turned on with GETURI).
The file should be a JSON file containing a list of labels from the specified GMail account and will look like the following:
{
"labels": [
{
"id": "CATEGORY_PERSONAL",
"name": "CATEGORY_PERSONAL",
"type": "system"
},
{
"id": "CATEGORY_SOCIAL",
"name": "CATEGORY_SOCIAL",
"type": "system"
},
{
"id": "IMPORTANT",
"name": "IMPORTANT",
"type": "system"
},
{
"id": "CATEGORY_UPDATES",
"name": "CATEGORY_UPDATES",
"type": "system"
},
{
"id": "CATEGORY_FORUMS",
"name": "CATEGORY_FORUMS",
"type": "system"
},
{
"id": "CHAT",
"name": "CHAT",
"messageListVisibility": "hide",
"labelListVisibility": "labelHide",
"type": "system"
},
{
"id": "SENT",
"name": "SENT",
"type": "system"
},
{
"id": "INBOX",
"name": "INBOX",
"messageListVisibility": "hide",
"labelListVisibility": "labelShow",
"type": "system"
},
{
"id": "TRASH",
"name": "TRASH",
"messageListVisibility": "hide",
"labelListVisibility": "labelHide",
"type": "system"
},
{
"id": "CATEGORY_PROMOTIONS",
"name": "CATEGORY_PROMOTIONS",
"type": "system"
},
{
"id": "DRAFT",
"name": "DRAFT",
"type": "system"
},
{
"id": "SPAM",
"name": "SPAM",
"messageListVisibility": "hide",
"labelListVisibility": "labelHide",
"type": "system"
},
{
"id": "STARRED",
"name": "STARRED",
"type": "system"
},
{
"id": "UNREAD",
"name": "UNREAD",
"type": "system"
}
]
}
So, once you have this you can use your favorite JSON parser to read through the data to process it.