spamhole
Version:
Like a blackhole, but for spam
95 lines • 3.58 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const events_1 = require("events");
const timers_1 = require("timers");
const mailparser_1 = require("mailparser");
const bottleneck_1 = require("bottleneck");
const Maildrop = require("maildrop-api");
const RandomString = require("randomstring");
// Constants
const DOMAIN = process.env.MAILDROP_URL || 'maildrop.cc';
const THROTTLE_INTERVAL = 1000; // Allow one request every 1s
const POLL_INTERVAL = 2000; // Poll inbox every 2s
/**
* Represents an ephemeral mailbox
*/
class Mailbox extends events_1.EventEmitter {
/**
* Creates a new ephemeral mailbox; either from a known ID or an auto-generated suggestion.
*
* @param id ID of the mailbox, if known
*/
static create(id) {
return new Mailbox(id || RandomString.generate(12));
}
constructor(id) {
super();
this.id = id;
this.knownEmails = new Set();
this.limiter = new bottleneck_1.default(1, THROTTLE_INTERVAL);
this.timer = timers_1.setInterval(() => this.update().catch(console.error), POLL_INTERVAL);
}
/**
* Returns the email address of this mailbox
*/
get address() {
return `${this.id}@${DOMAIN}`;
}
/**
* Returns an array of emails that have not been previously returned
*/
getNewMail() {
return __awaiter(this, void 0, void 0, function* () {
const mails = yield this.limiter.schedule(() => Maildrop.getInbox(this.id));
const newMails = mails
.filter(mail => !this.knownEmails.has(mail.id))
.map(createMailInfo);
mails.forEach(i => this.knownEmails.add(i.id));
return newMails;
});
}
/**
* Fetches new emails and emits 'newMail' events for each new email
*/
update() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.limiter.check()) {
return; // We are not ready to make more calls yet, skip this update cycle to avoid filling the queue
}
for (let mail of yield this.getNewMail()) {
this.emit('newMail', mail);
}
});
}
/**
* Fetches and parses an email in the inbox
* @param id ID of the email to fetch
*/
getEmail(id) {
return __awaiter(this, void 0, void 0, function* () {
const rawMail = yield this.limiter.schedule(() => Maildrop.getEmail(this.id, id));
if (typeof rawMail === 'string') {
throw new Error(`Failed to retreive email: ${this.id}/${id}`);
}
return mailparser_1.simpleParser(rawMail.body);
});
}
}
exports.Mailbox = Mailbox;
function createMailInfo(mail) {
return {
id: mail.id,
sender: mail.sender,
subject: mail.subject,
timestamp: new Date(Date.parse(mail.date))
};
}
//# sourceMappingURL=mailbox.js.map
;