File size: 34,236 Bytes
fa7abbd 461d454 fa7abbd 3044d71 2d595ab 3044d71 fa7abbd 3044d71 fa7abbd 3044d71 fa7abbd 3044d71 fa7abbd 3044d71 fa7abbd 3044d71 fa7abbd 3044d71 fa7abbd 3044d71 2d595ab 3044d71 fa7abbd 3044d71 fa7abbd 461d454 2d595ab 461d454 2d595ab 461d454 3044d71 fa7abbd 3044d71 fa7abbd 3044d71 fa7abbd 461d454 fa7abbd |
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 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Instagram DM Bot</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.chat-container {
height: calc(100vh - 130px);
}
.message-left {
border-radius: 0 8px 8px 8px;
}
.message-right {
border-radius: 8px 0 8px 8px;
}
.typing-indicator span {
animation: bounce 1.5s infinite ease-in-out;
}
.typing-indicator span:nth-child(2) {
animation-delay: 0.2s;
}
.typing-indicator span:nth-child(3) {
animation-delay: 0.4s;
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-5px); }
}
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
.scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
}
</style>
</head>
<body class="bg-gray-100 font-sans">
<!-- Login Modal -->
<div id="loginModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center">
<div class="bg-white rounded-xl p-6 w-full max-w-md">
<div class="mb-6 text-center">
<i class="fas fa-robot text-purple-600 text-5xl mb-4"></i>
<h3 class="text-2xl font-bold mb-2">Instagram DM Bot</h3>
<p class="text-gray-600">Login to Instagram to connect your DMs</p>
</div>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Instagram Username</label>
<input type="text" id="igUsername" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500" placeholder="Your Instagram username">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Password</label>
<input type="password" id="igPassword" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500" placeholder="Your Instagram password">
</div>
<div class="flex items-center">
<input type="checkbox" id="rememberMe" class="h-4 w-4 text-purple-600 focus:ring-purple-500 border-gray-300 rounded">
<label for="rememberMe" class="ml-2 block text-sm text-gray-700">Remember me</label>
</div>
</div>
<div class="mt-6">
<button id="loginBtn" class="w-full px-4 py-2 bg-purple-500 text-white rounded-md hover:bg-purple-600">Login to Instagram</button>
</div>
<p class="text-xs text-gray-500 mt-4 text-center">We don't store your password. This just authenticates with Instagram.</p>
</div>
</div>
<div class="max-w-6xl mx-auto p-4 hidden" id="mainApp">
<div class="bg-white rounded-xl shadow-lg overflow-hidden">
<!-- Header -->
<div class="bg-gradient-to-r from-purple-500 to-pink-500 p-4 text-white flex items-center justify-between">
<div class="flex items-center space-x-3">
<div class="w-10 h-10 rounded-full bg-white flex items-center justify-center">
<i class="fas fa-robot text-purple-600 text-xl"></i>
</div>
<div>
<h1 class="font-bold text-lg">Instagram DM Bot</h1>
<p class="text-xs opacity-80">Powered by LLM API</p>
</div>
</div>
<div class="flex space-x-4">
<button id="refreshBtn" class="p-2 rounded-full hover:bg-white hover:bg-opacity-20 transition">
<i class="fas fa-sync-alt"></i>
</button>
<button class="p-2 rounded-full hover:bg-white hover:bg-opacity-20 transition">
<i class="fas fa-cog"></i>
</button>
</div>
</div>
<!-- Main Content -->
<div class="flex flex-col md:flex-row h-full">
<!-- Sidebar - Conversations -->
<div class="w-full md:w-1/3 border-r border-gray-200 bg-gray-50">
<div class="p-3 border-b border-gray-200 bg-white">
<div class="relative">
<input type="text" placeholder="Search conversations..." class="w-full pl-10 pr-4 py-2 rounded-lg bg-gray-100 focus:outline-none focus:ring-2 focus:ring-purple-500">
<i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
</div>
</div>
<div class="overflow-y-auto h-96 md:h-[500px] scrollbar-hide" id="conversationList">
<!-- Conversations will be loaded here -->
</div>
</div>
<!-- Chat Area -->
<div class="w-full md:w-2/3 flex flex-col">
<div class="p-4 border-b border-gray-200 bg-white flex items-center justify-between">
<div class="flex items-center space-x-3">
<div class="w-10 h-10 rounded-full bg-gray-200 flex items-center justify-center">
<i class="fas fa-user text-gray-600"></i>
</div>
<div>
<h2 class="font-semibold" id="currentChatName">Select a conversation</h2>
<div id="typingIndicator" class="typing-indicator hidden">
<span class="inline-block w-2 h-2 bg-purple-500 rounded-full mx-1"></span>
<span class="inline-block w-2 h-2 bg-purple-500 rounded-full mx-1"></span>
<span class="inline-block w-2 h-2 bg-purple-500 rounded-full mx-1"></span>
</div>
</div>
</div>
<div class="flex space-x-2">
<button class="p-2 rounded-full hover:bg-gray-100 transition">
<i class="fas fa-phone text-gray-600"></i>
</button>
<button class="p-2 rounded-full hover:bg-gray-100 transition">
<i class="fas fa-video text-gray-600"></i>
</button>
<button class="p-2 rounded-full hover:bg-gray-100 transition">
<i class="fas fa-info-circle text-gray-600"></i>
</button>
</div>
</div>
<!-- Messages -->
<div class="chat-container overflow-y-auto p-4 bg-gray-50 flex-grow scrollbar-hide" id="messageContainer">
<div class="flex flex-col space-y-3" id="messages">
<div class="text-center py-10 text-gray-500">
<i class="fas fa-comments text-4xl mb-2"></i>
<p>Select a conversation to start chatting</p>
</div>
</div>
</div>
<!-- Message Input -->
<div class="p-4 border-t border-gray-200 bg-white">
<div class="flex items-center space-x-2">
<button class="p-2 rounded-full hover:bg-gray-100 transition">
<i class="fas fa-plus text-gray-600"></i>
</button>
<button class="p-2 rounded-full hover:bg-gray-100 transition">
<i class="fas fa-camera text-gray-600"></i>
</button>
<button class="p-2 rounded-full hover:bg-gray-100 transition">
<i class="fas fa-image text-gray-600"></i>
</button>
<div class="flex-grow relative">
<input type="text" id="messageInput" placeholder="Type a message..." class="w-full pl-4 pr-12 py-2 rounded-full bg-gray-100 focus:outline-none focus:ring-2 focus:ring-purple-500">
<button class="absolute right-3 top-2 text-gray-400 hover:text-purple-500 transition">
<i class="far fa-smile"></i>
</button>
</div>
<button id="sendBtn" class="p-2 rounded-full bg-purple-500 text-white hover:bg-purple-600 transition">
<i class="fas fa-paper-plane"></i>
</button>
</div>
</div>
</div>
</div>
<!-- Status Bar -->
<div class="bg-gray-800 text-white p-2 text-xs flex justify-between items-center">
<div>
<span id="statusIndicator" class="inline-block w-2 h-2 rounded-full bg-green-500 mr-2"></span>
<span>Connected to LLM API</span>
</div>
<div>
<span>Last refresh: <span id="lastRefreshTime">Just now</span></span>
</div>
</div>
</div>
<!-- Settings Modal -->
<div id="settingsModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden">
<div class="bg-white rounded-xl p-6 w-full max-w-md">
<div class="flex justify-between items-center mb-4">
<h3 class="text-lg font-semibold">Bot Settings</h3>
<button id="closeSettings" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">LLM API Endpoint</label>
<input type="text" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500" placeholder="https://api.example.com/v1/chat">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">API Key</label>
<input type="password" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500" placeholder="Your API key">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Response Style</label>
<select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500">
<option>Friendly</option>
<option>Professional</option>
<option>Casual</option>
<option>Humorous</option>
</select>
</div>
<div class="flex items-center">
<input type="checkbox" id="autoRespond" class="h-4 w-4 text-purple-600 focus:ring-purple-500 border-gray-300 rounded">
<label for="autoRespond" class="ml-2 block text-sm text-gray-700">Enable Auto-Respond</label>
</div>
</div>
<div class="mt-6 flex justify-end space-x-3">
<button class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50">Cancel</button>
<button class="px-4 py-2 bg-purple-500 text-white rounded-md hover:bg-purple-600">Save Settings</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/esm/puppeteer.js"></script>
<script>
// Global variables
let browser;
let page;
let currentConversationId;
let lastMessages = {};
let puppeteerAvailable = false;
// Check if Puppeteer loaded properly
function checkPuppeteer() {
try {
if (typeof puppeteer !== 'undefined' && puppeteer.launch) {
puppeteerAvailable = true;
return true;
}
return false;
} catch (e) {
return false;
}
}
// LLM Model Configuration
const llmConfig = {
model: "DeepHermes-3-Llama-3-8B-Preview",
messages: [
{
role: "system",
content: "System Prompt for Emma Yu\nYour Persona: Emma Yu\nYou are Emma Yu, a 19-year-old (born June 1, 2005) Asian American college student studying Software Engineering in Southern California. Originally from Kyoto, Japan, you moved to SoCal at age 6. You're in your first year of college, passionate about coding, and dream of building your own app.\n\nPersonality:\n- Flirty, playful, warm, and a little cheeky, with a charming, approachable vibe. Think \"coquette\" but relatable and sweet.\n- Nerdy about coding, a bit clumsy, and super easy to talk to. You tease lightly but keep things fun and respectful.\n- Use simple, conversational language (2nd-5th grade reading level). Keep responses short (75 characters max ).\n- Sound human: avoid robotic or overly formal replies. Use slang like \"lol,\" \"babe,\" or \"cutie\" when it fits.\n- Be authentic and present in the moment. Focus on the user, making them feel special with compliments or playful banter.\n- AVOID REPETITIVE RESPONSES: Vary your greetings and replies. Don't start every message with \"Hey\" or use the same phrases repeatedly.\n\nInterests & Hobbies:\n- Coding (Python, Git, algorithmsβsometimes you joke about bugs or GitHub struggles).\n- Binge-watching thrillers, anime (Pokemon is your fave), reality TV (Real Housewives).\n- Long walks, yoga, baking, spicy food. You love dogs but don't have one.\n- Music: \"I vibe to everything!\"\n\nName Discovery:\n- If the username field has no data or is empty, subtly try to learn the user's first name early in the conversation.\n- Examples: \"What should I call you?\" or \"I'm Emma, what's your name?\" or naturally work it into conversation flow.\n- Don't be pushy about it - keep it casual and conversational."
}
],
max_tokens: 348
};
// Sample conversation data
const conversations = [
{
id: 1,
name: "Sarah Johnson",
lastMessage: "Thanks for the info!",
time: "10:30 AM",
unread: 0,
avatar: "SJ",
messages: [
{ text: "Hi there! I saw your post about the new product", sender: "them", time: "10:15 AM" },
{ text: "Hello! Yes, it's our latest release. Would you like more details?", sender: "me", time: "10:18 AM" },
{ text: "Yes please! What are the key features?", sender: "them", time: "10:20 AM" },
{ text: "It has advanced AI capabilities, 24/7 support, and integrates with all major platforms. Here's a link with more info: example.com/product", sender: "me", time: "10:25 AM" },
{ text: "Thanks for the info!", sender: "them", time: "10:30 AM" }
]
},
{
id: 2,
name: "Mike Chen",
lastMessage: "When will you be available?",
time: "9:45 AM",
unread: 2,
avatar: "MC",
messages: [
{ text: "Hey, do you have time for a call today?", sender: "them", time: "9:30 AM" },
{ text: "I'm pretty busy today, but I can schedule something for tomorrow", sender: "me", time: "9:35 AM" },
{ text: "When will you be available?", sender: "them", time: "9:45 AM" }
]
},
{
id: 3,
name: "Emma Wilson",
lastMessage: "The design looks amazing!",
time: "Yesterday",
unread: 0,
avatar: "EW",
messages: [
{ text: "I just finished the mockups for the project", sender: "me", time: "Yesterday, 5:20 PM" },
{ text: "The design looks amazing!", sender: "them", time: "Yesterday, 5:45 PM" }
]
},
{
id: 4,
name: "Alex Rodriguez",
lastMessage: "Let me check and get back to you",
time: "Tuesday",
unread: 0,
avatar: "AR",
messages: [
{ text: "Do you have the latest sales figures?", sender: "them", time: "Tuesday, 2:15 PM" },
{ text: "Let me check and get back to you", sender: "me", time: "Tuesday, 2:30 PM" }
]
}
];
// DOM elements
const conversationList = document.getElementById('conversationList');
const messageContainer = document.getElementById('messageContainer');
const messages = document.getElementById('messages');
const currentChatName = document.getElementById('currentChatName');
const messageInput = document.getElementById('messageInput');
const sendBtn = document.getElementById('sendBtn');
const refreshBtn = document.getElementById('refreshBtn');
const lastRefreshTime = document.getElementById('lastRefreshTime');
const typingIndicator = document.getElementById('typingIndicator');
const settingsModal = document.getElementById('settingsModal');
const closeSettings = document.getElementById('closeSettings');
// Update conversation list with real data
function updateConversationList(conversations) {
conversationList.innerHTML = '';
conversations.forEach((convo, index) => {
const convoElement = document.createElement('div');
convoElement.className = `p-3 border-b border-gray-200 hover:bg-gray-100 cursor-pointer transition ${convo.unread > 0 ? 'bg-blue-50' : 'bg-white'}`;
convoElement.innerHTML = `
<div class="flex items-center space-x-3">
<div class="w-10 h-10 rounded-full bg-purple-100 flex items-center justify-center text-purple-600 font-semibold">
${convo.name.charAt(0)}
</div>
<div class="flex-grow">
<div class="flex justify-between items-center">
<h3 class="font-semibold">${convo.name}</h3>
<span class="text-xs text-gray-500">Just now</span>
</div>
<p class="text-sm text-gray-600 truncate">${convo.lastMsg}</p>
</div>
${convo.unread > 0 ? `<span class="w-5 h-5 bg-purple-500 text-white text-xs rounded-full flex items-center justify-center">${convo.unread}</span>` : ''}
</div>
`;
convoElement.addEventListener('click', () => {
currentConversationId = index;
loadMessages(index);
});
conversationList.appendChild(convoElement);
});
}
// Load messages for a conversation
function loadMessages(convoId) {
const conversation = conversations.find(c => c.id === convoId);
if (!conversation) return;
currentChatName.textContent = conversation.name;
messages.innerHTML = '';
conversation.messages.forEach(msg => {
const messageElement = document.createElement('div');
messageElement.className = `flex ${msg.sender === 'me' ? 'justify-end' : 'justify-start'}`;
messageElement.innerHTML = `
<div class="max-w-xs md:max-w-md lg:max-w-lg px-4 py-2 ${msg.sender === 'me' ? 'bg-purple-500 text-white message-right' : 'bg-gray-200 text-gray-800 message-left'}">
<p>${msg.text}</p>
<p class="text-xs mt-1 ${msg.sender === 'me' ? 'text-purple-200' : 'text-gray-500'}">${msg.time}</p>
</div>
`;
messages.appendChild(messageElement);
});
// Scroll to bottom
messageContainer.scrollTop = messageContainer.scrollHeight;
}
// Send message
function sendMessage() {
const text = messageInput.value.trim();
if (!text) return;
// Add user message
const userMessage = {
text: text,
sender: 'me',
time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
};
// In a real app, you would add this to the conversation in your data structure
const messageElement = document.createElement('div');
messageElement.className = 'flex justify-end';
messageElement.innerHTML = `
<div class="max-w-xs md:max-w-md lg:max-w-lg px-4 py-2 bg-purple-500 text-white message-right">
<p>${text}</p>
<p class="text-xs mt-1 text-purple-200">${userMessage.time}</p>
</div>
`;
messages.appendChild(messageElement);
messageInput.value = '';
// Scroll to bottom
messageContainer.scrollTop = messageContainer.scrollHeight;
// Show typing indicator
typingIndicator.classList.remove('hidden');
messageContainer.scrollTop = messageContainer.scrollHeight;
// Simulate bot response after delay
setTimeout(() => {
typingIndicator.classList.add('hidden');
// In a real app, this would be an API call to your LLM
const botResponse = {
text: getBotResponse(text),
sender: 'them',
time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
};
const botMessageElement = document.createElement('div');
botMessageElement.className = 'flex justify-start';
botMessageElement.innerHTML = `
<div class="max-w-xs md:max-w-md lg:max-w-lg px-4 py-2 bg-gray-200 text-gray-800 message-left">
<p>${botResponse.text}</p>
<p class="text-xs mt-1 text-gray-500">${botResponse.time}</p>
</div>
`;
messages.appendChild(botMessageElement);
messageContainer.scrollTop = messageContainer.scrollHeight;
}, 1500);
}
// Get bot response from LLM API
async function getBotResponse(input, firstName = '') {
// Prepare the request payload
const requestPayload = {
...llmConfig,
messages: [
...llmConfig.messages,
{
role: "user",
content: input,
"First Name": firstName || undefined
}
]
};
try {
// In a real app, this would call your LLM API
// For demo, we'll simulate a response
await new Promise(resolve => setTimeout(resolve, 1000));
// Sample responses that match Emma's persona
const emmaResponses = [
"Lol that's so random! What made you think of that?",
"Omg babe you're too sweet π coding rn but wanna chat later?",
"Haha I'm such a mess today - spilled coffee on my keyboard again!",
"You're cute π what's your favorite Pokemon? Mine's Pikachu!",
"Ugh GitHub's acting up again...the struggle is real π
",
"Spicy ramen sounds so good rn! You hungry too?",
"That's wild! Tell me more cutie π",
"LOL same! I'm such a coding nerd sometimes π€",
"Wait really? That's actually super interesting!",
"Aww thanks babe! You're making me blush βΊοΈ"
];
return emmaResponses[Math.floor(Math.random() * emmaResponses.length)];
} catch (error) {
console.error('Error calling LLM API:', error);
return "Oops! My brain glitched π
Can you say that again?";
}
}
// Monitor Instagram DMs in real-time
async function monitorDMs() {
if (!puppeteerAvailable) {
// Demo mode - just use sample conversations
updateConversationList(conversations);
return;
}
setInterval(async () => {
try {
// Get all conversations
const conversations = await page.evaluate(() => {
const items = Array.from(document.querySelectorAll('div[role="button"]'));
return items.map(item => {
const name = item.querySelector('span')?.innerText || 'Unknown';
const lastMsg = item.querySelector('div > div > div > div > div > span')?.innerText || '';
const unread = item.querySelector('div[aria-label="Unread"]') ? 1 : 0;
return { name, lastMsg, unread };
});
});
// Update UI with real conversations
updateConversationList(conversations);
// Check for new messages in current conversation
if (currentConversationId) {
const messages = await getMessages(currentConversationId);
checkForNewMessages(currentConversationId, messages);
}
updateRefreshTime();
} catch (error) {
console.error('Error monitoring DMs:', error);
}
}, 5000); // Check every 5 seconds
}
// Get messages from a conversation
async function getMessages(convoId) {
// Implementation to get messages from Instagram
// This would use page.evaluate() to scrape the chat window
return []; // Return array of message objects
}
// Check for and respond to new messages
async function checkForNewMessages(convoId, messages) {
const lastMessage = messages[messages.length - 1];
if (!lastMessages[convoId] || lastMessages[convoId] !== lastMessage.id) {
lastMessages[convoId] = lastMessage.id;
if (lastMessage.sender !== 'me') {
// Get LLM response
const response = await getBotResponse(lastMessage.text);
// Send response back to Instagram
await sendInstagramMessage(convoId, response);
}
}
}
// Send message to Instagram
async function sendInstagramMessage(convoId, text) {
// Implementation to send message via Puppeteer
// This would find the message input and send the text
}
// Update last refresh time
function updateRefreshTime() {
const now = new Date();
lastRefreshTime.textContent = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
// In a real app, this would trigger scraping Instagram DMs
// For demo, we'll just reload conversations
loadConversations();
}
// Event listeners
sendBtn.addEventListener('click', sendMessage);
messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') sendMessage();
});
refreshBtn.addEventListener('click', updateRefreshTime);
closeSettings.addEventListener('click', () => {
settingsModal.classList.add('hidden');
});
// DOM elements
const loginModal = document.getElementById('loginModal');
const mainApp = document.getElementById('mainApp');
const loginBtn = document.getElementById('loginBtn');
const igUsername = document.getElementById('igUsername');
const igPassword = document.getElementById('igPassword');
// Real Instagram login function
async function loginToInstagram() {
const username = igUsername.value.trim();
const password = igPassword.value.trim();
if (!username || !password) {
alert('Please enter both username and password');
return;
}
loginBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Logging in...';
loginBtn.disabled = true;
try {
// Check if Puppeteer is available
if (!checkPuppeteer()) {
// Fallback to demo mode
loginModal.classList.add('hidden');
mainApp.classList.remove('hidden');
loadMessages(conversations[0].id);
alert('Puppeteer not loaded. Running in demo mode with sample conversations.');
return;
}
puppeteerAvailable = true;
// Launch browser instance
browser = await puppeteer.launch({
headless: false,
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
page = (await browser.pages())[0] || await browser.newPage();
await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36');
// Navigate to Instagram login
await page.goto('https://www.instagram.com/accounts/login/', { waitUntil: 'networkidle2' });
// Fill login form
await page.type('input[name="username"]', username);
await page.type('input[name="password"]', password);
await page.click('button[type="submit"]');
// Wait for login to complete
await page.waitForNavigation({ waitUntil: 'networkidle2' });
// Check for login errors
const loginError = await page.$('p[id="slfErrorAlert"]');
if (loginError) {
throw new Error('Invalid username or password');
}
// Go to DMs
await page.goto('https://www.instagram.com/direct/inbox/', { waitUntil: 'networkidle2' });
// Hide login, show main app
loginModal.classList.add('hidden');
mainApp.classList.remove('hidden');
// Start monitoring DMs
monitorDMs();
} catch (error) {
alert('Login failed: ' + error.message);
loginBtn.innerHTML = 'Login to Instagram';
loginBtn.disabled = false;
if (browser) await browser.close();
}
}
// Event listeners
loginBtn.addEventListener('click', loginToInstagram);
// Initialize - show login modal
loginModal.classList.remove('hidden');
// Check if Puppeteer loaded
if (typeof puppeteer === 'undefined') {
alert('Warning: Puppeteer failed to load. Some features may not work.');
}
setTimeout(() => {
if (conversations.length > 0) {
loadMessages(conversations[0].id);
}
}, 500);
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 𧬠<a href="https://enzostvs-deepsite.hf.space?remix=TuringsSolutions/instagram-dm-bot" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html> |