Give a syndicated offer a title a stranger can read
A campaign's name is the member's own internal label, and some of them are
two characters ("MG"). DripOffers rejects anything under five, and more to
the point a click-earner scanning the offerwall learns nothing from "MG".
So the ad's own headline comes first, then the label, and a very short
label is qualified with the destination host — "MG (mailer.gold)" — rather
than dropped or dressed up in marketing copy we invented on the member's
behalf. Nothing usable at all returns null instead of a made-up title.
Found by the backfill: campaign 88 failed on it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+20
-2
@@ -108,6 +108,23 @@ function countriesFor(geo, tiers) {
|
||||
return [...new Set(out.map(c => String(c).toUpperCase()))].join(',');
|
||||
}
|
||||
|
||||
// What a click-earner sees in the offerwall list. A campaign's `name` is the member's own
|
||||
// internal label and is often too short to mean anything to a stranger ("MG"), so the ad's
|
||||
// headline comes first, then the label, and a very short label is qualified with the
|
||||
// destination host rather than dropped or dressed up in copy we invented for them. The
|
||||
// platform's own floor is five characters.
|
||||
function titleFor(campaign, url) {
|
||||
const clean = v => String(v || '').replace(/\s+/g, ' ').trim();
|
||||
const head = clean(campaign.title), label = clean(campaign.name);
|
||||
let host = '';
|
||||
try { host = new URL(url).hostname.replace(/^www\./, ''); } catch (e) {}
|
||||
const pick = head.length >= 5 ? head
|
||||
: label.length >= 5 ? label
|
||||
: label && host ? label + ' (' + host + ')'
|
||||
: host;
|
||||
return pick.length >= 5 ? pick.slice(0, 250) : null;
|
||||
}
|
||||
|
||||
// Push a campaign. Returns null when it is not worth syndicating (or cannot be targeted
|
||||
// faithfully) rather than throwing, so the caller treats "too small", "wrong format" and
|
||||
// "disabled" the same quiet way.
|
||||
@@ -125,7 +142,8 @@ async function push(campaign, opts) {
|
||||
const countries = countriesFor(campaign.geo, (opts && opts.tiers) || null);
|
||||
if (countries === null) return null;
|
||||
|
||||
const title = String(campaign.name || campaign.title || 'InstantAdPay').slice(0, 250);
|
||||
const title = titleFor(campaign, url);
|
||||
if (!title) return null;
|
||||
// The offerwall shows this line under the title, so it has to read like an offer rather
|
||||
// than like an internal campaign record.
|
||||
const description = String(campaign.title || campaign.body || campaign.name || title).slice(0, 250);
|
||||
@@ -156,6 +174,6 @@ async function remove(campaignId) {
|
||||
}
|
||||
async function packs() { return enabled() ? call('packs', {}) : null; }
|
||||
|
||||
module.exports = { enabled, push, readServed, pause, resume, remove, packs,
|
||||
module.exports = { enabled, push, readServed, pause, resume, remove, packs, titleFor,
|
||||
clicksFor, countriesFor, kindOk, refFor,
|
||||
MIN_CREDITS, MAX_CLICKS, MIN_CLICKS, PACK_ID, KINDS };
|
||||
|
||||
@@ -24,6 +24,14 @@ t('tier 3 alone is skipped, not silently widened', drip.countriesFor('3', tiers)
|
||||
|
||||
t('credits convert to clicks one for one', drip.clicksFor(4000) === 4000, String(drip.clicksFor(4000)));
|
||||
t('one campaign cannot swallow the platform', drip.clicksFor(500000) === drip.MAX_CLICKS, String(drip.clicksFor(500000)));
|
||||
// the offerwall title a stranger actually reads (the platform's floor is 5 characters)
|
||||
const T = (c, u) => drip.titleFor(c, u || 'https://www.mailer.gold/x');
|
||||
t('the ad headline wins over the internal label', T({ title: 'Get paid instantly', name: 'MG' }) === 'Get paid instantly', String(T({ title: 'Get paid instantly', name: 'MG' })));
|
||||
t('a usable label is used as-is', T({ name: 'Branded Voice' }) === 'Branded Voice', String(T({ name: 'Branded Voice' })));
|
||||
t('a two-letter label is qualified, not dropped', T({ name: 'MG' }) === 'MG (mailer.gold)', String(T({ name: 'MG' })));
|
||||
t('no label at all falls back to the destination', T({}) === 'mailer.gold', String(T({})));
|
||||
t('nothing usable returns null rather than a made-up title', T({}, 'not a url') === null, String(T({}, 'not a url')));
|
||||
|
||||
t('a click format is accepted', drip.kindOk('banner') && drip.kindOk('visits') && drip.kindOk('text'));
|
||||
t('video and solo are not click formats', !drip.kindOk('video') && !drip.kindOk('solo') && !drip.kindOk('featured'));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user