gpt4free-ts/utils/emailFactory.ts

1133 行
33 KiB
TypeScript

import { AxiosInstance, AxiosRequestConfig, CreateAxiosDefaults } from 'axios';
import { getRandomOne, Lock, md5, randomStr, sleep } from './index';
import { CreateAxiosProxy, CreateNewPage } from './proxyAgent';
import { Page } from 'puppeteer';
import Mailjs from '@cemalgnlts/mailjs';
// @ts-ignore
import * as cheerio from 'cheerio';
export enum TempEmailType {
// need credit card https://rapidapi.com/Privatix/api/temp-mail
TempEmail = 'temp-email',
// not need credit card , hard limit 100/day https://rapidapi.com/calvinloveland335703-0p6BxLYIH8f/api/temp-mail44
TempEmail44 = 'temp-email44',
// not need credit card and not need credit rapid_api_key
TempMailLOL = 'tempmail-lol',
Inbox = 'inbox',
Internal = 'internal',
SmailPro = 'smail-pro',
SmailProGmail = 'smail-pro-gmail',
SmailProGoogleMail = 'smail-pro-googlemail',
SmailProOutlook = 'smail-pro-outlook',
SmailProRandom = 'smail-pro-random',
SmailProStoreGmail = 'smail-pro-storegmail',
Gmail = 'gmail',
EmailNator = 'emailnator',
MailTM = 'mailtm',
YopMail = 'yopmail',
}
const gmailLock = new Lock();
const smailProLock = new Lock();
export function CreateEmail(
tempMailType: TempEmailType,
options?: BaseOptions,
): BaseEmail {
switch (tempMailType) {
case TempEmailType.TempEmail44:
return new TempMail44(options);
case TempEmailType.TempEmail:
return new TempMail(options);
case TempEmailType.TempMailLOL:
return new TempMailLOL(options);
case TempEmailType.Inbox:
return new Inbox(options);
case TempEmailType.Internal:
return new Internal(options);
case TempEmailType.SmailPro:
return new SmailPro({
...options,
lock: smailProLock,
mail: 'gmail.com',
});
case TempEmailType.SmailProGmail:
return new SmailPro({
...options,
lock: smailProLock,
mail: 'gmail.com',
});
case TempEmailType.SmailProGoogleMail:
return new SmailPro({
...options,
lock: smailProLock,
mail: 'googlemail.com',
});
case TempEmailType.SmailProOutlook:
return new SmailPro({
...options,
lock: smailProLock,
mail: 'outlook.com',
});
case TempEmailType.SmailProRandom:
return new SmailPro({
...options,
lock: smailProLock,
mail: 'random',
});
case TempEmailType.SmailProStoreGmail:
return new SmailPro({
...options,
lock: smailProLock,
mail: 'storegmail.net',
});
case TempEmailType.Gmail:
return new Gmail({ ...options, lock: gmailLock });
case TempEmailType.EmailNator:
return new EmailNator(options);
case TempEmailType.MailTM:
return new MailTM();
case TempEmailType.YopMail:
return new YopMail();
default:
throw new Error('not support TempEmailType');
}
}
export interface BaseMailMessage {
// main content of email
content: string;
}
export interface TempMailMessage extends BaseMailMessage {
_id: {
oid: string;
};
createdAt: {
milliseconds: number;
};
mail_id: string;
mail_address_id: string;
mail_from: string;
mail_subject: string;
mail_preview: string;
mail_text_only: string;
mail_text: string;
mail_html: string;
mail_timestamp: number;
mail_attachments_count: number;
mail_attachments: {
attachment: any[];
};
}
interface BaseOptions {}
abstract class BaseEmail {
public constructor(options?: BaseOptions) {}
public abstract getMailAddress(): Promise<string>;
public abstract waitMails(): Promise<BaseMailMessage[]>;
}
export interface TempMailOptions extends BaseOptions {
apikey?: string;
}
class Inbox extends BaseEmail {
private readonly client: AxiosInstance;
private address: string | undefined;
constructor(options?: TempMailOptions) {
super(options);
const apikey = options?.apikey || process.env.rapid_api_key;
if (!apikey) {
throw new Error('Need apikey for TempMail');
}
this.client = CreateAxiosProxy(
{
baseURL: 'https://inboxes-com.p.rapidapi.com',
headers: {
'X-RapidAPI-Key': apikey,
'X-RapidAPI-Host': 'inboxes-com.p.rapidapi.com',
},
} as CreateAxiosDefaults,
false,
);
}
public async getMailAddress(): Promise<string> {
this.address = `${randomStr()}@${await this.randomDomain()}`;
const res = await this.client.post(`inboxes/${this.address}`);
console.log(res.data);
return this.address;
}
public async waitMails(): Promise<TempMailMessage[]> {
return new Promise((resolve) => {
let time = 0;
const itl = setInterval(async () => {
const response = await this.client.get(`inboxes/${this.address}`);
if (response.data && response.data.length > 0) {
resolve(
response.data.map((item: any) => ({
...item,
content: item.mail_html,
})),
);
clearInterval(itl);
return;
}
if (time > 5) {
resolve([]);
clearInterval(itl);
return;
}
time++;
}, 10000);
});
}
async getDomainsList(): Promise<string[]> {
const res = await this.client.get(`/domains`);
return res.data.map((item: any) => item.qdn);
}
async randomDomain(): Promise<string> {
const domainList = await this.getDomainsList();
return domainList[Math.floor(Math.random() * domainList.length)];
}
}
class TempMail extends BaseEmail {
private readonly client: AxiosInstance;
private address: string | undefined;
private mailID: string = '';
constructor(options?: TempMailOptions) {
super(options);
const apikey = options?.apikey || process.env.rapid_api_key;
if (!apikey) {
throw new Error('Need apikey for TempMail');
}
this.client = CreateAxiosProxy({
baseURL: 'https://privatix-temp-mail-v1.p.rapidapi.com/request/',
headers: {
'X-RapidAPI-Key': apikey,
'X-RapidAPI-Host': 'privatix-temp-mail-v1.p.rapidapi.com',
},
} as CreateAxiosDefaults);
}
public async getMailAddress(): Promise<string> {
this.address = `${randomStr()}${await this.randomDomain()}`;
this.mailID = md5(this.address);
return this.address;
}
public async waitMails(): Promise<TempMailMessage[]> {
const mailID = this.mailID;
return new Promise((resolve) => {
let time = 0;
const itl = setInterval(async () => {
const response = await this.client.get(`/mail/id/${mailID}`);
if (response.data && response.data.length > 0) {
resolve(
response.data.map((item: any) => ({
...item,
content: item.mail_html,
})),
);
clearInterval(itl);
return;
}
if (time > 5) {
resolve([]);
clearInterval(itl);
return;
}
time++;
}, 10000);
});
}
async getDomainsList(): Promise<string[]> {
const res = await this.client.get(`/domains/`);
return res.data;
}
async randomDomain(): Promise<string> {
const domainList = await this.getDomainsList();
return domainList[Math.floor(Math.random() * domainList.length)];
}
}
class TempMail44 extends BaseEmail {
private readonly client: AxiosInstance;
private address: string = '';
constructor(options?: TempMailOptions) {
super(options);
const apikey = options?.apikey || process.env.rapid_api_key;
if (!apikey) {
throw new Error('Need apikey for TempMail');
}
this.client = CreateAxiosProxy(
{
baseURL: 'https://temp-mail44.p.rapidapi.com/api/v3/email/',
headers: {
'X-RapidAPI-Key': apikey,
'X-RapidAPI-Host': 'temp-mail44.p.rapidapi.com',
},
} as CreateAxiosDefaults,
false,
);
}
public async getMailAddress(): Promise<string> {
const response = await this.client.post('/new', {}, {
headers: {
'content-type': 'application/json',
},
} as AxiosRequestConfig);
this.address = response.data.email;
return this.address;
}
public async waitMails(): Promise<TempMailMessage[]> {
return new Promise((resolve) => {
let time = 0;
const itl = setInterval(async () => {
try {
const response = await this.client.get(`/${this.address}/messages`);
if (response.data && response.data.length > 0) {
resolve(
response.data.map((item: any) => ({
...item,
content: item.body_html,
})),
);
clearInterval(itl);
return;
}
if (time > 5) {
resolve([]);
clearInterval(itl);
return;
}
time++;
} catch (e: any) {
console.error('tempmail lol error', e.message);
}
}, 10000);
});
}
}
class TempMailLOL extends BaseEmail {
private readonly client: AxiosInstance;
private address: string = '';
private token: string = '';
constructor(options?: TempMailOptions) {
super(options);
this.client = CreateAxiosProxy({
baseURL: 'https://api.tempmail.lol',
} as CreateAxiosDefaults);
}
public async getMailAddress(): Promise<string> {
const response = await this.client.get('/generate');
this.address = response.data.address;
this.token = response.data.token;
return this.address;
}
public async waitMails(): Promise<TempMailMessage[]> {
return new Promise((resolve) => {
let time = 0;
const itl = setInterval(async () => {
const response = await this.client.get(`/auth/${this.token}`);
if (response.data && response.data.email.length > 0) {
resolve(
response.data.email.map((item: any) => ({
...item,
content: item.html,
})),
);
clearInterval(itl);
return;
}
if (time > 5) {
resolve([]);
clearInterval(itl);
return;
}
time++;
}, 10000);
});
}
}
class Internal extends BaseEmail {
private apiUrl: string;
private client: AxiosInstance;
constructor(options?: BaseOptions) {
super(options);
this.apiUrl = 'https://api.internal.temp-mail.io/api/v3';
this.client = CreateAxiosProxy({
baseURL: 'https://api.internal.temp-mail.io/api/v3',
});
}
public async getMailAddress(): Promise<string> {
const length = Math.floor(Math.random() * (15 - 8 + 1)) + 8;
const characters =
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
let address = '';
for (let i = 0; i < length; i++) {
address += characters.charAt(
Math.floor(Math.random() * characters.length),
);
}
const data = {
name: address,
domain: 'gixenmixen.com',
};
const response = await this.client.post('/email/new', data);
const result = response.data;
console.log(data);
console.log(result);
return result.email;
}
public async waitMails(): Promise<BaseMailMessage[]> {
const mailAddress = await this.getMailAddress();
let times = 0;
while (true) {
const response = await this.client.get(`/email/${mailAddress}/messages`);
console.log(`正在获取邮件:${times}`);
if (response.status === 200) {
const data = response.data;
if (data.length > 0) {
try {
const mail = data[0];
const content = mail.body_html;
const parser = new DOMParser();
const htmlDoc = parser.parseFromString(content, 'text/html');
const codeDiv = htmlDoc.querySelector(
"div[style='font-family:system-ui, Segoe UI, sans-serif;font-size:19px;font-weight:700;line-height:1.6;text-align:center;color:#333333;']",
);
const code = codeDiv?.textContent || '';
return [{ content: code }];
} catch (error) {
console.log('error');
}
break;
}
}
await new Promise((resolve) => setTimeout(resolve, 200));
times++;
}
return [];
}
}
export class SmailPro extends BaseEmail {
private page!: Page;
private mail: string;
constructor(options: SmailProOptions) {
super(options);
this.mail = options.mail || 'gmail';
}
async getMailAddress() {
try {
if (!this.page) {
this.page = await CreateNewPage('http://smailpro.com/advanced', {
simplify: true,
});
setTimeout(() => {
this.page
?.browser()
.close()
.catch((e) => console.error(e.message));
}, 360 * 1000);
}
const page = this.page;
await sleep(5000);
await page.waitForSelector('.grid > div > div > button:nth-child(2)');
await page.click('.grid > div > div > button:nth-child(2)');
await page.waitForSelector(
'.relative > .absolute > .text-gray-500 > .h-6 > path',
);
await page.click('.relative > .absolute > .text-gray-500 > .h-6 > path');
await sleep(1000);
await page.waitForSelector('#autosuggest__input', { visible: true });
await page.click('#autosuggest__input');
await page.keyboard.type(`random@${this.mail}`);
await page.keyboard.press('Enter');
console.log('generating email');
await sleep(5000);
let times = 0;
while (true) {
times += 1;
await page.waitForSelector('div > h1');
const [email, domain] = await page.evaluate(() =>
// @ts-ignore
document.querySelector('div > h1').textContent.split(' '),
);
if (email === '...') {
if (times > 5) {
throw new Error('get mail failed, max retry times!');
}
await sleep(5 * 1000);
continue;
}
return email + domain;
}
} catch (e) {
console.log('get mail failed, err:', e);
await this.page?.screenshot({
path: `./run/smailpro_${randomStr(10)}.png`,
});
this.page?.browser?.().close();
throw e;
}
}
async waitMails(): Promise<BaseMailMessage[]> {
const page = this.page;
if (!page) {
return [];
}
let times = 0;
while (true) {
try {
await page.waitForSelector(
'.flex-auto > .flex > .inline-flex > .order-last > .h-6',
{ timeout: 5 * 1000 },
);
await page.click(
'.flex-auto > .flex > .inline-flex > .order-last > .h-6',
);
await page.waitForSelector(
'.flex-auto > .flex > .py-2 > .scrollbar > .px-2',
{ timeout: 5 * 1000 },
);
await page.click('.flex-auto > .flex > .py-2 > .scrollbar > .px-2');
await page.waitForSelector('.flex > div > div > .mt-2 > .w-full', {
timeout: 5 * 1000,
});
// 获取 srcdoc 属性
const content = await page.evaluate(() => {
return (
//@ts-ignore
// prettier-ignore
document.querySelector('.flex > div > div > .mt-2 > .w-full')?.contentDocument.documentElement.outerHTML || ''
);
});
if (content) {
await this.page?.browser().close();
return [{ content }];
}
await sleep(10 * 1000);
} catch (e: any) {
if (times >= 6) {
await this.page?.screenshot({
path: `./run/smailpro_${randomStr(10)}.png`,
});
await this.page?.browser().close();
throw new Error('got mails failed');
}
} finally {
times += 1;
}
}
return [];
}
}
export interface GmailOptions extends BaseOptions {
lock: Lock;
}
export interface SmailProOptions extends GmailOptions {
lock: Lock;
mail: string;
}
class Gmail extends BaseEmail {
private readonly client: AxiosInstance;
private address: string = '';
private timestamp?: number = 0;
private lock: Lock;
constructor(options: GmailOptions) {
super(options);
const apikey = process.env.rapid_api_key || '';
this.lock = options.lock;
if (!apikey) {
throw new Error('Need apikey for TempMail');
}
this.client = CreateAxiosProxy(
{
baseURL: 'https://temp-gmail.p.rapidapi.com',
headers: {
'X-RapidAPI-Key': apikey,
'X-RapidAPI-Host': 'temp-gmail.p.rapidapi.com',
},
} as CreateAxiosDefaults,
false,
);
}
public async getMailAddress(): Promise<string> {
await this.lock.lock(60 * 1000);
const response: any = await this.client.get('/get', {
params: {
domain: 'googlemail.com',
username: 'random',
server: 'server-2',
type: 'real',
},
} as AxiosRequestConfig);
this.address = response.data.items.email;
this.timestamp = response.data.items.timestamp;
return this.address;
}
public async check(): Promise<[boolean, string]> {
try {
const checkres = await this.client.get(`/check`, {
params: {
email: this.address,
timestamp: `${this.timestamp}`,
},
});
const mid = checkres.data.items[0]?.mid;
return [checkres.data.msg === 'ok', mid || ''];
} catch (e: any) {
console.log('check email failed, err = ', e.message);
return [false, ''];
}
}
public async waitMails(): Promise<TempMailMessage[]> {
return new Promise((resolve) => {
let time = 0;
const itl = setInterval(async () => {
try {
const [ok, mid] = await this.check();
if (!mid) {
return;
}
const response = await this.client.get(`/read`, {
params: { email: this.address, message_id: mid },
});
if (response.data && response.data.items) {
const item = response.data.items;
resolve([{ ...item, content: item.body }]);
this.lock.unlock();
clearInterval(itl);
return;
}
if (time > 5) {
resolve([]);
this.lock.unlock();
clearInterval(itl);
return;
}
} catch (e: any) {
console.error(e.message);
}
time++;
}, 20 * 1000);
});
}
}
export class EmailNator extends BaseEmail {
page!: Page;
private clear?: NodeJS.Timeout;
private email?: string;
constructor(options?: BaseOptions) {
super(options);
}
async getMailAddress(): Promise<string> {
try {
if (!this.page) {
this.page = await CreateNewPage('https://emailnator.com/');
await this.page.waitForSelector('#custom-switch-domain');
await this.page.click('#custom-switch-domain');
await this.page.waitForSelector(
'.mb-3 > .card-body > .justify-content-md-center > .mx-auto > .btn-lg',
);
await this.page.click(
'.mb-3 > .card-body > .justify-content-md-center > .mx-auto > .btn-lg',
);
this.clear = setTimeout(() => {
this.page.browser().close();
}, 360 * 1000);
}
await this.page.waitForSelector(
'.col-lg-7 > .mb-3 > .card-body > .mb-3 > .form-control-lg',
);
const emailInput = await this.page.$(
'.col-lg-7 > .mb-3 > .card-body > .mb-3 > .form-control-lg',
);
await sleep(5000);
// @ts-ignore
const email = await emailInput.evaluate((el) => el.value);
// await sleep(10 * 60 * 1000);
if (!email) {
throw new Error('get email failed');
}
this.email = email;
await sleep(3000);
await this.page.waitForSelector(
'.col-lg-7 > .mb-3 > .card-body > .text-center > .btn-lg',
);
await this.page.click(
'.col-lg-7 > .mb-3 > .card-body > .text-center > .btn-lg',
);
return email;
} catch (e) {
throw e;
}
}
private async getMails() {
try {
await this.page.waitForSelector(
'.card > .card-body > .mb-3 > .col-md-6 > .float-md-end',
);
setImmediate(() => {
this.page.click(
'.card > .card-body > .mb-3 > .col-md-6 > .float-md-end',
);
});
const res = await this.page.waitForResponse(
(res) =>
res.url() === 'https://www.emailnator.com/message-list' &&
res.headers()['content-type'].indexOf('application/json') > -1,
);
let mails: any[] = (await res.json()).messageData;
mails = mails.filter((v) => v.messageID !== 'ADSVPN');
return mails || [];
} catch (e: any) {
console.log('get mails failed, err = ', e.message);
return [];
}
}
async getMailDetail(mail: string, messageID: string) {
try {
this.page
.goto(`https://www.emailnator.com/inbox/${mail}/${messageID}`)
.catch(console.error);
const res = await this.page.waitForResponse(
(res) => res.url() === 'https://www.emailnator.com/message-list',
);
return await res.text();
} catch (e) {
throw e;
}
}
async waitMails(): Promise<BaseMailMessage[]> {
let tryTimes = 0;
return new Promise(async (resolve, reject) => {
try {
for (let i = 0; i < 3; i++) {
const mails = await this.getMails();
const v = mails.find(
(v) =>
v.time.indexOf('Just Now') > -1 ||
v.time.indexOf('one minute ago') > -1,
);
if (!v) {
if (tryTimes >= 3) {
reject(new Error('get mail failed'));
await this.page.browser().close();
return;
}
await sleep(5000);
continue;
}
const content =
(await this.getMailDetail(this.email || '', v.messageID)) || '';
resolve([{ content } as BaseMailMessage]);
setTimeout(() => this.page.browser().close(), 5000);
return;
}
reject(new Error('get mail failed'));
} catch (e) {
reject(e);
}
});
}
}
export class MailTM extends BaseEmail {
private readonly mailjs: Mailjs;
private password?: string;
private account?: string;
constructor() {
super();
this.mailjs = new Mailjs();
}
async getMailAddress(): Promise<string> {
const account = await this.mailjs.createOneAccount();
this.mailjs.on('ready', () => console.log('Ready To Listen!'));
// @ts-ignore
return account.data.username;
}
async waitMails(): Promise<BaseMailMessage[]> {
for (let i = 0; i < 3; i++) {
const messages = await this.mailjs.getMessages(1);
if (messages.data.length === 0) {
await sleep(3000);
continue;
}
const one = messages.data[0];
const message = await this.mailjs.getMessage(one.id);
return [{ content: message.data.html.join('\n') }];
}
return [];
}
}
export class YopMail extends BaseEmail {
client = CreateAxiosProxy({ baseURL: 'https://yopmail.com/' }, false, true);
private realMail!: string;
private randomMail!: string;
private mailName!: string;
async getMailAddress(): Promise<string> {
this.realMail = await this.getMail();
this.mailName = this.realMail.split('@')[0];
const mailSfx = getRandomOne(await this.getMailSuffix());
this.randomMail = this.realMail.replace('yopmail.com', mailSfx);
return this.randomMail;
}
async waitMails(): Promise<BaseMailMessage[]> {
let msgs: BaseMailMessage[] = [];
for (let i = 0; i <= 3; i++) {
const inbox: { inbox: { id: string; subject: string }[] } =
await this.getInbox(this.realMail);
inbox.inbox = inbox.inbox.filter(
(v) => v.subject.indexOf('Progress report') === -1,
);
if (inbox.inbox.length === 0) {
await sleep(10 * 1000);
continue;
}
for (const v of inbox.inbox) {
const msg: { data: string } = await this.readMessage(
this.mailName,
v.id,
'html',
);
msgs.push({ content: msg.data });
}
return msgs;
}
throw new Error('wait mail failed');
}
async getMailSuffix(): Promise<string[]> {
const res = await this.client.get('/zh/domain?d=list');
const regex = /<option>@(.+?)<\/option>/g;
return [...res.data.matchAll(regex)]
.map((m) => m[1])
.filter((v) => typeof v === 'string')
.filter((v: string) => v.toLowerCase().indexOf('yopmail') === -1);
}
async getMail() {
const response = await this.client.get('/es/email-generator');
const $ = cheerio.load(response.data);
const genEmail = $('#geny').text();
return genEmail.split(';')[1] || genEmail;
}
async getInbox(
mailAddress: string,
search: any = {},
settings: any = {},
): Promise<any> {
const mail = (mailAddress.split('@')[0] || '').toLowerCase() || mailAddress;
const { cookie: cookie, yp: yp } = await this.getCookiesAndYP();
const yj = await this.getYJ(cookie);
return await this.detailInbox(mail, yp, yj, cookie, search, settings);
}
async getCookiesAndYP() {
const response = await this.client.get('/');
const $ = cheerio.load(response.data);
const yp = $('input#yp').val();
const cookie = response.headers['set-cookie']
?.map((x) => x.split(';')[0])
.join('; ');
if (!cookie) {
throw new Error('cookie is null');
}
const location = response.data.match(/lang=\"(.*?)\"/)[1];
return { cookie: cookie, yp: yp };
}
async getYJ(cookie: string) {
const response = await this.client.get('/ver/8.4/webmail.js', {
headers: { Cookie: cookie },
});
const match = response.data.match(/&yj=([^&]+)&v=/s);
return match ? match[1] : null;
}
shouldIncludeEmail(email: any, filteredSearch: string) {
return Object.entries(filteredSearch).every(([key, value]) => {
switch (key) {
case 'id':
return email.id === value;
case 'from':
return email.from === value;
case 'subject':
return email.subject === value;
case 'timestamp':
return email.timestamp === value;
default:
return false;
}
});
}
getDetailInboxFromPage(html: string, filteredSearch: any) {
const $ = cheerio.load(html);
const elements = $('.m');
return elements
.map((index, element) => this.parseEmail(element))
.toArray()
.filter((email) => this.shouldIncludeEmail(email, filteredSearch));
}
async fetchInboxPage(
mail: string,
yp: string,
yj: string,
pageNumber: number,
cookie: string,
) {
return await this.client.get(
`/es/inbox?login=${mail}&p=${pageNumber}&d=&ctrl=&yp=${yp}&yj=${yj}&v=8.4&r_c=&id=`,
{
headers: {
accept:
'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
cookie: `${cookie}; compte=${mail}; ywm=${mail}; _ga=GA1.2.490358059.1683208319; _gid=GA1.2.1148489241.1683208319; __gads=ID=8e03875306c449c6-22790dab88df0074:T=1683208320:RT=1683208320:S=ALNI_MasidzVb7xQcb0qS7Hrb-gTpCYFkQ; __gpi=UID=0000057b04df1c7f:T=1683208320:RT=1696576052:S=ALNI_MYMeBMqh92Qfh-oIx02VDmWeqsdAA; compte=${mail}; ywm=${mail}; ytime=15:7;`,
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'es-ES,es;q=0.9',
connection: 'keep-alive',
host: 'yopmail.com',
referer: 'https://yopmail.com/es/wm',
'sec-ch-ua':
'"Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': 'Windows',
'sec-fetch-dest': 'iframe',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'same-origin',
'upgrade-insecure-requests': '1',
'user-agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
},
},
);
}
async getTotalMails(html: string) {
const match = html.match(/w\.finrmail\((.*?)\)/);
let totalMails = 0;
if (match) {
totalMails = Number(match[1].split(',')[0]);
}
return totalMails;
}
private possibleKeys = ['id', 'from', 'subject', 'timestamp'];
async validateSearch(search: any) {
const result = this.possibleKeys.some(
(key) => Object.keys(search).includes(key) || null,
);
if (!result) {
throw new Error('Invalid search');
}
return Object.keys(search).reduce((acc: any, key) => {
if (this.possibleKeys.includes(key)) {
acc[key] = search[key];
}
return acc;
}, {});
}
parseEmail(element: any) {
const $ = cheerio.load(element);
const id = $(element).attr('id');
const timestamp = $(element).find('.lmh').text();
const from = $(element).find('.lmf').text();
const subject = $(element).find('.lms').text();
return { id: id, from: from, subject: subject, timestamp: timestamp };
}
async detailInbox(
mail: string,
yp: any,
yj: string,
cookie: string,
search = {},
settings: { GET_ALL_MAILS?: boolean } = {},
) {
const pageNumber = 1;
const response = await this.fetchInboxPage(
mail,
yp,
yj,
pageNumber,
cookie,
);
const inboxHtml = response.data;
const totalMails = await this.getTotalMails(inboxHtml);
let filteredSearch = {};
if (search && Object.keys(search).length > 0) {
filteredSearch = await this.validateSearch(search);
}
let currentPage = 1;
let hasNextPage = true;
let mailFromPage: any = {};
const mailsPerPage = 15;
const emails = [];
while (
hasNextPage &&
(settings.GET_ALL_MAILS === true || currentPage === 1)
) {
const currentPageHtml =
currentPage === 1
? inboxHtml
: (await this.fetchInboxPage(mail, yp, yj, currentPage, cookie)).data;
const currentPageEmails = this.getDetailInboxFromPage(
currentPageHtml,
filteredSearch,
);
mailFromPage[`page_${currentPage}`] = currentPageEmails.length;
emails.push(...currentPageEmails);
if (currentPage * mailsPerPage >= totalMails) {
hasNextPage = false;
} else {
currentPage += 1;
}
}
return {
settings: settings,
search: filteredSearch,
totalInbox: totalMails,
totalPages: Math.ceil(totalMails / mailsPerPage),
mailFromPage: mailFromPage,
totalGetMails: emails.length,
inbox: emails,
};
}
async readMessage(
mail: string,
id: string,
format: string,
selector = '',
): Promise<any> {
try {
const { cookie: cookie } = await this.getCookiesAndYP();
const response = await this.client.get(`/es/mail?b=${mail}&id=m${id}`, {
headers: {
accept:
'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
cookie: `${cookie}; compte=${mail}; ywm=${mail}; _ga=GA1.2.490358059.1683208319; _gid=GA1.2.1148489241.1683208319; __gads=ID=8e03875306c449c6-22790dab88df0074:T=1683208320:RT=1683208320:S=ALNI_MasidzVb7xQcb0qS7Hrb-gTpCYFkQ; __gpi=UID=0000057b04df1c7f:T=1683208320:RT=1696576052:S=ALNI_MYMeBMqh92Qfh-oIx02VDmWeqsdAA; compte=${mail}; ywm=${mail}; ytime=15:7;`,
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'es-ES,es;q=0.9',
connection: 'keep-alive',
host: 'yopmail.com',
referer: 'https://yopmail.com/es/wm',
'sec-ch-ua':
'"Chromium";v="112", "Google Chrome";v="112", "Not:A-Brand";v="99"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': 'Windows',
'sec-fetch-dest': 'iframe',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'same-origin',
'upgrade-insecure-requests': '1',
'user-agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36',
},
});
const $ = cheerio.load(response.data);
const submit = $('div.fl\x20>\x20div.ellipsis.nw.b.f18').text();
const fromSelector = $(
'div.fl > div.md.text.zoom.nw.f24 > span.ellipsis.b\n',
);
const dateSelector = $(
'div.fl > div.md.text.zoom.nw.f24 > span.ellipsis:last-child',
);
const from = fromSelector.length
? fromSelector.text()
: $('div.fl > div.md.text.zoom.nw.f18 > span.ellipsis.b').text();
const date = dateSelector.length
? dateSelector.text().replace(from, '')
: $(
'div.fl\x20>\x20div.md.text.zoom.nw.f18\x20>\x20span.ellipsis:last-child',
).text();
let message;
if (selector) {
selector = `${'#mail'} ${selector}`;
message =
format.toLowerCase() === 'html'
? $(selector).html()
: $(selector).text().trim();
} else {
selector = '#mail';
message =
format.toLowerCase() === 'html'
? $(selector).html()
: $(selector).text().trim();
}
return {
id: id,
submit: submit,
from: from,
date: date,
selector: selector,
format: format,
data: message,
};
} catch (e) {
console.error(e);
}
}
}