commit 223bac0b62d9ab54e6b3e5052a2835dfad1d8b79 Author: Killian Date: Thu Aug 27 15:54:50 2020 +0200 First commit diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..44639e8 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +BOTUSERNAME=Your bot account username +PASSWORD=Your bot account password \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d296706 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.env +node_modules/ +package-lock.json \ No newline at end of file diff --git a/Commands/Bot/ping.js b/Commands/Bot/ping.js new file mode 100644 index 0000000..cb29052 --- /dev/null +++ b/Commands/Bot/ping.js @@ -0,0 +1,20 @@ +const Command = require("../../Structure/Command.js"); + +module.exports = class extends Command { + constructor(client) { + super(client, { + name: "ping", + description: "Return the bot ping (just a test command for now until the real ping is added)", + category: "Bot", + enabled: true, + aliases: ["latency"], + cooldown: 3, + dmOnly: false, + }); + } + + async run(message, args) { + message.chat.sendMessage(`Hey, my name is ${this.client.user.fullName} and i am an instagram bot.`); + } +} + diff --git a/Events/connected.js b/Events/connected.js new file mode 100644 index 0000000..1cffda9 --- /dev/null +++ b/Events/connected.js @@ -0,0 +1,14 @@ +module.exports = class { + constructor(client) { + this.client = client; + } + + async emit() { + this.client.logger.log(`Logged in as ${this.client.user.fullName} (${this.client.user.username}).`, "ready"); + this.client.logger.log(`Followers: ${this.client.user.followerCount}`, "ready") + this.client.logger.log(`Following: ${this.client.user.followingCount}`, "ready") + this.client.logger.log(`Business : ${this.client.user.isBusiness}`, "ready") + this.client.logger.log(`Verified: ${this.client.user.isVerified}`, "ready") + this.client.logger.log(`Private: ${this.client.user.isPrivate}`, "ready") + } +} diff --git a/Events/followRequest.js b/Events/followRequest.js new file mode 100644 index 0000000..0f35b0b --- /dev/null +++ b/Events/followRequest.js @@ -0,0 +1,10 @@ +module.exports = class { + constructor(client) { + this.client = client; + } + + async emit(user) { + console.log(`${user.fullName} (${username}) wants to follow you.`) + user.approveFollow(); + } +} diff --git a/Events/messageCreate.js b/Events/messageCreate.js new file mode 100644 index 0000000..476656e --- /dev/null +++ b/Events/messageCreate.js @@ -0,0 +1,51 @@ +const Collection = require("@discordjs/collection"); + +module.exports = class { + constructor(client) { + this.client = client; + } + + async emit(message) { + if (message.authorID === this.client.user.id) return; + message.markSeen(); + + let prefixes = this.client.config.defaultPrefix; + if (message.content.indexOf(prefixes) !== 0) return; + let args = message.content.slice(prefixes.length).trim().split(/ +/g); + let command = args.shift().toLowerCase(); + let cmd = + this.client.commands.get(command) || + this.client.commands.get(this.client.aliases.get(command)); + if (!cmd) return; + + this.client.logger.log(`${message.author.username} (${message.authorID}) ran command ${cmd.help.name}`, "cmd") + + if (!cmd.conf.enabled) { + return message.chat.sendMessage("Sorry this command is disabled."); + } + if (cmd.conf.dmOnly && message.chat.isGroup) { + return message.chat.sendMessage("Sorry this command is usable only in a private conversation."); + } + + if (!this.client.cooldowns.has(cmd.help.name)) { + this.client.cooldowns.set(cmd.help.name, new Collection()); + }; + + let timeNow = Date.now(); + let tStamps = this.client.cooldowns.get(cmd.help.name); + let cdAmount = (cmd.help.cooldown || 3) * 1000; + + if (tStamps.has(message.authorID)) { + let cdExpirationTime = tStamps.get(message.authorID) + cdAmount; + if (timeNow < cdExpirationTime) { + let timeLeft = (cdExpirationTime - timeNow) / 1000; + return message.chat.sendMessage(`Please wait ${timeLeft.toFixed(0)} seconds to use the command ${cmd.help.name} again`); + }; + }; + + tStamps.set(message.authorID, timeNow); + setTimeout(() => tStamps.delete(message.authorID), cdAmount); + + cmd.run(message, args); + } +} diff --git a/Events/messageDelete.js b/Events/messageDelete.js new file mode 100644 index 0000000..ae40947 --- /dev/null +++ b/Events/messageDelete.js @@ -0,0 +1,10 @@ +module.exports = class { + constructor(client) { + this.client = client; + } + + async emit(cachedMessage) { + if (!cachedMessage) return; + console.log(`@${cachedMessage.author.username} has just deleted their message: ${cachedMessage.content}`); + } +} diff --git a/Events/newFollower.js b/Events/newFollower.js new file mode 100644 index 0000000..0a54bae --- /dev/null +++ b/Events/newFollower.js @@ -0,0 +1,10 @@ +module.exports = class { + constructor(client) { + this.client = client; + } + + async emit(user) { + console.log(`${user.fullName} (${username}) started following you.`) + user.follow(); + } +} diff --git a/Events/pendingRequest.js b/Events/pendingRequest.js new file mode 100644 index 0000000..8ac20c4 --- /dev/null +++ b/Events/pendingRequest.js @@ -0,0 +1,9 @@ +module.exports = class { + constructor(client) { + this.client = client; + } + + async emit(chat) { + chat.approve(); + } +} diff --git a/Helpers/logger.js b/Helpers/logger.js new file mode 100644 index 0000000..d0754d5 --- /dev/null +++ b/Helpers/logger.js @@ -0,0 +1,46 @@ +const { bgBlue, black, green } = require("chalk"); + +function dateTimePad(value, digits){ + let number = value + while (number.toString().length < digits) { + number = "0" + number + } + return number; +} + +function format(tDate){ + return (tDate.getFullYear() + "-" + + dateTimePad((tDate.getMonth() + 1), 2) + "-" + + dateTimePad(tDate.getDate(), 2) + " " + + dateTimePad(tDate.getHours(), 2) + ":" + + dateTimePad(tDate.getMinutes(), 2) + ":" + + dateTimePad(tDate.getSeconds(), 2) + "." + + dateTimePad(tDate.getMilliseconds(), 3)) +} + +module.exports = class Logger { + static log (content, type = "log") { + const date = `[${format(new Date(Date.now()))}]:`; + switch (type) { + case "log": { + return console.log(`${date} ${bgBlue(type.toUpperCase())} ${content} `); + } + case "warn": { + return console.log(`${date} ${black.bgYellow(type.toUpperCase())} ${content} `); + } + case "error": { + return console.log(`${date} ${black.bgRed(type.toUpperCase())} ${content} `); + } + case "debug": { + return console.log(`${date} ${green(type.toUpperCase())} ${content} `); + } + case "cmd": { + return console.log(`${date} ${black.bgWhite(type.toUpperCase())} ${content}`); + } + case "ready": { + return console.log(`${date} ${black.bgGreen(type.toUpperCase())} ${content}`); + } + default: throw new TypeError("Logger type must be either warn, debug, log, ready, cmd or error."); + } + } +}; \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..2ef64dd --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# Instagram Bot +### An instgram bot using the insta.js package from Androz2091 + +Here is how you can install and use it + +- Open a command prompt +- Go to the folder you want using +```bash +cd C:\path\to\the\folder\you\want\ +``` + +- Clone this repository + +```bash +git clone https://github.com/Mr-KayJayDee/instagram-bot +``` + +- Go to the folder where the bot is cloned + +```bash +cd instagram-bot +``` + - Install all dependencies + +```bash +npm i +``` + +- Rename the .env.example file to .env and fill it with your informations + +- Start the bot + +```bash +npm start +``` + +When you see something like that + +``` +Logged in as Full Name (username). +Followers: 67 +Following: 57 +Business : true +Verified: false +Private: false +``` +it means that the bot is ready to be used. 🎉 \ No newline at end of file diff --git a/Structure/Client.js b/Structure/Client.js new file mode 100644 index 0000000..6d70ace --- /dev/null +++ b/Structure/Client.js @@ -0,0 +1,48 @@ +const { Client } = require("@androz2091/insta.js"), +Collection = require("@discordjs/collection") +path = require("path"); + +class InstaBot extends Client { + constructor(options) { + super(options); + ["commands", "aliases", "cooldowns"].forEach(x => this[x] = new Collection()); + this.config = require("../config"); + this.logger = require("../Helpers/logger"); + } + + loadCommand(commandPath, commandName) { + try { + const props = new (require(`.${commandPath}${path.sep}${commandName}`))(this); + props.conf.location = commandPath; + if (props.init){ + props.init(this); + } + this.commands.set(props.help.name, props); + props.conf.aliases.forEach((alias) => { + this.aliases.set(alias, props.help.name); + }); + return false; + } catch (e) { + return `Unable to load command ${commandName}: ${e}`; + } + } + + async unloadCommand (commandPath, commandName) { + let command; + if(this.commands.has(commandName)) { + command = this.commands.get(commandName); + } else if(this.aliases.has(commandName)){ + command = this.commands.get(this.aliases.get(commandName)); + } + if(!command){ + return `The command \`${commandName}\` doesn't seem to exist, nor is it an alias. Try again!`; + } + if(command.shutdown){ + await command.shutdown(this); + } + delete require.cache[require.resolve(`.${commandPath}${path.sep}${commandName}.js`)]; + return false; + } +} + +module.exports = InstaBot; \ No newline at end of file diff --git a/Structure/Command.js b/Structure/Command.js new file mode 100644 index 0000000..d653141 --- /dev/null +++ b/Structure/Command.js @@ -0,0 +1,26 @@ +module.exports = class Command { + constructor( + client, { + name = null, + description = null, + category = null, + cooldown = 3, + enabled = false, + aliases = new Array(), + dmOnly = false, + } + ) { + this.client = client; + this.help = { + name, + description, + category, + }; + this.conf = { + cooldown, + enabled, + aliases, + dmOnly, + } + } +} \ No newline at end of file diff --git a/config.js b/config.js new file mode 100644 index 0000000..07fcac3 --- /dev/null +++ b/config.js @@ -0,0 +1,3 @@ +module.exports = { + defaultPrefix: `!`, +} \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..f547392 --- /dev/null +++ b/index.js @@ -0,0 +1,30 @@ +const InstaBot = require("./Structure/Client"), + client = new InstaBot(); + +const util = require("util"), + fs = require("fs"), + readdir = util.promisify(fs.readdir); +require("dotenv").config(); + +const initialize = async () => { + let directories = await readdir("./Commands/"); + directories.forEach(async (dir) => { + let commands = await readdir("./Commands/" + dir + "/"); + commands.filter((cmd) => cmd.split(".").pop() === "js").forEach((cmd) => { + const response = client.loadCommand("./Commands/" + dir, cmd); + if (response) { + client.logger.log(response, "error"); + } + }); + }); + + const evtFiles = await readdir("./Events/"); + evtFiles.forEach((file) => { + const eventName = file.split(".")[0]; + const event = new (require(`./Events/${file}`))(client); + client.on(eventName, (...args) => event.emit(...args)); + delete require.cache[require.resolve(`./Events/${file}`)]; + }); + client.login(process.env.BOTUSERNAME, process.env.PASSWORD); +}; +initialize(); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..5555b4c --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "instabot", + "version": "1.0.0", + "description": "A fully working instagram bot using Insta.js by androz2091", + "main": "index.js", + "scripts": { + "start": "node index.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Mr¤KayJayDee (https://github.com/Mr-KayJayDee)", + "license": "MIT", + "dependencies": { + "@androz2091/insta.js": "github:androz2091/insta.js", + "@discordjs/collection": "^0.1.6", + "chalk": "^4.1.0", + "dotenv": "^8.2.0" + } +}