feat: support temp-email which not need credit card bind

このコミットが含まれているのは:
xiang 2023-05-06 23:34:15 +08:00
コミット 3d8d32fc64
4個のファイルの変更177行の追加105行の削除

ファイルの表示

@ -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

ファイルの表示

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

ファイルの表示

@ -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<any> {
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<TempMailMessage[]> {
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<string[]> {
const res = await this.client.get(`/domains/`);
return res.data;
}
}

171
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<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);
});
}
}