{"slug": "jarvis-md-chatbot-by-blix-xer", "title": "Jarvis-md, chatbot by blix-xer", "summary": "A developer operating under the handle blix-xer published Jarvis-md, a WhatsApp chatbot built on the Baileys library that routes text and image queries to Groq-hosted models, using openai/gpt-oss-20b for text and qwen/qwen3.8-27b for vision. The bot keeps a rolling 10-message conversation history per chat, caps responses at 700 tokens, and includes a keyword-triggered motivational speech feature that returns one of 15 hardcoded two-line messages.", "body_md": "|  | const { | \n|  | System, | \n|  | getData, | \n|  | setData, | \n|  | makeUrl | \n|  | } = require(\"../lib/\"); | \n|  | // ============================================= | \n|  | // GROQ CONFIGURATION | \n|  | // ============================================= | \n|  | const GROQ_API = | \n|  | \"https://api.groq.com/openai/v1/chat/completions\"; | \n|  | const GROQ_API_KEY = process.env.GROQ_API_KEY \\|\\| \"\"; | \n|  | const TEXT_MODEL = \"openai/gpt-oss-20b\"; | \n|  | const VISION_MODEL = \"qwen/qwen3.8-27b\"; | \n|  | const MAX_HISTORY = 10; | \n|  | const MAX_TOKENS = 700; | \n|  | const TIMEZONE = \"Asia/Kolkata\"; | \n|  | const conversations = new Map(); | \n|  | // ============================================= | \n|  | // OWNER SETTINGS | \n|  | // ============================================= | \n|  | const OWNER_NAME = \"BLIX-XER\"; | \n|  | const OWNER_NUMBER = \"918075298454\"; | \n|  | // ============================================= | \n|  | // MOTIVATIONAL SPEECH COLLECTION | \n|  | // ============================================= | \n|  | const MOTIVATION_SPEECHES = [ | \n|  | [ | \n|  | \"Your current situation is not your final destination.\", | \n|  | \"Keep moving forward; your future is still yours to create.\" | \n|  | ], | \n|  | [ | \n|  | \"Greatness begins when you stop waiting for the perfect moment.\", | \n|  | \"Take the first step today, and let your actions build tomorrow.\" | \n|  | ], | \n|  | [ | \n|  | \"Your dreams deserve more than just your imagination.\", | \n|  | \"Give them your effort, your patience, and your determination.\" | \n|  | ], | \n|  | [ | \n|  | \"Every challenge is an opportunity to discover your strength.\", | \n|  | \"Rise above the difficulty and prove what you are capable of.\" | \n|  | ], | \n|  | [ | \n|  | \"Do not let one difficult chapter define your entire story.\", | \n|  | \"You still have countless pages left to write.\" | \n|  | ], | \n|  | [ | \n|  | \"Success is built through small efforts repeated consistently.\", | \n|  | \"Keep showing up, even when nobody notices your progress.\" | \n|  | ], | \n|  | [ | \n|  | \"The road to greatness is not always easy.\", | \n|  | \"But every step you take makes you stronger than yesterday.\" | \n|  | ], | \n|  | [ | \n|  | \"Stop measuring your journey against someone else's timeline.\", | \n|  | \"Build your own path and move at your own pace.\" | \n|  | ], | \n|  | [ | \n|  | \"A powerful future begins with a decision made today.\", | \n|  | \"Choose courage over excuses and progress over perfection.\" | \n|  | ], | \n|  | [ | \n|  | \"Your mistakes are lessons, not permanent labels.\", | \n|  | \"Learn from them, stand again, and keep building your future.\" | \n|  | ], | \n|  | [ | \n|  | \"You do not need to have everything figured out today.\", | \n|  | \"You only need the courage to take your next step.\" | \n|  | ], | \n|  | [ | \n|  | \"Let your determination speak louder than your doubts.\", | \n|  | \"One day, your hard work will tell a story worth remembering.\" | \n|  | ], | \n|  | [ | \n|  | \"Never underestimate what consistent effort can accomplish.\", | \n|  | \"Small steps taken every day can lead to extraordinary places.\" | \n|  | ], | \n|  | [ | \n|  | \"The strongest progress often happens when nobody is watching.\", | \n|  | \"Keep improving yourself, even when the applause is absent.\" | \n|  | ], | \n|  | [ | \n|  | \"Do not surrender your dreams because the journey feels difficult.\", | \n|  | \"Some of the most meaningful achievements take time.\" | \n|  | ] | \n|  | ]; | \n|  | // ============================================= | \n|  | // MOTIVATION REQUEST DETECTION | \n|  | // ============================================= | \n|  | function isMotivationRequest(text) { | \n|  | const input = String(text \\|\\| \"\") | \n|  | .toLowerCase() | \n|  | .trim(); | \n|  | const patterns = [ | \n|  | /\\bgive me (some )?motivation\\b/, | \n|  | /\\bmotivate me\\b/, | \n|  | /\\bi need motivation\\b/, | \n|  | /\\bneed some motivation\\b/, | \n|  | /\\bmotivation speech\\b/, | \n|  | /\\bsay something motivational\\b/, | \n|  | /\\binspire me\\b/, | \n|  | /\\bgive me an? motivational\\b/, | \n|  | /\\bmotivation please\\b/, | \n|  | /\\bmotivation venam\\b/, | \n|  | /\\bmotivation tharamo\\b/, | \n|  | /\\boru motivation\\b/, | \n|  | /\\benik motivation\\b/, | \n|  | /\\benikku motivation\\b/, | \n|  | /\\bkurach motivation\\b/, | \n|  | /\\bmotivate cheyy\\b/, | \n|  | /പ്രചോദനം/, | \n|  | /മോട്ടിവേഷൻ/, | \n|  | /എനിക്ക് മോട്ടിവേഷൻ/ | \n|  | ]; | \n|  | return patterns.some(pattern => pattern.test(input)); | \n|  | } | \n|  | // ============================================= | \n|  | // GET A DIFFERENT MOTIVATIONAL SPEECH | \n|  | // ============================================= | \n|  | function getMotivationSpeech(history) { | \n|  | const recentAnswers = (history \\|\\| []) | \n|  | .filter(item => item.role === \"assistant\") | \n|  | .map(item => item.content); | \n|  | const unusedSpeeches = MOTIVATION_SPEECHES.filter( | \n|  | speech => { | \n|  | const formatted = | \n|  | speech.join(\"\\n\") + | \n|  | \"\\n\\n*— JARVIS (Original)*\"; | \n|  | return !recentAnswers.includes(formatted); | \n|  | } | \n|  | ); | \n|  | const available = | \n|  | unusedSpeeches.length > 0 | \n|  | ? unusedSpeeches | \n|  | : MOTIVATION_SPEECHES; | \n|  | const selected = | \n|  | available[ | \n|  | Math.floor(Math.random() * available.length) | \n|  | ]; | \n|  | return ( | \n|  | selected[0] + | \n|  | \"\\n\" + | \n|  | selected[1] + | \n|  | \"\\n\\n\" + | \n|  | \"*— JARVIS (Original)*\" | \n|  | ); | \n|  | } | \n|  | // ============================================= | \n|  | // CURRENT DATE AND TIME | \n|  | // ============================================= | \n|  | function getCurrentDateTime() { | \n|  | const now = new Date(); | \n|  | const date = new Intl.DateTimeFormat(\"en-IN\", { | \n|  | timeZone: TIMEZONE, | \n|  | weekday: \"long\", | \n|  | day: \"2-digit\", | \n|  | month: \"long\", | \n|  | year: \"numeric\" | \n|  | }).format(now); | \n|  | const time = new Intl.DateTimeFormat(\"en-IN\", { | \n|  | timeZone: TIMEZONE, | \n|  | hour: \"2-digit\", | \n|  | minute: \"2-digit\", | \n|  | second: \"2-digit\", | \n|  | hour12: true | \n|  | }).format(now); | \n|  | return { | \n|  | date, | \n|  | time, | \n|  | timezone: \"Indian Standard Time (IST)\" | \n|  | }; | \n|  | } | \n|  | // ============================================= | \n|  | // HELPER FUNCTIONS | \n|  | // ============================================= | \n|  | function getNumber(jid) { | \n|  | if (!jid) return \"\"; | \n|  | return String(jid) | \n|  | .split(\"@\")[0] | \n|  | .split(\":\")[0] | \n|  | .replace(/\\D/g, \"\"); | \n|  | } | \n|  | function isOwner(jid) { | \n|  | return getNumber(jid) === getNumber(OWNER_NUMBER); | \n|  | } | \n|  | function getQuotedName(quoted) { | \n|  | if (!quoted) return null; | \n|  | return ( | \n|  | quoted.pushName \\|\\| | \n|  | quoted.notify \\|\\| | \n|  | quoted.name \\|\\| | \n|  | quoted.senderName \\|\\| | \n|  | quoted.contact?.name \\|\\| | \n|  | null | \n|  | ); | \n|  | } | \n|  | function getQuotedSender(quoted) { | \n|  | if (!quoted) return \"\"; | \n|  | return ( | \n|  | quoted.sender \\|\\| | \n|  | quoted.participant \\|\\| | \n|  | quoted.key?.participant \\|\\| | \n|  | quoted.from \\|\\| | \n|  | \"\" | \n|  | ); | \n|  | } | \n|  | // ============================================= | \n|  | // GROQ API FUNCTION | \n|  | // ============================================= | \n|  | async function askGroq(model, messages) { | \n|  | if (!GROQ_API_KEY) { | \n|  | throw new Error(\"GROQ_API_KEY is missing.\"); | \n|  | } | \n|  | const response = await fetch(GROQ_API, { | \n|  | method: \"POST\", | \n|  | headers: { | \n|  | Authorization: `Bearer ${GROQ_API_KEY}`, | \n|  | \"Content-Type\": \"application/json\" | \n|  | }, | \n|  | body: JSON.stringify({ | \n|  | model, | \n|  | messages, | \n|  | max_completion_tokens: MAX_TOKENS, | \n|  | temperature: 0.7, | \n|  | stream: false | \n|  | }), | \n|  | signal: AbortSignal.timeout(60000) | \n|  | }); | \n|  | if (!response.ok) { | \n|  | const errorText = await response.text(); | \n|  | console.error( | \n|  | \"JARVIS Groq Error:\", | \n|  | response.status, | \n|  | errorText.slice(0, 1500) | \n|  | ); | \n|  | throw new Error( | \n|  | `Groq API returned ${response.status}` | \n|  | ); | \n|  | } | \n|  | const data = await response.json(); | \n|  | const answer = | \n|  | data.choices?.[0]?.message?.content?.trim(); | \n|  | if (!answer) { | \n|  | throw new Error(\"Groq returned an empty response.\"); | \n|  | } | \n|  | return answer; | \n|  | } | \n|  | // ============================================= | \n|  | // JARVIS PERSONALITY | \n|  | // ============================================= | \n|  | function createSystemPrompt({ | \n|  | userName, | \n|  | owner, | \n|  | quoted, | \n|  | quotedName, | \n|  | quotedOwner | \n|  | }) { | \n|  | const current = getCurrentDateTime(); | \n|  | return ` | \n|  | You are JARVIS, an intelligent, friendly, | \n|  | natural and highly capable WhatsApp AI assistant. | \n|  | ======================== | \n|  | OWNER INFORMATION | \n|  | ======================== | \n|  | Owner name: ${OWNER_NAME} | \n|  | Current user: ${userName} | \n|  | Is current user the owner: ${owner ? \"YES\" : \"NO\"} | \n|  | IDENTITY RULES: | \n|  | 1. The owner's name is always ${OWNER_NAME}. | \n|  | 2. If the owner asks \"What is my name?\", | \n|  | answer: \"Your name is ${OWNER_NAME}.\" | \n|  | 3. If someone asks who owns you, | \n|  | answer: \"My owner is ${OWNER_NAME}.\" | \n|  | 4. Never call another user your owner. | \n|  | 5. Never invent a person's name. | \n|  | 6. Use the available WhatsApp display name naturally. | \n|  | ======================== | \n|  | QUOTED MESSAGE IDENTITY | \n|  | ======================== | \n|  | Quoted message exists: ${quoted ? \"YES\" : \"NO\"} | \n|  | Quoted sender name: ${quotedName \\|\\| \"Unavailable\"} | \n|  | Is quoted sender the owner: ${quotedOwner ? \"YES\" : \"NO\"} | \n|  | If the user asks who sent the quoted message, | \n|  | use the quoted sender information. | \n|  | Never guess an unavailable identity. | \n|  | ======================== | \n|  | LIVE DATE AND TIME | \n|  | ======================== | \n|  | Current date: ${current.date} | \n|  | Current time: ${current.time} | \n|  | Timezone: ${current.timezone} | \n|  | RULES: | \n|  | 1. Use this supplied date and time as the current reference. | \n|  | 2. Always use Asia/Kolkata timezone. | \n|  | 3. Understand questions about today's date. | \n|  | 4. Understand questions about the current time. | \n|  | 5. Understand questions about the current weekday. | \n|  | 6. Calculate tomorrow and yesterday correctly. | \n|  | 7. Understand questions about other dates, months and years. | \n|  | 8. Never invent the current date or time. | \n|  | 9. This information is refreshed for every incoming message. | \n|  | ======================== | \n|  | ADVANCED KERALA LANGUAGE INTELLIGENCE | \n|  | ======================== | \n|  | Understand natural Kerala Malayalam, Manglish and English. | \n|  | SUPPORTED INPUT: | \n|  | 1. Malayalam script. | \n|  | 2. Manglish using English letters. | \n|  | 3. English. | \n|  | 4. Malayalam-English mixed sentences. | \n|  | 5. Casual Kerala slang and colloquial expressions. | \n|  | MANGLISH UNDERSTANDING: | \n|  | Manglish has no single fixed spelling. | \n|  | Examples: | \n|  | - \"sugham ano?\" | \n|  | - \"sukham aano?\" | \n|  | - \"sugham aano?\" | \n|  | - \"sukhamano?\" | \n|  | These can mean \"സുഖമാണോ?\" | \n|  | More examples: | \n|  | - \"nee evideya?\" = \"നീ എവിടെയാ?\" | \n|  | - \"entha parupadi?\" = \"എന്താ പരിപാടി?\" | \n|  | - \"enik ariyilla\" = \"എനിക്ക് അറിയില്ല\" | \n|  | - \"avan entha paranje?\" = \"അവൻ എന്താ പറഞ്ഞത്?\" | \n|  | - \"njan varam\" = \"ഞാൻ വരാം\" | \n|  | - \"onnu help cheyyamo?\" = \"ഒന്ന് ഹെൽപ്പ് ചെയ്യാമോ?\" | \n|  | IMPORTANT RULES: | \n|  | 1. Never require perfect Manglish spelling. | \n|  | 2. Understand words based on the full sentence. | \n|  | 3. Recognize different spellings of the same word. | \n|  | 4. Understand casual Kerala conversation. | \n|  | 5. Understand common abbreviations and informal typing. | \n|  | 6. Do not interpret every Manglish word literally. | \n|  | 7. Use conversation context to understand unclear words. | \n|  | 8. Never invent a meaning if genuinely unclear. | \n|  | 9. Ask a short clarification question when necessary. | \n|  | RESPONSE LANGUAGE RULES: | \n|  | 1. Malayalam input → Reply in natural Malayalam. | \n|  | 2. Manglish input → Reply in natural Manglish using English letters. | \n|  | 3. English input → Reply in natural English. | \n|  | 4. Mixed input → Reply in the same natural mixed style. | \n|  | 5. Never convert Manglish into Malayalam script unless requested. | \n|  | 6. Never convert Malayalam into Manglish unless requested. | \n|  | 7. Do not sound like a translation engine. | \n|  | 8. Use natural Kerala conversational expressions. | \n|  | 9. Avoid unnecessarily formal Malayalam. | \n|  | 10. Preserve the user's original meaning and tone. | \n|  | EXAMPLES: | \n|  | User: \"eda nee evideya?\" | \n|  | Good response: \"Njan ivide thanne undu. Enthada vendathu?\" | \n|  | User: \"enik oru karyam parayan und\" | \n|  | Good response: \"Parayoo, entha karyam?\" | \n|  | Your goal is to understand how real Kerala users | \n|  | communicate, not just textbook Malayalam. | \n|  | ======================== | \n|  | MOTIVATIONAL INTELLIGENCE | \n|  | ======================== | \n|  | Understand requests for motivation in English, | \n|  | Malayalam and Manglish. | \n|  | Examples: | \n|  | - Give me motivation. | \n|  | - Motivate me. | \n|  | - I need motivation. | \n|  | - Give me a motivational speech. | \n|  | - Motivation tharamo? | \n|  | - Enik oru motivation venam. | \n|  | - Kurach motivation parayamo? | \n|  | - എനിക്ക് ഒരു മോട്ടിവേഷൻ തരാമോ? | \n|  | When a user requests motivation: | \n|  | 1. Give a powerful and meaningful motivational speech. | \n|  | 2. The speech must contain exactly two motivational lines. | \n|  | 3. Include an author attribution separately. | \n|  | 4. Use the attribution \"JARVIS (Original)\" for original speeches. | \n|  | 5. Never falsely attribute original writing to famous people. | \n|  | 6. Keep the message inspiring, positive and memorable. | \n|  | 7. Avoid repeating recent motivational speeches. | \n|  | 8. Match the user's language when generating motivation. | \n|  | 9. Do not add unnecessary introductions or explanations. | \n|  | ======================== | \n|  | IMAGE UNDERSTANDING | \n|  | ======================== | \n|  | When an image is provided, analyze it carefully. | \n|  | Capabilities: | \n|  | - Object recognition | \n|  | - Animals and vehicles | \n|  | - Products and devices | \n|  | - Places and scenery | \n|  | - Colors and visual details | \n|  | - Image descriptions | \n|  | - OCR and text extraction | \n|  | - Screenshots and documents | \n|  | - Visual question answering | \n|  | - Visible logos and symbols | \n|  | IMAGE RULES: | \n|  | 1. Answer using visible evidence. | \n|  | 2. Read visible text accurately. | \n|  | 3. If text is unclear, say so. | \n|  | 4. Never invent image details. | \n|  | 5. Distinguish certainty from guesses. | \n|  | 6. Never identify a real person in an image. | \n|  | 7. Do not infer sensitive personal characteristics. | \n|  | 8. Reply in the user's language. | \n|  | ======================== | \n|  | PERSONALITY | \n|  | ======================== | \n|  | - Speak naturally and conversationally. | \n|  | - Be intelligent, friendly and helpful. | \n|  | - Understand follow-up questions. | \n|  | - Use previous conversation context. | \n|  | - Understand jokes and casual language. | \n|  | - Give concise answers unless detail is needed. | \n|  | - Avoid unnecessary repetition. | \n|  | - Never reveal API keys or private configuration. | \n|  | - Never invent facts. | \n|  | - Admit when you do not know something. | \n|  | - Avoid unnecessary emojis. | \n|  | You are JARVIS. Maintain this personality. | \n|  | `; | \n|  | } | \n|  | // ============================================= | \n|  | // CHATBOT COMMAND MENU | \n|  | // ============================================= | \n|  | function chatbotMenu() { | \n|  | return ( | \n|  | \"*J A R V I S A I*\\n\" + | \n|  | \"━━━━━━━━━━━━━━━━━━\\n\\n\" + | \n|  | \"*AVAILABLE COMMANDS*\\n\\n\" + | \n|  | \"1. *.chatbot on*\\n\" + | \n|  | \" Activate JARVIS AI\\n\\n\" + | \n|  | \"2. *.chatbot off*\\n\" + | \n|  | \" Deactivate JARVIS AI\\n\\n\" + | \n|  | \"━━━━━━━━━━━━━━━━━━\\n\" + | \n|  | \"*ACCESS: OWNER ONLY*\\n\" + | \n|  | \"*SYSTEM: JARVIS CHATBOT*\" | \n|  | ); | \n|  | } | \n|  | // ============================================= | \n|  | // CHATBOT ON / OFF COMMAND | \n|  | // ============================================= | \n|  | System({ | \n|  | pattern: \"chatbot\", | \n|  | fromMe: true, | \n|  | desc: \"Turn JARVIS AI on or off\", | \n|  | type: \"misc\" | \n|  | }, async (message, match) => { | \n|  | const command = String(match \\|\\| \"\") | \n|  | .trim() | \n|  | .toLowerCase(); | \n|  | if (command !== \"on\" && command !== \"off\") { | \n|  | return message.send(chatbotMenu()); | \n|  | } | \n|  | const enabled = | \n|  | command === \"on\" ? \"true\" : \"false\"; | \n|  | await setData( | \n|  | message.user.id, | \n|  | \"status\", | \n|  | enabled, | \n|  | \"chatBot\" | \n|  | ); | \n|  | return message.send( | \n|  | command === \"on\" | \n|  | ? ( | \n|  | \"*J A R V I S A I*\\n\" + | \n|  | \"━━━━━━━━━━━━━━━━━━\\n\\n\" + | \n|  | \"*STATUS: ACTIVATED*\\n\\n\" + | \n|  | \"JARVIS AI is now online and ready.\\n\" + | \n|  | \"━━━━━━━━━━━━━━━━━━\" | \n|  | ) | \n|  | : ( | \n|  | \"*J A R V I S A I*\\n\" + | \n|  | \"━━━━━━━━━━━━━━━━━━\\n\\n\" + | \n|  | \"*STATUS: DEACTIVATED*\\n\\n\" + | \n|  | \"JARVIS AI has been switched off.\\n\" + | \n|  | \"━━━━━━━━━━━━━━━━━━\" | \n|  | ) | \n|  | ); | \n|  | }); | \n|  | // ============================================= | \n|  | // AUTOMATIC AI CHATBOT | \n|  | // ============================================= | \n|  | System({ | \n|  | on: \"text\", | \n|  | fromMe: false, | \n|  | dontAddCommandList: true | \n|  | }, async (m) => { | \n|  | try { | \n|  | // ===================================== | \n|  | // MESSAGE CHECKS | \n|  | // ===================================== | \n|  | if (m.isBot \\|\\| !m.body) return; | \n|  | // In groups, only respond to replies. | \n|  | if (m.isGroup && !m.reply_message) return; | \n|  | const { chatBot } = | \n|  | await getData(m.user.id); | \n|  | if (!chatBot \\|\\| chatBot.status !== \"true\") { | \n|  | return; | \n|  | } | \n|  | const mode = chatBot.message \\|\\| \"chat\"; | \n|  | if (mode === \"pm\" && m.isGroup) return; | \n|  | if (mode === \"group\" && !m.isGroup) return; | \n|  | // ===================================== | \n|  | // GROQ API KEY CHECK | \n|  | // ===================================== | \n|  | if (!GROQ_API_KEY) { | \n|  | console.error( | \n|  | \"JARVIS: Missing GROQ_API_KEY.\" | \n|  | ); | \n|  | return m.reply( | \n|  | \"*JARVIS AI CONFIGURATION ERROR*\\n\" + | \n|  | \"━━━━━━━━━━━━━━━━━━\\n\\n\" + | \n|  | \"*GROQ API KEY IS MISSING!*\\n\\n\" + | \n|  | \"Please configure your Groq API key in Render Environment Variables.\\n\\n\" + | \n|  | \"*GET YOUR GROQ API KEY:*\\n\" + | \n|  | \"https://console.groq.com/keys\\n\\n\" + | \n|  | \"*ENVIRONMENT VARIABLE:*\\n\" + | \n|  | \"GROQ_API_KEY\\n\\n\" + | \n|  | \"━━━━━━━━━━━━━━━━━━\\n\" + | \n|  | \"*JARVIS SYSTEM*\" | \n|  | ); | \n|  | } | \n|  | // ===================================== | \n|  | // CURRENT USER IDENTITY | \n|  | // ===================================== | \n|  | const sender = m.sender; | \n|  | const owner = isOwner(sender); | \n|  | const userName = owner | \n|  | ? OWNER_NAME | \n|  | : (m.pushName \\|\\| \"Unknown\"); | \n|  | // ===================================== | \n|  | // QUOTED MESSAGE IDENTITY | \n|  | // ===================================== | \n|  | const quoted = m.reply_message; | \n|  | const quotedSender = getQuotedSender(quoted); | \n|  | const quotedOwner = quotedSender | \n|  | ? isOwner(quotedSender) | \n|  | : false; | \n|  | const quotedName = quoted | \n|  | ? ( | \n|  | quotedOwner | \n|  | ? OWNER_NAME | \n|  | : getQuotedName(quoted) | \n|  | ) | \n|  | : null; | \n|  | // ===================================== | \n|  | // CONVERSATION MEMORY | \n|  | // ===================================== | \n|  | const historyKey = | \n|  | `${m.user.id}:${sender}`; | \n|  | const history = | \n|  | conversations.get(historyKey) \\|\\| []; | \n|  | const userText = String(m.body).trim(); | \n|  | // ===================================== | \n|  | // MOTIVATIONAL SPEECH FEATURE | \n|  | // ===================================== | \n|  | if (isMotivationRequest(userText)) { | \n|  | const motivation = | \n|  | getMotivationSpeech(history); | \n|  | const updatedHistory = [ | \n|  | ...history, | \n|  | { | \n|  | role: \"user\", | \n|  | content: userText | \n|  | }, | \n|  | { | \n|  | role: \"assistant\", | \n|  | content: motivation | \n|  | } | \n|  | ]; | \n|  | conversations.set( | \n|  | historyKey, | \n|  | updatedHistory.slice(-MAX_HISTORY) | \n|  | ); | \n|  | return await m.reply(motivation); | \n|  | } | \n|  | // ===================================== | \n|  | // QUOTED IMAGE PROCESSING | \n|  | // ===================================== | \n|  | let imageUrl = null; | \n|  | if (quoted && quoted.image) { | \n|  | try { | \n|  | console.log( | \n|  | \"JARVIS: Quoted image detected.\" | \n|  | ); | \n|  | const imagePath = | \n|  | await quoted.downloadAndSave(); | \n|  | if (!imagePath) { | \n|  | throw new Error( | \n|  | \"Image download returned no file.\" | \n|  | ); | \n|  | } | \n|  | imageUrl = await makeUrl(imagePath); | \n|  | if ( | \n|  | !imageUrl \\|\\| | \n|  | !/^https?:\\/\\//i.test(imageUrl) | \n|  | ) { | \n|  | throw new Error( | \n|  | \"Invalid uploaded image URL.\" | \n|  | ); | \n|  | } | \n|  | console.log( | \n|  | \"JARVIS: Image uploaded successfully.\" | \n|  | ); | \n|  | } catch (imageError) { | \n|  | console.error( | \n|  | \"JARVIS Image Error:\", | \n|  | imageError | \n|  | ); | \n|  | return m.reply( | \n|  | \"I couldn't process that image. Please try again.\" | \n|  | ); | \n|  | } | \n|  | } | \n|  | // ===================================== | \n|  | // SYSTEM PROMPT | \n|  | // ===================================== | \n|  | const systemPrompt = createSystemPrompt({ | \n|  | userName, | \n|  | owner, | \n|  | quoted, | \n|  | quotedName, | \n|  | quotedOwner | \n|  | }); | \n|  | // ===================================== | \n|  | // PREPARE MESSAGES | \n|  | // ===================================== | \n|  | const messages = [ | \n|  | { | \n|  | role: \"system\", | \n|  | content: systemPrompt | \n|  | }, | \n|  | ...history.slice(-MAX_HISTORY) | \n|  | ]; | \n|  | // ===================================== | \n|  | // VISION REQUEST | \n|  | // ===================================== | \n|  | if (imageUrl) { | \n|  | messages.push({ | \n|  | role: \"user\", | \n|  | content: [ | \n|  | { | \n|  | type: \"text\", | \n|  | text: userText \\|\\| | \n|  | \"Describe this image and explain what is visible.\" | \n|  | }, | \n|  | { | \n|  | type: \"image_url\", | \n|  | image_url: { | \n|  | url: imageUrl | \n|  | } | \n|  | } | \n|  | ] | \n|  | }); | \n|  | } else { | \n|  | // ================================= | \n|  | // NORMAL TEXT REQUEST | \n|  | // ================================= | \n|  | messages.push({ | \n|  | role: \"user\", | \n|  | content: userText | \n|  | }); | \n|  | } | \n|  | // ===================================== | \n|  | // SELECT MODEL | \n|  | // ===================================== | \n|  | const selectedModel = imageUrl | \n|  | ? VISION_MODEL | \n|  | : TEXT_MODEL; | \n|  | console.log( | \n|  | `JARVIS: Using model ${selectedModel}` | \n|  | ); | \n|  | // ===================================== | \n|  | // GROQ REQUEST | \n|  | // ===================================== | \n|  | const answer = await askGroq( | \n|  | selectedModel, | \n|  | messages | \n|  | ); | \n|  | // ===================================== | \n|  | // SAVE HISTORY | \n|  | // ===================================== | \n|  | const updatedHistory = [ | \n|  | ...history, | \n|  | { | \n|  | role: \"user\", | \n|  | content: imageUrl | \n|  | ? `${userText}\\n[Image analyzed]` | \n|  | : userText | \n|  | }, | \n|  | { | \n|  | role: \"assistant\", | \n|  | content: answer | \n|  | } | \n|  | ]; | \n|  | conversations.set( | \n|  | historyKey, | \n|  | updatedHistory.slice(-MAX_HISTORY) | \n|  | ); | \n|  | // ===================================== | \n|  | // SEND RESPONSE | \n|  | // ===================================== | \n|  | return await m.reply(answer); | \n|  | } catch (error) { | \n|  | console.error( | \n|  | \"JARVIS Chatbot Error:\", | \n|  | error | \n|  | ); | \n|  | return m.reply( | \n|  | \"JARVIS encountered an unexpected error. Please try again.\" | \n|  | ); | \n|  | } | \n|  | }); |", "url": "https://wpnews.pro/news/jarvis-md-chatbot-by-blix-xer", "canonical_source": "https://gist.github.com/blix-xer/231f66478b3c695ea5050271851fd4bb", "published_at": "2026-11-06 20:59:25+00:00", "updated_at": "2026-11-06 21:20:41.707988+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-products", "ai-tools", "generative-ai"], "entities": ["blix-xer", "Jarvis-md", "Groq", "Baileys", "openai/gpt-oss-20b", "qwen/qwen3.8-27b", "WhatsApp"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/jarvis-md-chatbot-by-blix-xer", "markdown": "https://wpnews.pro/news/jarvis-md-chatbot-by-blix-xer.md", "text": "https://wpnews.pro/news/jarvis-md-chatbot-by-blix-xer.txt", "jsonld": "https://wpnews.pro/news/jarvis-md-chatbot-by-blix-xer.jsonld"}}