const { Telegraf, Markup } = require("telegraf"); const TOKEN = "8671185243:AAE5LEGTnf7uFieED0Bcm7et16ZhemmF84Q"; const STORE_INFO = { name: "Supamart", tagline: "Fresh deals, daily essentials, and friendly service.", location: "Lot 18, Jalan Maju, Kuala Lumpur", hoursWeekday: "8:00 AM - 10:00 PM", hoursWeekend: "8:00 AM - 11:00 PM", contact: "+60 12-345 6789", delivery: "Same-day delivery available for selected areas.", }; const IMAGES = { storefront: "https://upload.wikimedia.org/wikipedia/commons/thumb/4/42/Exterior_of_an_Aldi_S%C3%BCd_supermarket_in_Franklin%2C_North_Carolina%2C_US_04.jpg/1280px-Exterior_of_an_Aldi_S%C3%BCd_supermarket_in_Franklin%2C_North_Carolina%2C_US_04.jpg", produce: "https://upload.wikimedia.org/wikipedia/commons/thumb/6/64/Fruits_and_vegetables_at_market.jpg/1280px-Fruits_and_vegetables_at_market.jpg", snacks: "https://upload.wikimedia.org/wikipedia/commons/5/5f/Extra_%28Coop_supermarket%29_Bergen_Storsenter_Norway_2017-11-16_snacks_aisle.jpg", breakfast: "https://upload.wikimedia.org/wikipedia/commons/1/15/Breakfast_with_Bread_%26_Egg.jpg", household: "https://upload.wikimedia.org/wikipedia/commons/8/82/Ammonia_%28%22Salmiakk%22%29%2C_bleach_%28%22Klorin%22%29_and_other_cleaning_products_aisle_in_Coop_Extra_supermarket%2C_Bergen_Stormarked_Shopping_Mall%2C_Norway_2017-10-25_a.jpg", grocery: "https://upload.wikimedia.org/wikipedia/commons/9/9b/Grocery_store_scene%2C_Cartagena%2C_Colombia_%2823714682243%29.jpg", delivery: "https://upload.wikimedia.org/wikipedia/commons/6/69/Food_delivery_driver_delivering_online_order.jpg", }; const PROMOTIONS = [ { title: "Mega Grocery Saver", description: "Buy any 2 household essentials and get 15% off the third item. Applies to detergent, dishwash liquid, paper towels, and toilet rolls.", validity: "Valid until Sunday", highlight: "Perfect for family restocks.", imageKey: "household", }, { title: "Fresh Produce Friday", description: "Get 20% off selected vegetables and fruits including tomatoes, carrots, bananas, and apples.", validity: "Every Friday only", highlight: "Freshness at better prices.", imageKey: "produce", }, { title: "Snack Attack Combo", description: "Buy 3 snacks and get 1 free on selected chips, biscuits, and chocolate bars.", validity: "While stocks last", highlight: "Great for movie nights and office snacks.", imageKey: "snacks", }, { title: "Breakfast Bundle", description: "Purchase bread + eggs + milk together and enjoy a bundle discount of RM5.", validity: "Daily offer", highlight: "Easy morning essentials in one deal.", imageKey: "breakfast", }, { title: "Member Monday", description: "Supamart members receive 10% off total bill when spending above RM80.", validity: "Every Monday", highlight: "Best for weekly household shopping.", imageKey: "storefront", }, ]; const PRODUCT_RECOMMENDATIONS = { rice: { text: "Our top rice pick this week is Supamart Premium Fragrant Rice 5kg. Good value and popular with regular shoppers.", imageKey: "grocery", }, milk: { text: "For milk, customers usually go for fresh full cream milk or family value UHT packs when stocking up.", imageKey: "breakfast", }, snacks: { text: "Our snack section is popular for chips, chocolate wafers, seaweed crisps, and party packs.", imageKey: "snacks", }, drinks: { text: "For drinks, we usually recommend mineral water multipacks, juice cartons, isotonic drinks, and canned coffee.", imageKey: "grocery", }, cleaning: { text: "For cleaning supplies, our bestsellers include laundry detergent, dishwashing liquid, floor cleaner, and multipurpose wipes.", imageKey: "household", }, baby: { text: "For baby care, parents often ask for diapers, baby wipes, baby bath wash, and formula.", imageKey: "grocery", }, }; const COMMON_FAQ = { delivery: "Yes, Supamart offers same-day delivery for selected areas. You can ask me about deals before ordering.", location: `Supamart is located at ${STORE_INFO.location}.`, hours: `Weekdays: ${STORE_INFO.hoursWeekday}\nWeekends: ${STORE_INFO.hoursWeekend}`, contact: `You can contact Supamart at ${STORE_INFO.contact}.`, member: "Supamart membership gives access to member-only deals, especially our Member Monday promotion.", payment: "Supamart accepts cash, card, and e-wallet payments.", }; const GREETINGS = [ "Hello! Welcome to Supamart. How can I help you today?", "Hi there! I’m the Supamart assistant. Looking for today’s promotions, store info, or product suggestions?", "Hey! Great to see you. I can help with Supamart deals, shopping ideas, and store details.", ]; const HOW_ARE_YOU_REPLIES = [ "I’m doing great, thank you. I’m here and ready to help you shop smarter at Supamart.", "I’m good and ready to help. Want to hear today’s best Supamart promotions?", "Doing well. I’ve got fresh Supamart deals ready for you if you want them.", ]; const FALLBACK_RESPONSES = [ "I can help with Supamart promotions, store hours, delivery, product suggestions, and shopping bundles. Try asking: What promotions do you have?", "I’m here to chat and help you discover Supamart deals. You can ask about discounts, groceries, delivery, or store info.", "I can help with deals, location, contact details, product suggestions, and shopping recommendations. Try asking about Supamart promotions.", ]; const userMemory = new Map(); function mainKeyboard() { return Markup.keyboard([ ["Promotions", "Store Hours"], ["Location", "Delivery"], ["Best Deals", "Contact"], ]).resize(); } function currentStoreHours() { const day = new Date().getDay(); // Sunday=0, Saturday=6 const isWeekend = day === 0 || day === 6; return isWeekend ? `🕒 Supamart is open today from ${STORE_INFO.hoursWeekend}.` : `🕒 Supamart is open today from ${STORE_INFO.hoursWeekday}.`; } function detectName(text) { const patterns = [ /\bmy name is ([A-Za-z][A-Za-z\s'-]{1,30})\b/i, /\bi am ([A-Za-z][A-Za-z\s'-]{1,30})\b/i, /\bi'm ([A-Za-z][A-Za-z\s'-]{1,30})\b/i, ]; for (const pattern of patterns) { const match = text.match(pattern); if (match) { return match[1].trim().replace(/\b\w/g, (c) => c.toUpperCase()); } } return null; } function getUserName(userId) { return userMemory.get(userId)?.name || ""; } function saveUserName(userId, name) { const current = userMemory.get(userId) || {}; userMemory.set(userId, { ...current, name }); } function personalizedPrefix(userId) { const name = getUserName(userId); return name ? `${name}, ` : ""; } function keywordMatch(text, keywords) { const lower = text.toLowerCase(); return keywords.some((keyword) => lower.includes(keyword)); } function randomItem(array) { return array[Math.floor(Math.random() * array.length)]; } function pickRandomPromotions(count) { const shuffled = [...PROMOTIONS].sort(() => Math.random() - 0.5); return shuffled.slice(0, Math.min(count, shuffled.length)); } async function safeReplyPhoto(ctx, imageKey, caption) { const photoUrl = IMAGES[imageKey]; if (!photoUrl) { await ctx.reply(caption, mainKeyboard()); return; } try { await ctx.replyWithPhoto(photoUrl, { caption, ...mainKeyboard(), }); } catch (error) { console.error(`Failed to send photo for ${imageKey}:`, error.message); await ctx.reply(caption, mainKeyboard()); } } async function sendText(ctx, text) { await ctx.reply(text, mainKeyboard()); } async function sendStorefrontMessage(ctx, text) { await safeReplyPhoto(ctx, "storefront", text); } async function sendDeliveryMessage(ctx, text) { await safeReplyPhoto(ctx, "delivery", text); } async function sendPromotionGallery(ctx) { for (const promo of PROMOTIONS) { const caption = `🛒 ${promo.title}\n\n` + `${promo.description}\n\n` + `⭐ ${promo.highlight}\n` + `📅 ${promo.validity}`; await safeReplyPhoto(ctx, promo.imageKey, caption); } await ctx.reply( "Need help choosing the best promotion for your budget? Tell me what you need and I’ll recommend the best deal.", mainKeyboard() ); } async function sendBestDeals(ctx) { const featured = pickRandomPromotions(3); for (const promo of featured) { const caption = `🔥 ${promo.title}\n\n` + `${promo.description}\n\n` + `📌 ${promo.highlight}\n` + `📅 ${promo.validity}`; await safeReplyPhoto(ctx, promo.imageKey, caption); } } function productReply(text) { const lower = text.toLowerCase(); for (const [keyword, payload] of Object.entries(PRODUCT_RECOMMENDATIONS)) { if (lower.includes(keyword)) { return { message: `🛍️ ${payload.text}\n\n` + "Would you like me to recommend a Supamart promotion that matches it?", imageKey: payload.imageKey, }; } } return null; } function shoppingIntentReply(text) { const lower = text.toLowerCase(); if ( ["cheap", "budget", "save", "saving", "discount"].some((word) => lower.includes(word) ) ) { return { message: "💡 If you're trying to save money, I recommend these Supamart offers:\n" + "1. Breakfast Bundle\n" + "2. Member Monday\n" + "3. Mega Grocery Saver\n\n" + "Tell me what items you need, and I’ll suggest the best deal.", imageKey: "household", }; } if ( ["family", "weekly groceries", "household", "restock"].some((word) => lower.includes(word) ) ) { return { message: "👨‍👩‍👧‍👦 For family or household restocking, the best Supamart promotions are:\n" + "- Mega Grocery Saver\n" + "- Member Monday\n" + "- Breakfast Bundle\n\n" + "These are great for practical weekly shopping.", imageKey: "household", }; } if ( ["party", "movie night", "office snacks"].some((word) => lower.includes(word) ) ) { return { message: "🎉 For parties or snack runs, I’d suggest our Snack Attack Combo. It’s one of the most fun promotions we have right now.", imageKey: "snacks", }; } return null; } if (TOKEN === "PASTE_YOUR_TELEGRAM_BOT_TOKEN_HERE") { throw new Error("Please replace TOKEN with your real Telegram bot token."); } const bot = new Telegraf(TOKEN); bot.start(async (ctx) => { const firstName = ctx.from?.first_name || "there"; await safeReplyPhoto( ctx, "storefront", `Hello ${firstName}! 👋\n\nWelcome to ${STORE_INFO.name}.\n${STORE_INFO.tagline}` ); await ctx.reply( "I’m your Supamart assistant. I can chat with you naturally and help with:\n" + "• Current promotions\n" + "• Best-value shopping ideas\n" + "• Store hours\n" + "• Delivery info\n" + "• Location and contact details\n" + "• Product suggestions\n\n" + "Try asking:\n" + "• What promotions do you have?\n" + "• Do you have any deals on snacks?\n" + "• Where is Supamart?\n" + "• What time do you close?\n" + "• I want to save money on groceries\n", mainKeyboard() ); }); bot.command("help", async (ctx) => { await sendText( ctx, "Here’s what I can help you with:\n\n" + "/start - Start chatting with Supamart assistant\n" + "/help - Show help menu\n" + "/promotions - Show all current promotions\n" + "/deals - Show best featured deals\n" + "/hours - Show store hours\n" + "/location - Show store location\n" + "/contact - Show contact and delivery details\n\n" + "You can also chat normally with me.\n" + "Examples:\n" + "- Hello\n" + "- How are you?\n" + "- I need cheap groceries\n" + "- Any snack promotion?\n" + "- Do you deliver?\n" ); }); bot.command("promotions", async (ctx) => { await sendPromotionGallery(ctx); }); bot.command("deals", async (ctx) => { await sendBestDeals(ctx); }); bot.command("hours", async (ctx) => { await sendStorefrontMessage( ctx, `${currentStoreHours()}\n\nWeekdays: ${STORE_INFO.hoursWeekday}\nWeekends: ${STORE_INFO.hoursWeekend}` ); }); bot.command("location", async (ctx) => { await sendStorefrontMessage( ctx, `📍 Supamart is located at:\n${STORE_INFO.location}` ); }); bot.command("contact", async (ctx) => { await sendDeliveryMessage( ctx, `📞 Contact Supamart: ${STORE_INFO.contact}\n🚚 Delivery: ${STORE_INFO.delivery}` ); }); bot.hears("Promotions", async (ctx) => { await sendPromotionGallery(ctx); }); bot.hears("Store Hours", async (ctx) => { await sendStorefrontMessage( ctx, `${currentStoreHours()}\n\nWeekdays: ${STORE_INFO.hoursWeekday}\nWeekends: ${STORE_INFO.hoursWeekend}` ); }); bot.hears("Location", async (ctx) => { await sendStorefrontMessage( ctx, `📍 Supamart is located at ${STORE_INFO.location}.` ); }); bot.hears("Delivery", async (ctx) => { await sendDeliveryMessage(ctx, `🚚 ${STORE_INFO.delivery}`); }); bot.hears("Best Deals", async (ctx) => { await sendBestDeals(ctx); }); bot.hears("Contact", async (ctx) => { await sendDeliveryMessage( ctx, `📞 You can reach Supamart at ${STORE_INFO.contact}.` ); }); bot.on("text", async (ctx) => { const userText = ctx.message.text.trim(); const textLower = userText.toLowerCase(); const userId = ctx.from?.id; if (!userId) { await sendText(ctx, "I couldn't identify this user session."); return; } const detectedName = detectName(userText); if (detectedName) { saveUserName(userId, detectedName); await sendStorefrontMessage( ctx, `Nice to meet you, ${detectedName}! 😊 How can I help you with Supamart today?` ); return; } const prefix = personalizedPrefix(userId); if ( keywordMatch(textLower, [ "hello", "hi", "hey", "good morning", "good afternoon", "good evening", ]) ) { await sendText(ctx, prefix + randomItem(GREETINGS)); return; } if (keywordMatch(textLower, ["how are you", "how are u", "how r you"])) { await sendText(ctx, prefix + randomItem(HOW_ARE_YOU_REPLIES)); return; } if ( keywordMatch(textLower, [ "promotion", "promotions", "deal", "deals", "discount", "offer", "offers", "promo", ]) ) { await sendPromotionGallery(ctx); return; } if ( keywordMatch(textLower, [ "open", "close", "closing", "hours", "time do you open", "time do you close", ]) ) { await sendStorefrontMessage( ctx, `${currentStoreHours()}\n\nWeekdays: ${STORE_INFO.hoursWeekday}\nWeekends: ${STORE_INFO.hoursWeekend}` ); return; } if (keywordMatch(textLower, ["where", "location", "address", "located"])) { await sendStorefrontMessage( ctx, `📍 ${prefix}Supamart is located at ${STORE_INFO.location}.` ); return; } if (keywordMatch(textLower, ["delivery", "deliver", "shipping"])) { await sendDeliveryMessage(ctx, `🚚 ${prefix}${COMMON_FAQ.delivery}`); return; } if (keywordMatch(textLower, ["contact", "phone", "number", "call"])) { await sendDeliveryMessage( ctx, `📞 ${prefix}You can contact Supamart at ${STORE_INFO.contact}.` ); return; } if (keywordMatch(textLower, ["member", "membership"])) { await sendStorefrontMessage(ctx, `💳 ${prefix}${COMMON_FAQ.member}`); return; } if ( keywordMatch(textLower, ["payment", "pay", "cash", "card", "ewallet", "e-wallet"]) ) { await sendStorefrontMessage(ctx, `💵 ${prefix}${COMMON_FAQ.payment}`); return; } const productSuggestion = productReply(textLower); if (productSuggestion) { await safeReplyPhoto(ctx, productSuggestion.imageKey, productSuggestion.message); return; } const intentReply = shoppingIntentReply(textLower); if (intentReply) { await safeReplyPhoto(ctx, intentReply.imageKey, intentReply.message); return; } if ( keywordMatch(textLower, [ "what should i buy", "recommend", "suggest", "best item", "best items", ]) ) { await safeReplyPhoto( ctx, "grocery", "🛒 Here are some Supamart recommendations right now:\n\n" + "1. Breakfast Bundle - practical daily essentials\n" + "2. Snack Attack Combo - fun and value-packed\n" + "3. Fresh Produce Friday - best for healthier shopping\n" + "4. Mega Grocery Saver - ideal for restocking home supplies\n\n" + "Tell me your budget or what category you want, and I’ll narrow it down for you." ); return; } if (keywordMatch(textLower, ["thanks", "thank you", "tq"])) { await sendText( ctx, `You’re welcome, ${getUserName(userId) || "my friend"}! Let me know if you want more Supamart deals.` ); return; } await safeReplyPhoto(ctx, "grocery", prefix + randomItem(FALLBACK_RESPONSES)); }); bot.catch((err) => { console.error("Bot error:", err); }); bot.launch(); console.log("Supamart bot is running..."); process.once("SIGINT", () => bot.stop("SIGINT")); process.once("SIGTERM", () => bot.stop("SIGTERM"));