// ==UserScript==
// @name Instagram Chat Bot
// @namespace https://github.com/swempish
// @version 1.0.6
// @description A script that adds a side panel to Instagram's DM section. Activates an AI-powered bot to automatically reply to incoming messages.
// @author Emirhan Çolak
// @match https://www.instagram.com/direct/t/*
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// @license GPL-3.0
// @require https://code.jquery.com/jquery-3.7.1.slim.min.js
// ==/UserScript==
// Side panel element (Start bot button)
var panelElement = `
<div style="
justify-content: center;
display: flex;
flex-direction: column;
text-align: center;
padding: 1rem;
gap: 1rem;
">
<h2>Insta Chat Bot Utilz</h2>
<button id="startTheBot" style="
min-height: 2rem;
max-width: 14rem;
margin: auto;
width: 100%;
cursor: pointer;
">Start the Bot!</button>
<div style="
border-style: outset;
border-color: brown;
background-color: rgb(66,66,66);
text-align: left;
padding: 0 .2rem 0 .2rem;
font-family: monospace;
font-size: x-small;
word-break: break-all;
overflow-x: hidden;
overflow-y: auto;
max-height: 8rem;
height: 100%;
display: none;
" id="botLogChat">
<p>Log</p>
</div>
</div>
`;
const injectCSS = css => {
let el = document.createElement('style');
el.type = 'text/css';
el.innerText = css;
document.head.appendChild(el);
return el;
};
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var personalities = [
'Your name is Emirhan. You are talking to someone in Instagram. Reply to them.' // Put here your personality prompt
]
const GEMINI_API_KEY = "YOUR-GEMINI-API-KEY";
const GEMINI_API_URL = `https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${GEMINI_API_KEY}`;
var bot_config = {
contents: [
{
role: "user",
parts: [{ text: personalities[0] }]
},
{
role: "model",
parts: [{ text: "Okay." }]
},
],
"safetySettings": [
{
category: "HARM_CATEGORY_HARASSMENT",
threshold: "BLOCK_NONE"
},
{
category: "HARM_CATEGORY_HATE_SPEECH",
threshold: "BLOCK_NONE"
},
{
category: "HARM_CATEGORY_SEXUALLY_EXPLICIT",
threshold: "BLOCK_NONE"
},
{
category: "HARM_CATEGORY_DANGEROUS_CONTENT",
threshold: "BLOCK_NONE"
},
]
}
async function generate_ai_response(input) {
// Provide time information to the bot
//save_message("*** SYSTEM MESSAGE *** Time: " + new Date().toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' }) + " Date: " + new Date().toLocaleDateString() + " Day of the week: " + days[new Date().getDay()], "user");
//save_message("*** DATE AND TIME RECORDED ***", "model");
save_message(input, "user");
const response = await fetch(GEMINI_API_URL, {
method: "POST",
body: JSON.stringify(bot_config),
});
const result = await response.json();
save_message(result["candidates"][0]["content"]["parts"][0]["text"], "model");
return String(result["candidates"][0]["content"]["parts"][0]["text"]);
}
function save_message(message, role) {
bot_config["contents"].push({ role: role, parts: [{ text: message }] });
}
var lastSentMessage = "---------------";
var generatingResponse = false;
var lastChatContent = "";
var isButtonAvailable = false;
function main() {
// Add the start bot button
if(!isButtonAvailable){
document.querySelector("main > section > div > div > div > div > div > div > div > div:nth-child(2) > div > div > div > div > div:nth-child(2)").innerHTML = panelElement + document.querySelector("main > section > div > div > div > div > div > div > div > div:nth-child(2) > div > div > div > div > div:nth-child(2)").innerHTML;
isButtonAvailable = true;
}
var chatContainer = document.querySelector("main > section > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div:nth-child(3) > div");
var sendButton = document.querySelector("main > section > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div:nth-child(2) > div > div > div:nth-child(3)");
document.querySelector("#startTheBot").addEventListener("click", function () {
var inputPlaceholderElement = document.querySelector("main > section > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div > div:nth-child(2) > div > div > div > div > div:nth-child(2)");
inputPlaceholderElement.innerText = "Controlled by the bot...";
$("#botLogChat").show();
logBot("Starting the bot...");
injectCSS('*{--messenger-card-background: rgb(34 113 120);}');
lastChatContent = chatContainer.innerHTML;
// Create a new interval that will check chatContainer's innerHTML and if it changes, generate a response
var elementTesterInterval = setInterval(async () => {
if (!generatingResponse && chatContainer.innerHTML != lastChatContent) {
var chatSize = chatContainer.childNodes.length;
var lastMessage = "";
for (let index = 1; index < chatContainer.childNodes[chatSize - 2].getElementsByTagName("span").length; index++) {
lastMessage += chatContainer.childNodes[chatSize - 2].getElementsByTagName("span")[index].innerText + " ";
}
var whoSent = chatContainer.childNodes[chatSize - 2].getElementsByTagName("span")[0].innerText == "You sent" ? "yourself" : "other";
if (generatingResponse || whoSent == "yourself") {
return;
}
logBot("Got message from user. Waiting for AI response...");
generatingResponse = true;
var response = await generate_ai_response(lastMessage);
logBot(`Got the response: ${response.slice(0, 30) + "..."}`);
lastSentMessage = response;
typeAndSend(response, sendButton);
}
}, 100);
var observer = new MutationObserver(function (mutations) {
// Iterate over each mutation record
mutations.forEach(async function (mutation) {
if (mutation.type === 'childList') {
}
});
});
// Configure the observer to observe changes in childList
var config = { childList: true };
// Start observing the chat container element
observer.observe(chatContainer, config);
});
}
async function typeAndSend(text, sendButton) {
// Insert text character by character so it looks like someone is typing. Max duration is 1 second
// This is to simulate human typing
for (var i = 0; i < text.length; i++) {
document.execCommand('insertText', false, text.charAt(i));
await new Promise(r => setTimeout(r, 100));
}
// Wait for 1 second
await new Promise(r => setTimeout(r, 100));
sendButton.click();
generatingResponse = false;
await new Promise(r => setTimeout(r, 100));
inputPlaceholderElement.innerText = "Controlled by the bot...";
}
// Log to chat div. Put logs to bottom
function logBot(text) {
document.querySelector("#botLogChat").innerHTML += "<p>" + text + "</p>";
document.querySelector("#botLogChat").scrollTop = document.querySelector("#botLogChat").scrollHeight;
}
$(document).ready(function () {
var elementTesterInterval = setInterval(() => {
if (document.querySelector("main > section > div > div > div > div > div > div > div > div:nth-child(2) > div > div > div > div > div:nth-child(2)")) {
clearInterval(elementTesterInterval);
main();
}
}, 1000);
});