Send a bilingual campaign in the language of the matched keyword - #24
Send a bilingual campaign in the language of the matched keyword#24emanueletech wants to merge 1 commit into
Conversation
|
@emanueletech is attempting to deploy a commit to the diwenne's projects Team on Vercel. A member of the Team first needs to authorize it. |
Bilingual campaigns had to send both halves to everyone, making every
message twice as long as the reader needed. matchKeywords() already
returned matchedKeyword; it only had to reach the send.
pickLanguage() cuts on the flag that opens each half and is applied
inside the two rendering functions, so one place covers public reply,
opening DM, follow gate and final message.
Which keyword means which language is configuration, not code:
KEYWORD_LANGUAGES maps them (documented in .env.example) and an unmapped
keyword — or an unset variable — leaves the message whole, so nothing
changes for anyone who does not opt in.
Two non-obvious details:
- {link} is written at the bottom, after the last half, so a naive cut
left every other reader without a link: neutral tokens are re-attached
to the half that lost them.
- pressing the follow gate button, the comment is out of the picture and
the language would be lost halfway, so it travels in the payload
(reveal:<id>:it). The suffix is optional: buttons already sent in the
old format stay valid.
Button labels go through pickLabel(), which narrows to a single language
even without a known keyword, because Instagram truncates titles at 20
characters and a bilingual label would arrive cut mid-word.
Ported from ispazio/openreply@484e675, with the iSpazio-specific keyword
map and defaults replaced by configuration.
Co-authored-by: Fabiano Confuorto <37019652+ispazio@users.noreply.github.com>
16fc413 to
3bceadd
Compare
|
Following the i18n discussion in #22, a note on this one — it is a different animal, but the size objection may well apply here too, so let me make it easy to say no or to shrink it. This PR is not a translation layer: nothing in the UI changes, and it is inert unless If the size is what makes it awkward, it splits cleanly in two, and the first half stands on its own:
Happy to open just the first, or to close this if the feature is not a direction you want the project to take. No hard feelings either way — the two merged fixes were the ones that mattered to me, since they were breaking real sends. |
The problem
A campaign aimed at a bilingual audience has to write every message twice — one half per language — and then send both halves to everyone. The reader scrolls past the half they cannot read, in the public reply, the opening DM, the follow gate and the final message alike.
The change
The keyword that matched the comment picks the language.
matchKeywords()already returnedmatchedKeyword; it only had to reach the send.Messages stay written once, with each half opened by its flag:
pickLanguage()cuts on the flags and is applied inside the two rendering functions inlib/tracking/message.ts, so a single place covers public reply, opening DM, follow gate and final message.Which keyword means which language is configuration, not code.
KEYWORD_LANGUAGESmaps them (documented in.env.example):Unset by default, so this changes nothing for anyone who does not opt in: an unmapped keyword — or an "any word" campaign — leaves the language null and the whole message goes out exactly as it does today. Six languages are supported (it, en, es, fr, de, pt), one flag each; a malformed pair in the variable is skipped rather than thrown, so a typo degrades to the current behaviour instead of breaking the worker.
Two non-obvious details
{link}is written at the bottom, after the last half, so a naive cut left every reader but the last one without a link. Neutral tokens are re-attached to the half that lost them.reveal:<id>:it. The suffix is optional and the parser accepts both forms, so buttons already sent stay valid.Button labels go through
pickLabel(), which narrows to a single language even without a known keyword: Instagram truncates button titles at 20 characters, and a bilingual label would arrive cut mid-word.Checks
npm run typecheck,npm run lint,npm test,npm run buildall pass. 12 new tests in__tests__/language.test.ts(154 total, up from 142) cover the malformed map, an absent language, a non-bilingual message, the trailing{link}, a third language and the button labels.Not exercised against the live Meta API — the message rendering and the payload round-trip are covered by unit tests only.
Credit
The idea and the first implementation are Fabiano's, in
ispazio/openreply@484e675. This port replaces the hardcoded keyword map and campaign defaults with configuration so it fits any account, not just his.