169 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
const config = require('../lib/config');
 | 
						|
const process = require('process');
 | 
						|
const log = require('../lib/log');
 | 
						|
const knex = require('../lib/knex');
 | 
						|
const senders = require('../lib/senders');
 | 
						|
const { CampaignType, CampaignStatus, CampaignSource } = require('../../shared/campaigns');
 | 
						|
const campaigns = require('../models/campaigns');
 | 
						|
const contextHelpers = require('../lib/context-helpers');
 | 
						|
const {fetch} = require('../lib/feedcheck');
 | 
						|
require('../lib/fork');
 | 
						|
 | 
						|
const { tLog } = require('../lib/translate');
 | 
						|
 | 
						|
const feedCheckInterval = 10 * 60 * 1000;
 | 
						|
 | 
						|
const dbCheckInterval = 60 * 1000;
 | 
						|
 | 
						|
let running = false;
 | 
						|
 | 
						|
let periodicTimeout = null;
 | 
						|
 | 
						|
async function run() {
 | 
						|
    if (running) {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    running = true;
 | 
						|
 | 
						|
    try {
 | 
						|
        let rssCampaignIdRow;
 | 
						|
 | 
						|
        while (rssCampaignIdRow = await knex('campaigns')
 | 
						|
            .where('type', CampaignType.RSS)
 | 
						|
            .where('status', CampaignStatus.ACTIVE)
 | 
						|
            .where(qry => qry.whereNull('last_check').orWhere('last_check', '<', new Date(Date.now() - feedCheckInterval)))
 | 
						|
            .select('id')
 | 
						|
            .first()) {
 | 
						|
 | 
						|
            const rssCampaign = await campaigns.getById(contextHelpers.getAdminContext(), rssCampaignIdRow.id, false);
 | 
						|
 | 
						|
            let checkStatus = null;
 | 
						|
 | 
						|
            try {
 | 
						|
                const entries = await fetch(rssCampaign.data.feedUrl);
 | 
						|
 | 
						|
                let added = 0;
 | 
						|
 | 
						|
                for (const entry of entries) {
 | 
						|
                    let entryId = null;
 | 
						|
 | 
						|
                    await knex.transaction(async tx => {
 | 
						|
                        const existingEntry = await tx('rss').where({
 | 
						|
                            parent: rssCampaign.id,
 | 
						|
                            guid: entry.guid
 | 
						|
                        }).first();
 | 
						|
 | 
						|
                        if (!existingEntry) {
 | 
						|
                            const campaignData = {};
 | 
						|
 | 
						|
                            let source = rssCampaign.source;
 | 
						|
                            if (source === CampaignSource.CUSTOM_FROM_TEMPLATE || source === CampaignSource.CUSTOM) {
 | 
						|
                                source = CampaignSource.CUSTOM_FROM_CAMPAIGN;
 | 
						|
                                campaignData.sourceCampaign = rssCampaign.id;
 | 
						|
                            } else {
 | 
						|
                                Object.assign(campaignData, rssCampaign.data);
 | 
						|
                            }
 | 
						|
 | 
						|
                            campaignData.rssEntry = entry;
 | 
						|
 | 
						|
                            const campaign = {
 | 
						|
                                parent: rssCampaign.id,
 | 
						|
                                type: CampaignType.RSS_ENTRY,
 | 
						|
                                source,
 | 
						|
                                name: entry.title || `RSS entry ${entry.guid.substr(0, 67)}`,
 | 
						|
                                lists: rssCampaign.lists,
 | 
						|
                                namespace: rssCampaign.namespace,
 | 
						|
                                send_configuration: rssCampaign.send_configuration,
 | 
						|
 | 
						|
                                from_name_override: rssCampaign.from_name_override,
 | 
						|
                                from_email_override: rssCampaign.from_email_override,
 | 
						|
                                reply_to_override: rssCampaign.reply_to_override,
 | 
						|
                                subject: rssCampaign.subject,
 | 
						|
                                data: campaignData,
 | 
						|
 | 
						|
                                click_tracking_disabled: rssCampaign.click_tracking_disabled,
 | 
						|
                                open_tracking_disabled: rssCampaign.open_tracking_disabled,
 | 
						|
                                unsubscribe_url: rssCampaign.unsubscribe_url
 | 
						|
                            };
 | 
						|
 | 
						|
                            const ids = await campaigns.createRssTx(tx, contextHelpers.getAdminContext(), campaign);
 | 
						|
                            const campaignId = ids[0];
 | 
						|
 | 
						|
                            await tx('rss').insert({
 | 
						|
                                parent: rssCampaign.id,
 | 
						|
                                campaign: campaignId,
 | 
						|
                                guid: entry.guid,
 | 
						|
                                pubdate: entry.date ? new Date(entry.date) : null,
 | 
						|
                            });
 | 
						|
 | 
						|
                            added += 1;
 | 
						|
                        }
 | 
						|
                    });
 | 
						|
                }
 | 
						|
 | 
						|
                if (added > 0) {
 | 
						|
                    checkStatus = tLog('foundAddedMessagesNewCampaignMessages', {
 | 
						|
                        addedMessages: added,
 | 
						|
                        campaignId: rssCampaign.id
 | 
						|
                    });
 | 
						|
                    log.verbose('Feed', `Found ${added} new campaigns messages from feed ${rssCampaign.id}`);
 | 
						|
 | 
						|
                    process.send({
 | 
						|
                        type: 'entries-added'
 | 
						|
                    });
 | 
						|
                } else {
 | 
						|
                    checkStatus = tLog('foundNothingNewFromTheFeed');
 | 
						|
                }
 | 
						|
 | 
						|
                rssCampaign.data.checkStatus = checkStatus;
 | 
						|
                await knex('campaigns').where('id', rssCampaign.id).update({
 | 
						|
                    last_check: new Date(),
 | 
						|
                    data: JSON.stringify(rssCampaign.data)
 | 
						|
                });
 | 
						|
 | 
						|
            } catch (err) {
 | 
						|
                log.error('Feed', err.message);
 | 
						|
                log.verbose(err.stack);
 | 
						|
                rssCampaign.data.checkStatus = err.message;
 | 
						|
                await knex('campaigns').where('id', rssCampaign.id).update({
 | 
						|
                    last_check: new Date(),
 | 
						|
                    data: JSON.stringify(rssCampaign.data)
 | 
						|
                });
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
    } catch (err) {
 | 
						|
        log.error('Feed', `Feedcheck failed with error: ${err.message}`);
 | 
						|
        log.verbose(err.stack);
 | 
						|
    }
 | 
						|
 | 
						|
    running = false;
 | 
						|
 | 
						|
    periodicTimeout = setTimeout(run, dbCheckInterval);
 | 
						|
}
 | 
						|
 | 
						|
process.on('message', msg => {
 | 
						|
    if (msg) {
 | 
						|
        const type = msg.type;
 | 
						|
 | 
						|
        if (type === 'scheduleCheck') {
 | 
						|
            if (periodicTimeout) {
 | 
						|
                clearTimeout(periodicTimeout);
 | 
						|
                setImmediate(run);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
});
 | 
						|
 | 
						|
if (config.title) {
 | 
						|
    process.title = config.title + ': feedcheck';
 | 
						|
}
 | 
						|
 | 
						|
process.send({
 | 
						|
    type: 'feedcheck-started'
 | 
						|
});
 | 
						|
 | 
						|
run();
 |