All files / src Service.ts

0% Statements 0/50
0% Branches 0/13
0% Functions 0/17
0% Lines 0/45
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106                                                                                                                                                                                                                   
import * as schedule from 'node-schedule';
import {logger} from './logger';
import * as models from './models';
import {Patreon} from './Patreon';

/**
 * Patreon service
 */
export class Service {
	public job: schedule.Job;
	public patreon: Patreon;

	constructor() {
		this.patreon = new Patreon();
	}
 
	public start(): void {
		this.job = schedule.scheduleJob('*/5 * * * *', this.processPledges.bind(this));
	}

	private async processPledges() {
		let pledges: PatronPledge[];
		let existingPatrons: models.PatronDocument[];
 
		logger.info(`[${new Date()}] Pledge processing started.`);

		try {
			pledges = await this.patreon.getPledges();
		} catch (err) {
			logger.error(err);
			return;
		}

		try {
			existingPatrons = await (await models.patrons.find({ deleted: false })).fetchAll();
		} catch (err) {
			logger.error(err);
			return;
		}

		await this.addNewPatrons(pledges).catch((err: string) => logger.error(err));
		this.updateDeletedPatrons(pledges, existingPatrons).catch((err: string) => logger.error(err));
		this.updateRenewedPatrons(pledges, existingPatrons).catch((err: string) => logger.error(err));
	}
 
	private async addNewPatrons(pledges: PatronPledge[]): Promise<void> {
		let upsertCount = 0;
 
		for (const pledge of pledges) {
			await models.patrons.updateOne({ id: pledge.id }, { $set: pledge }, { upsert: true })
				.then(() => {
					upsertCount = upsertCount + 1;
				})
				.catch((err: Error) => {
					throw err;
				});
		}
	}

	private async updateRenewedPatrons(pledges: PatronPledge[], existingPatrons: models.PatronDocument[]): Promise<void> {
		let renewedCount = 0;

		for (const patron of existingPatrons) {
			const foundPatron = pledges.find((p: PatronPledge) => p.id === patron.id);
 
			if (foundPatron != undefined && foundPatron.pledge.declined_since == undefined && patron.pledge.declined_since != undefined) {
				await models.patrons.updateOne({ id: patron.id }, { $set: { deleted: false, 'pledge.declined_since': patron.pledge.declined_since } })
					.then(() => {
						renewedCount = renewedCount + 1;
						logger.debug(`Deleted ${patron.id}`);
					})
					.catch((err: Error) => {
						throw err;
					});
			}
		}

		if (renewedCount > 0) {
			logger.info(`Renewed ${renewedCount} patrons.`);
		}
	}
 
	private async updateDeletedPatrons(pledges: PatronPledge[], existingPatrons: models.PatronDocument[]): Promise<void> {
		let deletedCount = 0;

		for (const patron of existingPatrons) {
			const foundPatron = pledges.find((p: PatronPledge) => p.id === patron.id);
 
			if (foundPatron == undefined || foundPatron.pledge.declined_since != undefined) {
				await models.patrons.updateOne({ id: patron.id }, { $set: { deleted: true, 'pledge.declined_since': patron.pledge.declined_since } })
					.then(() => {
						deletedCount = deletedCount + 1;
						logger.debug(`Deleted ${patron.id}`);
					})
					.catch((err: Error) => {
						throw err;
					});
			}
		}
 
		if (deletedCount > 0) {
			logger.info(`Deleted ${deletedCount} patrons.`);
		}
	}
}