From 3d8d32fc647e834542cedac0c3a3adec173d0bda Mon Sep 17 00:00:00 2001 From: xiang <1984871009@qq.com> Date: Sat, 6 May 2023 23:34:15 +0800 Subject: [PATCH] feat: support temp-email which not need credit card bind --- README.md | 2 +- model/forefront/index.ts | 10 +-- utils/email.ts | 99 ----------------------- utils/emailFactory.ts | 171 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 177 insertions(+), 105 deletions(-) delete mode 100644 utils/email.ts create mode 100644 utils/emailFactory.ts diff --git a/README.md b/README.md index ab02007..f1bd17a 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ first, you should create file .env ```env http_proxy=http://host:port # you should config this if you use forefront api, this apikey is used for receive register email -# get api key here https://rapidapi.com/Privatix/api/temp-mail +# get api key here https://rapidapi.com/calvinloveland335703-0p6BxLYIH8f/api/temp-mail44 rapid_api_key=xxxxxxxxxx ``` deploy diff --git a/model/forefront/index.ts b/model/forefront/index.ts index ca47e57..c3ec144 100644 --- a/model/forefront/index.ts +++ b/model/forefront/index.ts @@ -3,7 +3,7 @@ import UserAgent from 'user-agents'; import tlsClient from 'tls-client'; import {Chat, ChatOptions, Request, Response, ResponseStream} from "../base"; -import {Email} from '../../utils/email'; +import {CreateEmail, TempEmailType, TempMailMessage} from '../../utils/emailFactory'; import axios, {AxiosInstance, AxiosRequestConfig, CreateAxiosDefaults} from "axios"; import {v4} from "uuid"; import es from "event-stream"; @@ -150,8 +150,8 @@ export class Forefront extends Chat { } async createToken(): Promise { - const mailbox = new Email(); - const mailAddress = await mailbox.create(); + const mailbox = CreateEmail(TempEmailType.TempEmail44); + const mailAddress = await mailbox.getMailAddress(); const agent = new UserAgent().toString(); const session = new tlsClient.Session({clientIdentifier: 'chrome_108'}); session.headers = { @@ -177,10 +177,10 @@ export class Forefront extends Chat { if (verifyRes.text.indexOf('sign_up_attempt') === -1) { throw new Error('forefront create account failed'); } - const msgs = await mailbox.getMessage() + const msgs = (await mailbox.waitMails()) as TempMailMessage[] let validateURL: string | undefined; for (const msg of msgs) { - validateURL = msg.mail_html.match(/https:\/\/clerk\.forefront\.ai\/v1\/verify\?token=[^\s"]+/i)?.[0]; + validateURL = msg.content.match(/https:\/\/clerk\.forefront\.ai\/v1\/verify\?token=[^\s"]+/i)?.[0]; if (validateURL) { break; } diff --git a/utils/email.ts b/utils/email.ts deleted file mode 100644 index 83b9295..0000000 --- a/utils/email.ts +++ /dev/null @@ -1,99 +0,0 @@ -import axios, {AxiosInstance, CreateAxiosDefaults} from 'axios'; -import {md5, randomStr} from "./index"; - -export class Email { - private mail: TempMail; - private address: string | undefined; - private domainList: string[]; - private mailID: string; - - constructor() { - this.mail = new TempMail(process.env.rapid_api_key || ""); - this.address = undefined; - this.mailID = ''; - this.domainList = []; - } - - async create(): Promise { - this.domainList = await this.mail.getDomainsList(); - this.address = `${randomStr()}${this.randomDomain()}`; - this.mailID = md5(this.address); - return this.address; - } - - randomDomain(): string { - return this.domainList[Math.floor(Math.random() * this.domainList.length)]; - } - - emailAddress() { - if (!this.address) { - throw new Error('create first'); - } - return this.address; - } - - async getMessage() { - return this.mail.getEmail(this.mailID); - } -} - -interface TempMailMessage { - _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[]; - }; -} - -class TempMail { - private readonly client: AxiosInstance; - - constructor(apikey: string) { - this.client = axios.create({ - 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); - } - - async getEmail(md5Str: string): Promise { - return new Promise(resolve => { - let time = 0; - const itl = setInterval(async () => { - const response = await this.client.get(`/mail/id/${md5Str}`); - if (response.data && response.data.length > 0) { - resolve(response.data); - clearInterval(itl); - return; - } - if (time > 5) { - resolve([]); - clearInterval(itl); - return; - } - time++; - }, 1000); - }); - } - - async getDomainsList(): Promise { - const res = await this.client.get(`/domains/`); - return res.data; - } -} diff --git a/utils/emailFactory.ts b/utils/emailFactory.ts new file mode 100644 index 0000000..5e73828 --- /dev/null +++ b/utils/emailFactory.ts @@ -0,0 +1,171 @@ +import axios, {AxiosInstance, AxiosRequestConfig, CreateAxiosDefaults} from 'axios'; +import {md5, randomStr} from "./index"; + +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', +} + +export function CreateEmail(tempMailType: TempEmailType, options?: BaseOptions): BaseEmail { + switch (tempMailType) { + case TempEmailType.TempEmail44: + return new TempMail44(options); + case TempEmailType.TempEmail: + return new TempMail(options); + 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 { + protected constructor(options?: BaseOptions) { + } + + public abstract getMailAddress(): Promise + + public abstract waitMails(): Promise +} + +export interface TempMailOptions extends BaseOptions { + apikey?: string; +} + +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 = axios.create({ + 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 { + this.address = `${randomStr()}${await this.randomDomain()}`; + this.mailID = md5(this.address); + return this.address; + } + + public async waitMails(): Promise { + 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++; + }, 1000); + }); + } + + async getDomainsList(): Promise { + const res = await this.client.get(`/domains/`); + return res.data; + } + + async randomDomain(): Promise { + 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 = axios.create({ + 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); + } + + public async getMailAddress(): Promise { + 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 { + return new Promise(resolve => { + let time = 0; + const itl = setInterval(async () => { + 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++; + }, 1000); + }); + } +}