Campaign preview and campaign test send pulls the first entry in the RSS feed and substitutes its data in `[RSS_ENTRY_*]`
157 lines
5.2 KiB
JavaScript
157 lines
5.2 KiB
JavaScript
'use strict';
|
|
|
|
const config = require('../lib/config');
|
|
const log = require('../lib/log');
|
|
const knex = require('../lib/knex');
|
|
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;
|
|
|
|
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,
|
|
});
|
|
|
|
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);
|
|
rssCampaign.data.checkStatus = err.message;
|
|
await knex('campaigns').where('id', rssCampaign.id).update({
|
|
last_check: new Date(),
|
|
data: JSON.stringify(rssCampaign.data)
|
|
});
|
|
}
|
|
}
|
|
|
|
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();
|