@dxdeveloperexperience/hygie
Version:
Hygie is an easy-to-use Open-Source REST API allowing you to interact with GIT events. This NestJS API expose a set of customizable rules to automate your project's life cycle.
181 lines (164 loc) • 5.07 kB
text/typescript
import { Runnable } from './runnable.class';
import { RuleResult } from '../rules/ruleResult';
import { readFile, writeFile } from 'fs-extra';
import { createInterface } from 'readline';
import { google } from 'googleapis';
import { logger } from '../logger/logger.service';
import { CallbackType } from './runnables.service';
import { RunnableDecorator } from './runnable.decorator';
import { Inject } from '@nestjs/common';
import { Visitor } from 'universal-analytics';
import { EnvVarAccessor } from '../env-var/env-var.accessor';
import { Utils } from '../utils/utils';
function makeBody(to: string, subject: string, message: string): string {
const str = [
'Content-Type: text/html; charset="UTF-8"\n',
'MIME-Version: 1.0\n',
'Content-Transfer-Encoding: 7bit\n',
'to: ',
to,
'\n',
'subject: ',
subject,
'\n\n',
message,
].join('');
const encodedMail = Buffer.from(str)
.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_');
return encodedMail;
}
interface SendEmailArgs {
to: string | string[];
subject: string;
message: string;
}
/**
* `SendEmailRunnable` allows you to send Email with the Gmail API.
* @warn Be sure to have configured the Gmail API as explained in the documentation.
*/
('SendEmailRunnable')
export class SendEmailRunnable extends Runnable {
// If modifying these scopes, delete token.json.
SCOPES = [
'https://mail.google.com/',
'https://www.googleapis.com/auth/gmail.modify',
'https://www.googleapis.com/auth/gmail.compose',
'https://www.googleapis.com/auth/gmail.send',
];
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
TOKEN_PATH = 'token.json';
sendMessage(
authentication,
ruleResult: RuleResult,
args: SendEmailArgs,
): void {
const gmail = google.gmail({ version: 'v1', authentication });
// Convert args.to fied
if (typeof args.to !== 'string') {
args.to = args.to.toString();
}
const content = makeBody(
Utils.render(args.to, ruleResult),
Utils.render(args.subject, ruleResult),
Utils.render(args.message, ruleResult),
);
gmail.users.messages.send(
{
auth: authentication,
userId: 'me',
resource: {
raw: content,
},
},
err => {
err ? logger.error(err) : logger.info('mail sent!');
},
);
}
authorize(credentials, callback, ...args): void {
const { client_secret, client_id, redirect_uris } = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(
client_id,
client_secret,
redirect_uris[0],
);
// Check if we have previously stored a token.
readFile(this.TOKEN_PATH, (err, token) => {
if (err) {
return this.getNewToken(oAuth2Client, callback);
}
oAuth2Client.setCredentials(JSON.parse(token.toString()));
callback(oAuth2Client, ...args);
});
}
getNewToken(oAuth2Client, callback): void {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: this.SCOPES,
});
logger.warn(`Authorize this app by visiting this url: ${authUrl}`);
const rl = createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', code => {
rl.close();
oAuth2Client.getToken(code, (err, token) => {
if (err) {
return logger.error('Error retrieving access token', err);
}
oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
// tslint:disable-next-line:no-shadowed-variable
writeFile(this.TOKEN_PATH, JSON.stringify(token), err => {
if (err) {
return logger.error(err);
}
logger.info('Token stored to', this.TOKEN_PATH);
});
callback(oAuth2Client);
});
});
}
constructor(
('GoogleAnalytics')
private readonly googleAnalytics: Visitor,
private readonly envVarAccessor: EnvVarAccessor,
) {
super();
}
async run(
callbackType: CallbackType,
ruleResult: RuleResult,
args: SendEmailArgs,
): Promise<void> {
ruleResult.env = this.envVarAccessor.getAllEnvVar();
this.googleAnalytics
.event('Runnable', 'sendEmail', ruleResult.projectURL)
.send();
if (
typeof args.to === 'undefined' ||
typeof args.subject === 'undefined' ||
typeof args.message === 'undefined'
) {
return null;
}
readFile('credentials.json')
.then(content => {
// Authorize a client with credentials, then call the Gmail API.
this.authorize(
JSON.parse(content.toString()),
this.sendMessage,
ruleResult,
args,
);
})
.catch(err => {
logger.error('Error loading credentials.json:', err);
});
}
}