Skip to content

Commit

Permalink
feat: support temp-email which not need credit card bind
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangsx committed May 6, 2023
1 parent 875aa64 commit 3d8d32f
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 105 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions model/forefront/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -150,8 +150,8 @@ export class Forefront extends Chat {
}

async createToken(): Promise<ForefrontSessionInfo> {
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 = {
Expand All @@ -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;
}
Expand Down
99 changes: 0 additions & 99 deletions utils/email.ts

This file was deleted.

171 changes: 171 additions & 0 deletions utils/emailFactory.ts
Original file line number Diff line number Diff line change
@@ -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<string>

public abstract waitMails(): Promise<BaseMailMessage[]>
}

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<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++;
}, 1000);
});
}

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 = 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<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 () => {
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);
});
}
}

0 comments on commit 3d8d32f

Please sign in to comment.