diff --git a/packages/nodes-base/credentials/GoogleApi.credentials.ts b/packages/nodes-base/credentials/GoogleApi.credentials.ts
index 9a777496d0..4f411a5229 100644
--- a/packages/nodes-base/credentials/GoogleApi.credentials.ts
+++ b/packages/nodes-base/credentials/GoogleApi.credentials.ts
@@ -10,7 +10,7 @@ export class GoogleApi implements ICredentialType {
 	documentationUrl = 'google';
 	properties = [
 		{
-			displayName: 'Email',
+			displayName: 'Service Account Email',
 			name: 'email',
 			type: 'string' as NodePropertyTypes,
 			default: '',
@@ -25,5 +25,25 @@ export class GoogleApi implements ICredentialType {
 			default: '',
 			description: 'Use the multiline editor. Make sure there are exactly 3 lines.<br />-----BEGIN PRIVATE KEY-----<br />KEY IN A SINGLE LINE<br />-----END PRIVATE KEY-----',
 		},
+		{
+			displayName: ' Impersonate a User',
+			name: 'inpersonate',
+			type: 'boolean' as NodePropertyTypes,
+			default: false,
+		},
+		{
+			displayName: 'Email',
+			name: 'delegatedEmail',
+			type: 'string' as NodePropertyTypes,
+			default: '',
+			displayOptions: {
+				show: {
+					inpersonate: [
+						true,
+					],
+				},
+			},
+			description: 'The email address of the user for which the application is requesting delegated access.',
+		},
 	];
 }
diff --git a/packages/nodes-base/nodes/Google/Books/GenericFunctions.ts b/packages/nodes-base/nodes/Google/Books/GenericFunctions.ts
index 56105c4f04..ef3f6187e3 100644
--- a/packages/nodes-base/nodes/Google/Books/GenericFunctions.ts
+++ b/packages/nodes-base/nodes/Google/Books/GenericFunctions.ts
@@ -103,7 +103,7 @@ function getAccessToken(this: IExecuteFunctions | IExecuteSingleFunctions | ILoa
 	const signature = jwt.sign(
 		{
 			'iss': credentials.email as string,
-			'sub': credentials.email as string,
+			'sub': credentials.delegatedEmail || credentials.email as string,
 			'scope': scopes.join(' '),
 			'aud': `https://oauth2.googleapis.com/token`,
 			'iat': now,
diff --git a/packages/nodes-base/nodes/Google/Drive/GenericFunctions.ts b/packages/nodes-base/nodes/Google/Drive/GenericFunctions.ts
index cabaa1e7d4..36919cba27 100644
--- a/packages/nodes-base/nodes/Google/Drive/GenericFunctions.ts
+++ b/packages/nodes-base/nodes/Google/Drive/GenericFunctions.ts
@@ -66,6 +66,8 @@ export async function googleApiRequest(this: IExecuteFunctions | IExecuteSingleF
 
 			} else if (error.response.body.error.message) {
 				errorMessages = error.response.body.error.message;
+			} else if (error.response.body.error_description) {
+				errorMessages = error.response.body.error_description;
 			}
 
 			throw new Error(`Google Drive error response [${error.statusCode}]: ${errorMessages}`);
@@ -107,7 +109,7 @@ function getAccessToken(this: IExecuteFunctions | IExecuteSingleFunctions | ILoa
 	const signature = jwt.sign(
 		{
 			'iss': credentials.email as string,
-			'sub': credentials.email as string,
+			'sub': credentials.delegatedEmail || credentials.email as string,
 			'scope': scopes.join(' '),
 			'aud': `https://oauth2.googleapis.com/token`,
 			'iat': now,
diff --git a/packages/nodes-base/nodes/Google/Gmail/GenericFunctions.ts b/packages/nodes-base/nodes/Google/Gmail/GenericFunctions.ts
index c86752fcb9..3dc2eabe92 100644
--- a/packages/nodes-base/nodes/Google/Gmail/GenericFunctions.ts
+++ b/packages/nodes-base/nodes/Google/Gmail/GenericFunctions.ts
@@ -23,10 +23,15 @@ import {
 	IEmail,
 } from './Gmail.node';
 
+import * as moment from 'moment-timezone';
+
+import * as jwt from 'jsonwebtoken';
+
 const mailComposer = require('nodemailer/lib/mail-composer');
 
 export async function googleApiRequest(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, method: string,
 	endpoint: string, body: any = {}, qs: IDataObject = {}, uri?: string, option: IDataObject = {}): Promise<any> { // tslint:disable-line:no-any
+	const authenticationMethod = this.getNodeParameter('authentication', 0, 'serviceAccount') as string;
 	let options: OptionsWithUri = {
 		headers: {
 			'Accept': 'application/json',
@@ -46,8 +51,22 @@ export async function googleApiRequest(this: IExecuteFunctions | IExecuteSingleF
 			delete options.body;
 		}
 
-		//@ts-ignore
-		return await this.helpers.requestOAuth2.call(this, 'gmailOAuth2', options);
+		if (authenticationMethod === 'serviceAccount') {
+			const credentials = this.getCredentials('googleApi');
+
+			if (credentials === undefined) {
+				throw new Error('No credentials got returned!');
+			}
+
+			const { access_token } = await getAccessToken.call(this, credentials as IDataObject);
+
+			options.headers!.Authorization = `Bearer ${access_token}`;
+			//@ts-ignore
+			return await this.helpers.request(options);
+		} else {
+			//@ts-ignore
+			return await this.helpers.requestOAuth2.call(this, 'gmailOAuth2', options);
+		}
 
 	} catch (error) {
 		if (error.response && error.response.body && error.response.body.error) {
@@ -64,6 +83,8 @@ export async function googleApiRequest(this: IExecuteFunctions | IExecuteSingleF
 
 			} else if (error.response.body.error.message) {
 				errorMessages = error.response.body.error.message;
+			} else if (error.response.body.error_description) {
+				errorMessages = error.response.body.error_description;
 			}
 
 			throw new Error(`Gmail error response [${error.statusCode}]: ${errorMessages}`);
@@ -190,3 +211,50 @@ export function extractEmail(s: string) {
 	const data = s.split('<')[1];
 	return data.substring(0, data.length - 1);
 }
+
+function getAccessToken(this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, credentials: IDataObject): Promise<IDataObject> {
+	//https://developers.google.com/identity/protocols/oauth2/service-account#httprest
+
+	const scopes = [
+		'https://www.googleapis.com/auth/books',
+	];
+
+	const now = moment().unix();
+
+	const signature = jwt.sign(
+		{
+			'iss': credentials.email as string,
+			'sub': credentials.delegatedEmail || credentials.email as string,
+			'scope': scopes.join(' '),
+			'aud': `https://oauth2.googleapis.com/token`,
+			'iat': now,
+			'exp': now + 3600,
+		},
+		credentials.privateKey as string,
+		{
+			algorithm: 'RS256',
+			header: {
+				'kid': credentials.privateKey as string,
+				'typ': 'JWT',
+				'alg': 'RS256',
+			},
+		},
+	);
+
+	const options: OptionsWithUri = {
+		headers: {
+			'Content-Type': 'application/x-www-form-urlencoded',
+		},
+		method: 'POST',
+		form: {
+			grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
+			assertion: signature,
+		},
+		uri: 'https://oauth2.googleapis.com/token',
+		json: true,
+	};
+
+	//@ts-ignore
+	return this.helpers.request(options);
+}
+
diff --git a/packages/nodes-base/nodes/Google/Gmail/Gmail.node.ts b/packages/nodes-base/nodes/Google/Gmail/Gmail.node.ts
index 33c458db74..5601c259c5 100644
--- a/packages/nodes-base/nodes/Google/Gmail/Gmail.node.ts
+++ b/packages/nodes-base/nodes/Google/Gmail/Gmail.node.ts
@@ -78,12 +78,46 @@ export class Gmail implements INodeType {
 		inputs: ['main'],
 		outputs: ['main'],
 		credentials: [
+			{
+				name: 'googleApi',
+				required: true,
+				displayOptions: {
+					show: {
+						authentication: [
+							'serviceAccount',
+						],
+					},
+				},
+			},
 			{
 				name: 'gmailOAuth2',
 				required: true,
+				displayOptions: {
+					show: {
+						authentication: [
+							'oAuth2',
+						],
+					},
+				},
 			},
 		],
 		properties: [
+			{
+				displayName: 'Authentication',
+				name: 'authentication',
+				type: 'options',
+				options: [
+					{
+						name: 'Service Account',
+						value: 'serviceAccount',
+					},
+					{
+						name: 'OAuth2',
+						value: 'oAuth2',
+					},
+				],
+				default: 'oAuth2',
+			},
 			{
 				displayName: 'Resource',
 				name: 'resource',
diff --git a/packages/nodes-base/nodes/Google/Sheet/GenericFunctions.ts b/packages/nodes-base/nodes/Google/Sheet/GenericFunctions.ts
index 1ac6a2658b..21831fc9b7 100644
--- a/packages/nodes-base/nodes/Google/Sheet/GenericFunctions.ts
+++ b/packages/nodes-base/nodes/Google/Sheet/GenericFunctions.ts
@@ -94,7 +94,7 @@ function getAccessToken(this: IExecuteFunctions | IExecuteSingleFunctions | ILoa
 	const signature = jwt.sign(
 		{
 			'iss': credentials.email as string,
-			'sub': credentials.email as string,
+			'sub': credentials.delegatedEmail || credentials.email as string,
 			'scope': scopes.join(' '),
 			'aud': `https://oauth2.googleapis.com/token`,
 			'iat': now,