Added an API endpoint that triggers an RSS campaign.
This commit is contained in:
parent
e786964411
commit
428fb9db7b
8 changed files with 88 additions and 7 deletions
|
@ -348,6 +348,26 @@ export default class API extends Component {
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<pre>curl -XGET '{getUrl(`api/lists/test@example.com?access_token=${accessToken}`)}'</pre>
|
<pre>curl -XGET '{getUrl(`api/lists/test@example.com?access_token=${accessToken}`)}'</pre>
|
||||||
|
|
||||||
|
|
||||||
|
<h4>GET /api/rss/fetch/:campaignCid – {t('Trigger fetch of a campaign')}</h4>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{t('Forces the RSS feed check to immediately check the campaign with the given CID (in :campaignCid). It works only for RSS campaigns.')}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>GET</strong> {t('arguments')}
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>access_token</strong> – {t('yourPersonalAccessToken')}</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>{t('example')}</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>curl -XGET '{getUrl(`api/rss/fetch/5OOnZKrp0?access_token=${accessToken}`)}'</pre>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,6 +230,10 @@ roles:
|
||||||
description: All permissions
|
description: All permissions
|
||||||
permissions: [rebuildPermissions, createJavascriptWithROAccess, manageBlacklist, manageSettings, setupAutomation]
|
permissions: [rebuildPermissions, createJavascriptWithROAccess, manageBlacklist, manageSettings, setupAutomation]
|
||||||
rootNamespaceRole: master
|
rootNamespaceRole: master
|
||||||
|
nobody:
|
||||||
|
name: None
|
||||||
|
description: No permissions
|
||||||
|
permissions: []
|
||||||
|
|
||||||
namespace:
|
namespace:
|
||||||
master:
|
master:
|
||||||
|
@ -240,7 +244,7 @@ roles:
|
||||||
sendConfiguration: [viewPublic, viewPrivate, edit, delete, share, sendWithoutOverrides, sendWithAllowedOverrides, sendWithAnyOverrides]
|
sendConfiguration: [viewPublic, viewPrivate, edit, delete, share, sendWithoutOverrides, sendWithAllowedOverrides, sendWithAnyOverrides]
|
||||||
list: [view, edit, delete, share, viewFields, manageFields, viewSubscriptions, manageSubscriptions, viewSegments, manageSegments, viewImports, manageImports]
|
list: [view, edit, delete, share, viewFields, manageFields, viewSubscriptions, manageSubscriptions, viewSegments, manageSegments, viewImports, manageImports]
|
||||||
customForm: [view, edit, delete, share]
|
customForm: [view, edit, delete, share]
|
||||||
campaign: [view, edit, delete, share, viewFiles, manageFiles, viewAttachments, manageAttachments, viewTriggers, manageTriggers, send, viewStats]
|
campaign: [view, edit, delete, share, viewFiles, manageFiles, viewAttachments, manageAttachments, viewTriggers, manageTriggers, send, viewStats, fetchRss]
|
||||||
template: [view, edit, delete, share, viewFiles, manageFiles]
|
template: [view, edit, delete, share, viewFiles, manageFiles]
|
||||||
report: [view, edit, delete, share, execute, viewContent, viewOutput]
|
report: [view, edit, delete, share, execute, viewContent, viewOutput]
|
||||||
reportTemplate: [view, edit, delete, share, execute]
|
reportTemplate: [view, edit, delete, share, execute]
|
||||||
|
@ -269,7 +273,11 @@ roles:
|
||||||
master:
|
master:
|
||||||
name: Master
|
name: Master
|
||||||
description: All permissions
|
description: All permissions
|
||||||
permissions: [view, edit, delete, share, viewFiles, manageFiles, viewAttachments, manageAttachments, viewTriggers, manageTriggers, send, viewStats, manageMessages]
|
permissions: [view, edit, delete, share, viewFiles, manageFiles, viewAttachments, manageAttachments, viewTriggers, manageTriggers, send, viewStats, manageMessages, fetchRss]
|
||||||
|
rssTrigger:
|
||||||
|
name: RSS Campaign Trigger
|
||||||
|
description: Allows triggering a fetch of an RSS campaign
|
||||||
|
permissions: [fetchRss]
|
||||||
|
|
||||||
template:
|
template:
|
||||||
master:
|
master:
|
||||||
|
|
|
@ -312,7 +312,6 @@ class CampaignSender {
|
||||||
const sendConfiguration = this.sendConfiguration;
|
const sendConfiguration = this.sendConfiguration;
|
||||||
|
|
||||||
const {html, text, attachments} = await this._getMessage(campaign, list, subscriptionGrouped, mergeTags, true);
|
const {html, text, attachments} = await this._getMessage(campaign, list, subscriptionGrouped, mergeTags, true);
|
||||||
console.log(html);
|
|
||||||
|
|
||||||
const campaignAddress = [campaign.cid, list.cid, subscriptionGrouped.cid].join('.');
|
const campaignAddress = [campaign.cid, list.cid, subscriptionGrouped.cid].join('.');
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,12 @@ const log = require('./log');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const senders = require('./senders');
|
const senders = require('./senders');
|
||||||
|
|
||||||
|
let messageTid = 0;
|
||||||
let feedcheckProcess;
|
let feedcheckProcess;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
spawn
|
spawn,
|
||||||
|
scheduleCheck
|
||||||
};
|
};
|
||||||
|
|
||||||
function spawn(callback) {
|
function spawn(callback) {
|
||||||
|
@ -34,3 +36,13 @@ function spawn(callback) {
|
||||||
log.error('Feed', 'Feedcheck process exited with code %s signal %s', code, signal);
|
log.error('Feed', 'Feedcheck process exited with code %s signal %s', code, signal);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function scheduleCheck() {
|
||||||
|
feedcheckProcess.send({
|
||||||
|
type: 'scheduleCheck',
|
||||||
|
tid: messageTid
|
||||||
|
});
|
||||||
|
|
||||||
|
messageTid++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,15 +86,18 @@ module.exports.loggedIn = (req, res, next) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.authByAccessToken = (req, res, next) => {
|
module.exports.authByAccessToken = (req, res, next) => {
|
||||||
if (!req.query.access_token) {
|
const accessToken = req.get('access-token') || req.query.access_token
|
||||||
|
|
||||||
|
if (!accessToken) {
|
||||||
res.status(403);
|
res.status(403);
|
||||||
res.json({
|
res.json({
|
||||||
error: 'Missing access_token',
|
error: 'Missing access_token',
|
||||||
data: []
|
data: []
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
users.getByAccessToken(req.query.access_token).then(user => {
|
users.getByAccessToken(accessToken).then(user => {
|
||||||
req.user = user;
|
req.user = user;
|
||||||
next();
|
next();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
|
|
|
@ -18,6 +18,7 @@ const subscriptions = require('./subscriptions');
|
||||||
const segments = require('./segments');
|
const segments = require('./segments');
|
||||||
const senders = require('../lib/senders');
|
const senders = require('../lib/senders');
|
||||||
const {LinkId} = require('./links');
|
const {LinkId} = require('./links');
|
||||||
|
const feedcheck = require('../lib/feedcheck');
|
||||||
|
|
||||||
const allowedKeysCommon = ['name', 'description', 'segment', 'namespace',
|
const allowedKeysCommon = ['name', 'description', 'segment', 'namespace',
|
||||||
'send_configuration', 'from_name_override', 'from_email_override', 'reply_to_override', 'subject_override', 'data', 'click_tracking_disabled', 'open_tracking_disabled', 'unsubscribe_url'];
|
'send_configuration', 'from_name_override', 'from_email_override', 'reply_to_override', 'subject_override', 'data', 'click_tracking_disabled', 'open_tracking_disabled', 'unsubscribe_url'];
|
||||||
|
@ -921,6 +922,21 @@ async function getStatisticsOpened(context, id) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchRssCampaign(context, cid) {
|
||||||
|
return await knex.transaction(async tx => {
|
||||||
|
|
||||||
|
const campaign = await tx('campaigns').where('cid', cid).select(['id', 'type']).first();
|
||||||
|
|
||||||
|
await shares.enforceEntityPermissionTx(tx, context, 'campaign', campaign.id, 'fetchRss');
|
||||||
|
|
||||||
|
enforce(campaign.type === CampaignType.RSS, 'Invalid campaign type');
|
||||||
|
|
||||||
|
await tx('campaigns').where('id', campaign.id).update('last_check', null);
|
||||||
|
|
||||||
|
feedcheck.scheduleCheck();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.exports.Content = Content;
|
module.exports.Content = Content;
|
||||||
module.exports.hash = hash;
|
module.exports.hash = hash;
|
||||||
|
|
||||||
|
@ -961,3 +977,5 @@ module.exports.disable = disable;
|
||||||
module.exports.rawGetByTx = rawGetByTx;
|
module.exports.rawGetByTx = rawGetByTx;
|
||||||
module.exports.getTrackingSettingsByCidTx = getTrackingSettingsByCidTx;
|
module.exports.getTrackingSettingsByCidTx = getTrackingSettingsByCidTx;
|
||||||
module.exports.getStatisticsOpened = getStatisticsOpened;
|
module.exports.getStatisticsOpened = getStatisticsOpened;
|
||||||
|
|
||||||
|
module.exports.fetchRssCampaign = fetchRssCampaign;
|
|
@ -16,6 +16,7 @@ const contextHelpers = require('../lib/context-helpers');
|
||||||
const shares = require('../models/shares');
|
const shares = require('../models/shares');
|
||||||
const slugify = require('slugify');
|
const slugify = require('slugify');
|
||||||
const passport = require('../lib/passport');
|
const passport = require('../lib/passport');
|
||||||
|
const campaigns = require('../models/campaigns');
|
||||||
|
|
||||||
class APIError extends Error {
|
class APIError extends Error {
|
||||||
constructor(msg, status) {
|
constructor(msg, status) {
|
||||||
|
@ -279,5 +280,10 @@ router.getAsync('/blacklist/get', passport.loggedIn, async (req, res) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.getAsync('/rss/fetch/:campaignCid', passport.loggedIn, async (req, res) => {
|
||||||
|
await campaigns.fetchRssCampaign(req.context, req.params.campaignCid);
|
||||||
|
return res.json();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
|
@ -17,6 +17,8 @@ const dbCheckInterval = 60 * 1000;
|
||||||
|
|
||||||
let running = false;
|
let running = false;
|
||||||
|
|
||||||
|
let periodicTimeout = null;
|
||||||
|
|
||||||
async function fetch(url) {
|
async function fetch(url) {
|
||||||
const httpOptions = {
|
const httpOptions = {
|
||||||
uri: url,
|
uri: url,
|
||||||
|
@ -161,9 +163,22 @@ async function run() {
|
||||||
|
|
||||||
running = false;
|
running = false;
|
||||||
|
|
||||||
setTimeout(run, dbCheckInterval);
|
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) {
|
if (config.title) {
|
||||||
process.title = config.title + ': feedcheck';
|
process.title = config.title + ': feedcheck';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue