Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | 2x 2x 544x 690x 433x | import type { RrmLocale } from "../api/admin/rrm";
/**
* The ten answers an operator gives over and over in the partner inbox (F-21).
*
* These are the questions a cold Hyderabad property agent actually asks in the
* first two minutes of a WhatsApp thread. Typing them fresh each time is how a
* promise drifts: "we never sell their number" becomes "we don't really sell
* it", and the campaign's whole argument is that the promises are verifiable.
*
* Wording is lifted from the public partner page (`apps/go/src/i18n/en.ts`) on
* purpose — an operator must never answer something different from what the
* page the prospect just read already says.
*
* Vocabulary rules carried over from that file and binding on translations:
* "contact" not "lead" — an agent sends people, not leads
* "professional" not "designer" — the marketplace has both
* "enquiry form" not "link" — a form is something they fill in themselves
*/
/**
* Closed union rather than `string`, so `CANNED_REPLIES` cannot quietly gain
* an eleventh entry that no chip renders and no test covers.
*/
export type CannedReplyKey =
| "where_number"
| "who_is_interioring"
| "number_policy"
| "payment"
| "not_spam"
| "no_exclusivity"
| "areas"
| "your_page"
| "no_problem"
| "understood_stopping";
/** Short chip label. Kept to two or three words so ten fit on one row. */
export type CannedReply = {
key: CannedReplyKey;
label: Record<RrmLocale, string>;
body: Record<RrmLocale, string>;
};
/**
* Typed as a total map over both unions, which is the whole point: a locale
* added to `RrmLocale` or a key added to `CannedReplyKey` fails the build here
* instead of falling back to English at the operator's fingertips. Requirement
* P1-6.1 forbids a silent English fallback — a half-translated reply reads as
* carelessness to exactly the audience this campaign is asking to trust it.
*/
export const CANNED_REPLIES: Record<CannedReplyKey, CannedReply> = {
where_number: {
key: "where_number",
label: {
en: "Where I got your number",
te: "మీ నంబర్ ఎక్కడిది",
"te-Latn": "Mee number ekkadidi",
},
body: {
en: "Your number is on your public property listing — that is where I found it. I am not from a list anyone sold me, and if you would rather I did not message again, say so and I will stop for good.",
te: "మీ పబ్లిక్ ప్రాపర్టీ లిస్టింగ్లో మీ నంబర్ ఉంది — అక్కడి నుండే తీసుకున్నాను. ఎవరూ అమ్మిన లిస్ట్ నుండి కాదు. నేను మళ్లీ మెసేజ్ చేయకూడదు అనుకుంటే చెప్పండి, శాశ్వతంగా ఆపేస్తాను.",
"te-Latn":
"Mee public property listing lo mee number undi — akkadi nunche teesukunnanu. Evaro ammina list nunchi kaadu. Nenu malli message cheyakudadu anukunte cheppandi, permanent ga aapestanu.",
},
},
who_is_interioring: {
key: "who_is_interioring",
label: {
en: "Who is Interioring",
te: "ఇంటీరియరింగ్ అంటే",
"te-Latn": "Interioring ante",
},
body: {
en: "Interioring is a Hyderabad marketplace that helps interior professionals grow. For a homeowner we get itemised quotes, review those quotes on their behalf, and match them with a professional who can do the job. We do not do the design work ourselves.",
te: "ఇంటీరియరింగ్ అనేది హైదరాబాద్లో ఇంటీరియర్ ప్రొఫెషనల్స్ ఎదగడానికి సహాయపడే మార్కెట్ప్లేస్. ఇంటి యజమాని కోసం మేము వివరాలతో కూడిన కొటేషన్లు తెప్పించి, వాటిని వారి తరఫున సమీక్షించి, పని చేయగల ప్రొఫెషనల్తో కలుపుతాము. డిజైన్ పని మేము చేయము.",
"te-Latn":
"Interioring ante Hyderabad lo interior professionals edagadaniki sahayapade marketplace. Inti yajamani kosam memu itemised quotes teppinchi, vaatini vaari tarafuna review chesi, pani cheyagala professional tho kalupu tamu. Design pani memu cheyamu.",
},
},
number_policy: {
key: "number_policy",
label: {
en: "Their number",
te: "వారి నంబర్",
"te-Latn": "Vaari number",
},
body: {
en: "Nothing happens to your contact's number until they fill in the enquiry form themselves. We never sell it or pass it on, we never say we got it from you unless you have told them first, and if they ask us to stop we stop permanently.",
te: "మీ కాంటాక్ట్ స్వయంగా ఎంక్వైరీ ఫారం నింపే వరకు వారి నంబర్కు ఏమీ జరగదు. మేము దానిని అమ్మము, ఎవరికీ ఇవ్వము. మీరు ముందుగా చెప్పకపోతే అది మీ నుండి వచ్చిందని మేము చెప్పము. వారు ఆపమంటే శాశ్వతంగా ఆపేస్తాము.",
"te-Latn":
"Mee contact svayanga enquiry form nimpe varaku vaari number ki emi jaragadu. Memu daanini ammamu, evariki ivvamu. Meeru mundhuga cheppakapothe adi mee nunchi vachchindani memu cheppamu. Vaaru aapamante permanent ga aapestamu.",
},
},
payment: {
key: "payment",
label: {
en: "How payment works",
te: "చెల్లింపు ఎలా",
"te-Latn": "Payment ela",
},
body: {
en: "₹100 once the contact you send is validated, and ₹1,000 if they go ahead with a matched professional. Earnings are released to your UPI once the balance reaches ₹1,000, after a 5-day hold. Nothing expires while it builds.",
te: "మీరు పంపిన కాంటాక్ట్ ధృవీకరించబడిన తర్వాత ₹100, వారు మ్యాచ్ అయిన ప్రొఫెషనల్తో ముందుకు వెళ్తే ₹1,000. బ్యాలెన్స్ ₹1,000 చేరిన తర్వాత, 5 రోజుల హోల్డ్ తర్వాత మీ UPIకి విడుదల చేస్తాము. పేరుకుంటున్నంత సేపు ఏదీ రద్దు కాదు.",
"te-Latn":
"Meeru pampina contact validate ayina tarvata ₹100, vaaru match ayina professional tho mundhuku velthe ₹1,000. Balance ₹1,000 cherina tarvata, 5 rojula hold tarvata mee UPI ki release chestamu. Perukuntunnanta sepu edi radhu kaadu.",
},
},
not_spam: {
key: "not_spam",
label: {
en: "Is this spam",
te: "ఇది స్పామ్ కాదా",
"te-Latn": "Idi spam aa",
},
body: {
en: "Fair question. We are Interioring Business and Technology Solutions Pvt Ltd, Hyderabad. There is nothing to pay and nothing to sign up for — you send one contact and watch what we say to them on your own page. If it is not useful, tell me and I will stop messaging you.",
te: "సరైన ప్రశ్న. మేము ఇంటీరియరింగ్ బిజినెస్ అండ్ టెక్నాలజీ సొల్యూషన్స్ ప్రైవేట్ లిమిటెడ్, హైదరాబాద్. కట్టడానికి ఏమీ లేదు, సైన్ అప్ చేయాల్సింది ఏమీ లేదు — మీరు ఒక కాంటాక్ట్ పంపి, వారికి మేము ఏమి చెబుతున్నామో మీ పేజీలో చూడండి. ఉపయోగం లేకపోతే చెప్పండి, మెసేజ్ చేయడం ఆపేస్తాను.",
"te-Latn":
"Saraina prashna. Memu Interioring Business and Technology Solutions Pvt Ltd, Hyderabad. Kattadaniki emi ledu, sign up cheyalsindi emi ledu — meeru oka contact pampi, vaariki memu emi chebuthunnamo mee page lo chudandi. Upayogam lekapothe cheppandi, message cheyadam aapestanu.",
},
},
no_exclusivity: {
key: "no_exclusivity",
label: {
en: "No exclusivity",
te: "ప్రత్యేకత అవసరం లేదు",
"te-Latn": "Exclusivity ledu",
},
body: {
en: "This asks for no exclusivity. Keep working with whoever else you like — it takes under a minute per contact. Run both and see which one pays.",
te: "దీనికి ఎలాంటి ప్రత్యేకత అవసరం లేదు. మీరు ఇంకెవరితో పని చేస్తున్నా కొనసాగించండి — ఒక్కో కాంటాక్ట్కు నిమిషం కూడా పట్టదు. రెండూ నడిపి, ఏది డబ్బు ఇస్తుందో చూడండి.",
"te-Latn":
"Deeniki elanti exclusivity avasaram ledu. Meeru inkevaritho pani chestunna konasaginchandi — okko contact ki nimisham kuda pattadu. Rendu nadipi, edi dabbu istundo chudandi.",
},
},
areas: {
key: "areas",
label: {
en: "Areas covered",
te: "కవర్ చేసే ప్రాంతాలు",
"te-Latn": "Cover chese praantalu",
},
body: {
en: "All of Hyderabad. We are strongest in the western corridor: Tellapur, Kokapet, Narsingi, Gachibowli, Nallagandla, Bachupally.",
te: "హైదరాబాద్ మొత్తం. పశ్చిమ కారిడార్లో మేము బలంగా ఉన్నాము: తెల్లాపూర్, కోకాపేట, నార్సింగి, గచ్చిబౌలి, నల్లగండ్ల, బాచుపల్లి.",
"te-Latn":
"Hyderabad motham. Paschima corridor lo memu balanga unnamu: Tellapur, Kokapet, Narsingi, Gachibowli, Nallagandla, Bachupally.",
},
},
your_page: {
key: "your_page",
label: {
en: "Here is your page",
te: "ఇదిగో మీ పేజీ",
"te-Latn": "Idigo mee page",
},
body: {
en: "Here is your page. Every message we send the person you introduce, and every reply, appears here as it happens — along with what you have earned. Nothing to log in to, the link is yours.",
te: "ఇదిగో మీ పేజీ. మీరు పరిచయం చేసిన వ్యక్తికి మేము పంపే ప్రతి మెసేజ్, వారి ప్రతి సమాధానం ఇక్కడ అప్పటికప్పుడు కనిపిస్తాయి — మీరు సంపాదించినది కూడా. లాగిన్ అవసరం లేదు, ఈ లింక్ మీది.",
"te-Latn":
"Idigo mee page. Meeru parichayam chesina vyaktiki memu pampe prati message, vaari prati samadhanam ikkada appatikappudu kanipistayi — meeru sampadinchindi kuda. Login avasaram ledu, ee link meedi.",
},
},
/**
* Sent as part of the snooze action, not on its own. P1-7.11: a snoozed
* prospect has to be told, otherwise silence looks like being ignored and
* the next message in two months arrives with no context.
*/
no_problem: {
key: "no_problem",
label: {
en: "No problem, leaving it",
te: "ఫర్వాలేదు, వదిలేస్తున్నాను",
"te-Latn": "Parledu, vadilestunnanu",
},
body: {
en: "No problem at all — I will leave it there. If a buyer ever asks you about interiors, you have my number. Thank you for reading.",
te: "ఫర్వాలేదు — ఇక్కడితో వదిలేస్తాను. ఎప్పుడైనా ఒక కొనుగోలుదారు ఇంటీరియర్స్ గురించి అడిగితే, నా నంబర్ మీ దగ్గర ఉంది. చదివినందుకు ధన్యవాదాలు.",
"te-Latn":
"Parledu — ikkaditho vadilestanu. Eppudaina oka konugoludaru interiors gurinchi adigite, naa number mee daggara undi. Chadivinanduku dhanyavadalu.",
},
},
/**
* The single confirmation a DNC prospect receives. Deliberately says only
* that we are stopping: an opt-out reply is not an opening to re-pitch.
*/
understood_stopping: {
key: "understood_stopping",
label: {
en: "Understood, stopping",
te: "అర్థమైంది, ఆపేస్తున్నాను",
"te-Latn": "Ardhamaindi, aapestunnanu",
},
body: {
en: "Understood. I have removed your number and you will not hear from us again. Sorry for the interruption.",
te: "అర్థమైంది. మీ నంబర్ తొలగించాను, మా నుండి మీకు ఇక ఎప్పుడూ మెసేజ్ రాదు. ఇబ్బంది పెట్టినందుకు క్షమించండి.",
"te-Latn":
"Ardhamaindi. Mee number tolaginchanu, maa nunchi meeku ika eppudu message raadu. Ibbandi pettinanduku kshaminchandi.",
},
},
};
/** Chip render order. Explicit because object key order is not a design decision. */
export const CANNED_REPLY_ORDER: readonly CannedReplyKey[] = [
"where_number",
"who_is_interioring",
"number_policy",
"payment",
"not_spam",
"no_exclusivity",
"areas",
"your_page",
"no_problem",
"understood_stopping",
];
export function cannedReplyBody(
key: CannedReplyKey,
locale: RrmLocale,
): string {
return CANNED_REPLIES[key].body[locale];
}
export function cannedReplyLabel(
key: CannedReplyKey,
locale: RrmLocale,
): string {
return CANNED_REPLIES[key].label[locale];
}
/**
* First line of a reply, for the triage-button tooltips.
*
* The operator has to be able to read what a button will send before pressing
* it — these buttons send immediately, with no draft step to review.
*/
export function firstLine(body: string): string {
// `split` always yields at least one element, including for "".
return body.split("\n")[0].trim();
}
|