feat: support temp-email which not need credit card bind
このコミットが含まれているのは:
コミット
3d8d32fc64
|
@ -29,7 +29,7 @@ first, you should create file .env
|
||||||
```env
|
```env
|
||||||
http_proxy=http://host:port
|
http_proxy=http://host:port
|
||||||
# you should config this if you use forefront api, this apikey is used for receive register email
|
# 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
|
rapid_api_key=xxxxxxxxxx
|
||||||
```
|
```
|
||||||
deploy
|
deploy
|
||||||
|
|
|
@ -3,7 +3,7 @@ import UserAgent from 'user-agents';
|
||||||
import tlsClient from 'tls-client';
|
import tlsClient from 'tls-client';
|
||||||
|
|
||||||
import {Chat, ChatOptions, Request, Response, ResponseStream} from "../base";
|
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 axios, {AxiosInstance, AxiosRequestConfig, CreateAxiosDefaults} from "axios";
|
||||||
import {v4} from "uuid";
|
import {v4} from "uuid";
|
||||||
import es from "event-stream";
|
import es from "event-stream";
|
||||||
|
@ -150,8 +150,8 @@ export class Forefront extends Chat {
|
||||||
}
|
}
|
||||||
|
|
||||||
async createToken(): Promise<ForefrontSessionInfo> {
|
async createToken(): Promise<ForefrontSessionInfo> {
|
||||||
const mailbox = new Email();
|
const mailbox = CreateEmail(TempEmailType.TempEmail44);
|
||||||
const mailAddress = await mailbox.create();
|
const mailAddress = await mailbox.getMailAddress();
|
||||||
const agent = new UserAgent().toString();
|
const agent = new UserAgent().toString();
|
||||||
const session = new tlsClient.Session({clientIdentifier: 'chrome_108'});
|
const session = new tlsClient.Session({clientIdentifier: 'chrome_108'});
|
||||||
session.headers = {
|
session.headers = {
|
||||||
|
@ -177,10 +177,10 @@ export class Forefront extends Chat {
|
||||||
if (verifyRes.text.indexOf('sign_up_attempt') === -1) {
|
if (verifyRes.text.indexOf('sign_up_attempt') === -1) {
|
||||||
throw new Error('forefront create account failed');
|
throw new Error('forefront create account failed');
|
||||||
}
|
}
|
||||||
const msgs = await mailbox.getMessage()
|
const msgs = (await mailbox.waitMails()) as TempMailMessage[]
|
||||||
let validateURL: string | undefined;
|
let validateURL: string | undefined;
|
||||||
for (const msg of msgs) {
|
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) {
|
if (validateURL) {
|
||||||
break;
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
読み込み中…
新しいイシューから参照