I’m processing incoming WhatsApp messages from Twilio’s webhook.
Each message payload includes fields such as:
-
Body → the text the user sends (e.g., city name like Toronto)
-
From → the user’s WhatsApp number
-
To → my Twilio WhatsApp business number
The goal is to read the user’s message, identify which city they mentioned, and automatically send back an event info reply (date, venue, ticket link, etc.) through WhatsApp.
Please see the code below
// ====== INPUT ======
const raw = (input.text || "").trim();
// ====== 1) Normalize ======
const normalize = s =>
s.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "")
.toLowerCase()
.replace(/\s+/g, "");
const key = normalize(raw);
// ====== 2) Master lookup (variant → full data) ======
const CITY_DATA = {
// Toronto
"toronto": {
canonical: "Toronto",
sheetId: "694522877",
reply: `Got it🙂,\nHere is the info:\n-*Event Name:* Ghalia Benali.\n-*Event Date:* November 1st.\n-*Location:* Aga Khan Museum – North York.\n-*Ticket Price:* Starts from $45 CAD.\n-*Tickets Link:* https://maplearts.co/maple-arts-concerts/toronto/\n\nYou can chat with our support team directly by clicking this link: https://wa.me/16479642706`
},
"تورونتو": { canonical: "Toronto", sheetId: "694522877" }, // Arabic
// Mississauga
"mississauga": {
canonical: "Mississauga",
sheetId: "571473591",
reply: `Got it🙂,\nHere is the info:\n-*Event Name:* Sing Along Fayrouz (غنوا معنا فيروز).\n-*Event Date:* December 6th, 2025.\n-*Time:* 7:30 pm.\n-*Location:* Studio Theatre – Living Arts Center, 4141 Living Arts Drive, Mississauga, ON.\n-*Ticket Price:* Starts from $45 CAD.\n-*Tickets Link:* https://maplearts.co/maple-arts-concerts/mississauga-3/\n\nYou can chat with our support team directly by clicking this link: https://wa.me/16479642706`
},
"ميسيساجا": { canonical: "Mississauga", sheetId: "571473591" },
// Montreal
"montreal": {
canonical: "Montreal",
sheetId: "1120094816",
reply: `Got it 🙂\nHere is the info:\n**Event:** Ahmad Azrak: Mwashahat wa Qudood (أحمد الأزرق: موشحات وقدود)\n**Date:** November 29th, 2025\n**Location:** Oscar Peterson Hall – Université Concordia, Montréal\n**Price:** From $58 CAD\n**Tickets:** https://maplearts.co/maple-arts-concerts/montreal-2/\n\n**Support:** https://wa.me/16479642706`
},
"مونتريال": { canonical: "Montreal", sheetId: "1120094816" },
// Ottawa
"ottawa": {
canonical: "Ottawa",
sheetId: "841957480",
reply: `Got it 🙂\nHere is the info:\n*Event:* Marwan Khoury (مروان خوري)\n*Date:* October 26th, 2025\n*Location:* Meridian Theatres @ Centrepointe – Nepean, ON\n*Price:* From $147 CAD\n*Tickets:* https://maplearts.co/maple-arts-concerts/ottawa-2/\n\n*Support:* https://wa.me/16479642706`
},
"اوتاوا": { canonical: "Ottawa", sheetId: "841957480" },
"أوتاوا": { canonical: "Ottawa", sheetId: "841957480" },
// Vancouver
"vancouver": {
canonical: "Vancouver",
sheetId: "1248528019",
reply: `Got it🙂,\nHere is the info:\n-*Event Name:* Marwan Khoury.\n-*Event Date:* October 31st.\n-*Location:* Chan Shun Concert Hall – Vancouver.\n-*Ticket Price:* Starts from $156 CAD.\n-*Tickets Link:* https://maplearts.co/maple-arts-concerts/vancouver/\n\nYou can chat with our support team directly by clicking this link: https://wa.me/16479642706`
},
"فانكوفر": { canonical: "Vancouver", sheetId: "1248528019" },
// Markham
"markham": {
canonical: "Markham",
sheetId: "918000282",
reply: `Got it🙂, we have two concerts in Markham:\nHere is the info:\n*First Event:*\n- *Event Name:* Hidden Gems.\n- *Event Date:* October 17th.\n- *Location:* People's Theatre for the Performing Arts – Markham.\n- *Ticket Price:* $34 CAD.\n- *Tickets Link:* https://maplearts.co/maple-arts-concerts/markham-2/\n\n*Second Event:*\n- *Event Name:* Marwan Khoury.\n- *Event Date:* November 1st.\n- *Location:* People's Theatre for the Performing Arts – Markham.\n- *Ticket Price:* Starts from $134 CAD.\n- *Tickets Link:* https://maplearts.co/maple-arts-concerts/markham/\n\nYou can chat with our support team directly by clicking this link: https://wa.me/16479642706`
},
"ماركام": { canonical: "Markham", sheetId: "918000282" },
// Windsor
"windsor": {
canonical: "Windsor",
sheetId: "318168110",
reply: `Got it🙂,\nHere is the info:\n-*Event Name:* Tribute to Melhem Barakat.\n-*Event Date:* November 9th.\n-*Location:* Capitol Theatre – Windsor.\n-*Ticket Price:* Starts from $45 CAD.\n-*Tickets Link:* https://maplearts.co/maple-arts-concerts/windsor/\n\nYou can chat with our support team directly by clicking this link: https://wa.me/16479642706`
},
"وندسور": { canonical: "Windsor", sheetId: "318168110" },
// Lakewood
"lakewood": {
canonical: "Lakewood",
sheetId: "658793209",
reply: `Got it🙂,\nHere is the info:\n-*Event Name:* Sing Along.\n-*Event Date:* November 15th.\n-*Location:* Lakewood Civic Auditorium – Lakewood.\n-*Ticket Price:* Starts from $57 USD.\n-*Tickets Link:* https://whoome.ca/featured_item/cleveland/\n\nYou can chat with our support team directly by clicking this link: https://wa.me/16479642706`
},
"cleveland": { canonical: "Lakewood", sheetId: "658793209" },
// Tampa
"tampa": {
canonical: "Tampa",
sheetId: "931276343",
reply: `Got it 🙂\nHere is the info:\n*Event:* Sing Along! (غنوا معنا)\n*Date:* November 7th, 2025\n*Location:* Centro Asturiano de Tampa – Tampa, FL\n*Price:* From $62 CAD\n*Tickets:* https://whoome.ca/featured_item/florida\n\n**Support:** https://wa.me/16479642706`
},
"تامبا": { canonical: "Tampa", sheetId: "931276343" },
// Scarborough
"scarborough": {
canonical: "Scarborough",
sheetId: "1195212322",
reply: `Got it 🙂\nHere is the info:\n*Event:* Crossroads (مُفترق الطُرُق)\n*Date:* November 1st, 2025\n*Location:* Salvation Army Scarborough – Scarborough, ON\n*Price:* From $50 CAD\n*Tickets:* https://maplearts.co/maple-arts-concerts/scharborough/\n\nSupport: https://wa.me/16479642706`
},
"سكرابورو": { canonical: "Scarborough", sheetId: "1195212322" },
// Stop
"stop": {
canonical: "Stop",
sheetId: "0",
reply: `Sure, no problem. You will not receive further messages.\nحسنًا، نعتذر عن الإزعاج 🙏`
},
"توقف": { canonical: "Stop", sheetId: "0" }
};
// ====== 3) Resolve city or default ======
const defaultData = {
canonical: "Invalid",
sheetId: "1995010707",
reply:
"Invalid city. Please reply with one of: Toronto, Mississauga, Montreal, Ottawa, Vancouver, Markham, Windsor, Lakewood, Tampa, Scarborough."
};
const cityData = CITY_DATA[key] || defaultData;
// ====== 4) Return bundle ======
return [{
inputRaw: raw,
normalized: key,
city: cityData.canonical,
sheetId: cityData.sheetId,
valid: cityData.canonical !== "Invalid",
isStop: cityData.canonical === "Stop",
reply: cityData.reply
}];