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 };
|
||||
|
||||
Reference in New Issue
Block a user