@bhavinkumarvegad/playwright-email-utils
Version:
Reusable utilities for handling emails in Playwright tests from Yopmail, Gmail and other providers.
101 lines (87 loc) • 3.2 kB
text/typescript
import { google } from 'googleapis';
import dotenv from 'dotenv';
export interface GmailMessage {
id?: string;
raw?: string;
headers?: Array<{
name: string;
value: string;
}>;
labelIds?: string[];
snippet?: string;
body?: string;
subject?: string;
from?: string;
to?: string;
}
dotenv.config();
export class GmailAPI {
private static GMAIL_REDIRECT_URI = 'http://localhost';
private constructor() {}
private static async getOAuth2Client(clientId: string, clientSecret: string, refreshToken: string) {
const oAuth2Client = new google.auth.OAuth2(
clientId,
clientSecret,
this.GMAIL_REDIRECT_URI
);
oAuth2Client.setCredentials({ refresh_token: refreshToken });
return oAuth2Client;
}
private static async getGmail(clientId: string, clientSecret: string, refreshToken: string) {
const auth = await this.getOAuth2Client(clientId, clientSecret, refreshToken);
return google.gmail({ version: 'v1', auth });
}
static async getAccessToken(clientId: string, clientSecret: string, refreshToken: string): Promise<string> {
const oAuth2Client = await this.getOAuth2Client(clientId, clientSecret, refreshToken);
const { token } = await oAuth2Client.getAccessToken();
return token || '';
}
static async listMessages(clientId: string, clientSecret: string, refreshToken: string, query: string): Promise<GmailMessage[]> {
const gmail = await this.getGmail(clientId, clientSecret, refreshToken);
const res = await gmail.users.messages.list({
userId: 'me',
q: query,
});
return (res.data.messages || []).map(msg => ({
id: msg.id || undefined,
labelIds: msg.labelIds || undefined
}));
}
static async getMessage(clientId: string, clientSecret: string, refreshToken: string, msgId: string): Promise<GmailMessage> {
const gmail = await this.getGmail(clientId, clientSecret, refreshToken);
const res = await gmail.users.messages.get({
userId: 'me',
id: msgId,
format: 'full',
});
// Extract headers
const headers = res.data.payload?.headers?.map(h => ({
name: h.name || '',
value: h.value || ''
})) || [];
// Find email metadata
const subject = headers.find(h => h.name.toLowerCase() === 'subject')?.value;
const from = headers.find(h => h.name.toLowerCase() === 'from')?.value;
const to = headers.find(h => h.name.toLowerCase() === 'to')?.value;
// Decode email body
let body = '';
if (res.data.payload?.body?.data) {
body = Buffer.from(res.data.payload.body.data, 'base64').toString('utf8');
} else if (res.data.payload?.parts) {
const textPart = res.data.payload.parts.find(part => part.mimeType === 'text/plain');
if (textPart?.body?.data) {
body = Buffer.from(textPart.body.data, 'base64').toString('utf8');
}
}
return {
id: res.data.id || undefined,
headers,
labelIds: res.data.labelIds || undefined,
snippet: res.data.snippet || undefined,
body,
subject,
from,
to
};
}
}