mirror of
				https://gitlab.com/ceda_ei/Quadnite-Bot
				synced 2025-10-31 01:00:05 +01:00 
			
		
		
		
	Compare commits
	
		
			57 Commits
		
	
	
		
			45b613ca9b
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7cf9689420 | |||
| e3a5f1a67b | |||
| cd374090f2 | |||
|  | 8274ab0980 | ||
| 80a0dbd2d3 | |||
| 41ae943913 | |||
| bdf52331b1 | |||
| 5ededd535f | |||
| 21871c9cd6 | |||
| c01ad5109d | |||
| 5f7f1ced01 | |||
| d844ac8455 | |||
| 69448a1052 | |||
| f44d83c89a | |||
| ae21f68cc7 | |||
| 4b8aecf28a | |||
| f1740ce4c0 | |||
| 5ac1c1e4a6 | |||
| ce9611f079 | |||
| 7527fb6a1a | |||
| 159ca9e87d | |||
| 4878274656 | |||
| f0a918f77e | |||
| 463d9c254b | |||
| fde5830309 | |||
| 71e6f6927d | |||
| 6da0e12171 | |||
| b0eff87e72 | |||
| 9024ec65f9 | |||
| 53dda834f9 | |||
| af56ffbbb3 | |||
| 382579ba3f | |||
| 8f16112b2e | |||
| 72e69b7ac1 | |||
| 3ed015b584 | |||
| 2914321b3c | |||
| 375f032b97 | |||
| dcf77e56a3 | |||
| e4311467b3 | |||
| bd2f38679c | |||
| 59e8db799a | |||
| 610fadefcc | |||
| 4481e94624 | |||
| 87fa5eb60c | |||
| 54f1e9a73b | |||
| 3b945e17f3 | |||
| 56999fd89d | |||
| 4d2b2eb650 | |||
| 1f6fc86faa | |||
| b6edbb8b3b | |||
| 71809ed109 | |||
| 2b6837adb5 | |||
| 2d7dc0ca02 | |||
| 6c8bb4000b | |||
| 7f2f2173a0 | |||
| abc1a87a6e | |||
| f3407d1eda | 
							
								
								
									
										29
									
								
								.eslintrc.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								.eslintrc.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | module.exports = { | ||||||
|  | 	"parserOptions": { | ||||||
|  | 		"ecmaVersion": 2018 | ||||||
|  | 	}, | ||||||
|  | 	"env": { | ||||||
|  | 		"node": true, | ||||||
|  | 		"es6": true | ||||||
|  | 	}, | ||||||
|  | 	"extends": "eslint:recommended", | ||||||
|  | 	"rules": { | ||||||
|  | 		"indent": [ "error", "tab" ], | ||||||
|  | 		"operator-linebreak": [ "error", "before" ], | ||||||
|  | 		"semi": [ "error", "always" ], | ||||||
|  | 		"comma-dangle": [ "error", "only-multiline" ], | ||||||
|  | 		"quotes": [ "error", "double" ], | ||||||
|  | 		"no-tabs": [ "error", { "allowIndentationTabs": true } ], | ||||||
|  | 		"padded-blocks": 2, | ||||||
|  | 		"space-before-blocks": 2, | ||||||
|  | 		"comma-style": 2, | ||||||
|  | 		"no-console": 0, | ||||||
|  | 		"valid-typeof": 0, | ||||||
|  | 		"arrow-parens": 0, | ||||||
|  | 		"generator-star-spacing": 0, | ||||||
|  | 		"space-before-function-paren": 0, | ||||||
|  | 		"object-property-newline": 0, | ||||||
|  | 		"new-cap": 0, | ||||||
|  | 		"no-eval": 0 | ||||||
|  | 	} | ||||||
|  | }; | ||||||
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1 +1,3 @@ | |||||||
| api_key.php | node_modules | ||||||
|  | data/* | ||||||
|  | !data/.gitkeep | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,2 +1,18 @@ | |||||||
| # Quadnite-Bot | # Quadnite-Bot | ||||||
| Source code for @quadnite_bot |  | ||||||
|  | Source code for [@quadnite\_bot](https://t.me/quadnite_bot) | ||||||
|  |  | ||||||
|  | ## Running your own instance | ||||||
|  |  | ||||||
|  | Quadnite bot depends on [Ugoki](https://gitlab.com/ceda_ei/ugoki) for providing | ||||||
|  | roleplay gifs. Once you have an instance of Ugoki (and optionally | ||||||
|  | [Ugoki Frontend](https://gitlab.com/ceda_ei/ugoki-frontend)) running: | ||||||
|  |  | ||||||
|  | - Clone this repo | ||||||
|  | - `npm install` | ||||||
|  | - `export BOT_API_KEY="your-token-for-bot"` | ||||||
|  | - `export FEEDBACK_ID="chat-id-where-feedback-is-forwarded-to"` | ||||||
|  | - `export UGOKI_ROOT="https://root.of.ugoki.api/server/"` | ||||||
|  | - `export RATE_TIMEFRAME=5000 # rate limit time interval in milliseconds` | ||||||
|  | - `export RATE_LIMIT=5 # number of requests allowed in the timeframe` | ||||||
|  | - `npm start` | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| <?php return 'xxxxxxxxxx:xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxx'; ?> |  | ||||||
							
								
								
									
										33
									
								
								bot.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								bot.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | const { Telegraf } = require("telegraf"); | ||||||
|  | const { BOT_API_KEY, FEEDBACK_ID, UGOKI_ROOT, RATE_TIMEFRAME, RATE_LIMIT } = process.env; | ||||||
|  | const fs = require("fs").promises; | ||||||
|  | const commands = require("./commands"); | ||||||
|  | const axios = require("axios"); | ||||||
|  | const roleplay = require("./static/roleplay.json"); | ||||||
|  | const { limit } = require("@grammyjs/ratelimiter"); | ||||||
|  |  | ||||||
|  | const bot = new Telegraf(BOT_API_KEY); | ||||||
|  | bot.catch((err) => console.log(err)); | ||||||
|  | bot.use(limit({ | ||||||
|  | 	// default config: 1 message per 1 second | ||||||
|  | 	timeFrame: RATE_TIMEFRAME ?? 1000, | ||||||
|  | 	limit: RATE_LIMIT ?? 1, | ||||||
|  | 	keyGenerator: (ctx) => ctx.chat?.id.toString() ?? ctx.from?.id.toString(), | ||||||
|  | })) | ||||||
|  |  | ||||||
|  | const data = [ | ||||||
|  | 	"questions", | ||||||
|  | 	"kys", | ||||||
|  | 	"insults", | ||||||
|  | 	"commands_list", | ||||||
|  | 	"words" | ||||||
|  | ].map(file => | ||||||
|  | 	fs.readFile("static/" + file + ".txt", "utf-8") | ||||||
|  | 		.then(list => | ||||||
|  | 			list.split("\n"))); | ||||||
|  |  | ||||||
|  | Promise.all(data) | ||||||
|  | 	.then(data => | ||||||
|  | 		commands(bot, [...data, roleplay], FEEDBACK_ID, BOT_API_KEY, UGOKI_ROOT, axios)); | ||||||
|  |  | ||||||
|  | bot.launch(); | ||||||
| @@ -1,23 +0,0 @@ | |||||||
| question - Get a random question |  | ||||||
| word - Get a random word |  | ||||||
| words - Get n random words |  | ||||||
| kys - Kill yourself |  | ||||||
| coin - Tosses a coin |  | ||||||
| wiki - Search Wikipedia |  | ||||||
| arch_wiki - Search the Arch wiki |  | ||||||
| insult - As expected, insults |  | ||||||
| weebify - Weebifies the given text |  | ||||||
| absurdify - mAke tExT aBSUrd |  | ||||||
| is - Is <your question> |  | ||||||
| are - Are <your question> |  | ||||||
| can - Can <your question> |  | ||||||
| will - will <your question> |  | ||||||
| shall - shall <your question> |  | ||||||
| was - Was <your question> |  | ||||||
| do - Do <your question> |  | ||||||
| does - Does <your question> |  | ||||||
| did - Did <your question> |  | ||||||
| should - Should <your question> |  | ||||||
| help - Need help? Go here |  | ||||||
| feedback - Send feedback, suggestion for kys, insult text |  | ||||||
| rate - Rate me on TGDR |  | ||||||
							
								
								
									
										27
									
								
								commands/absurdify.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								commands/absurdify.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | function absurdify(text) { | ||||||
|  |  | ||||||
|  | 	const text_array = text.split(""); | ||||||
|  | 	return text_array.map((character) => | ||||||
|  | 		Math.random() > 0.5 ? character.toLowerCase(): character.toUpperCase()) | ||||||
|  | 		.join(""); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = () => (ctx) => { | ||||||
|  |  | ||||||
|  | 	const message = ctx.message.text.replace(/^[^ ]+/, ""); | ||||||
|  | 	if (message) { | ||||||
|  |  | ||||||
|  | 		return absurdify(message); | ||||||
|  |  | ||||||
|  | 	} else { | ||||||
|  |  | ||||||
|  | 		if (ctx.message.reply_to_message && !ctx.message.reply_to_message.is_topic_message) | ||||||
|  | 			return absurdify(ctx.message.reply_to_message.text); | ||||||
|  | 		else | ||||||
|  | 			return "Need text to absurdify. Send /absurdify text or reply to a" | ||||||
|  | 			+ "message with /absurdify"; | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										31
									
								
								commands/dice.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								commands/dice.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | function diceRoll(side) { | ||||||
|  |  | ||||||
|  | 	return Math.ceil(Math.random() * side); | ||||||
|  |  | ||||||
|  | } | ||||||
|  | module.exports = () => async (ctx) => { | ||||||
|  |  | ||||||
|  | 	const numDice = parseInt(ctx.match[1] || "1"); | ||||||
|  | 	const diceSides = parseInt(ctx.match[2]); | ||||||
|  | 	const rolls = Array(numDice) | ||||||
|  | 		.fill(0) | ||||||
|  | 		.map(() => diceRoll(diceSides)); | ||||||
|  | 	const total = rolls.reduce((acc, curr) => acc + curr, 0); | ||||||
|  | 	const message = rolls | ||||||
|  | 		.map((i) => `_You roll a_ *D${diceSides}* _and get a_ *${i}*`) | ||||||
|  | 		.join("\n"); | ||||||
|  | 	let totalMessage = ""; | ||||||
|  | 	if (numDice > 1 || ctx.match[4]) | ||||||
|  | 		totalMessage = `*Total:* ${total}`; | ||||||
|  |  | ||||||
|  | 	if (ctx.match[4]) { | ||||||
|  |  | ||||||
|  | 		const modifier = parseInt(ctx.match[6]); | ||||||
|  | 		const sign = ctx.match[5]; | ||||||
|  | 		if (sign === "+") totalMessage += ` + ${modifier} = ${total + modifier}`; | ||||||
|  | 		else totalMessage += ` - ${modifier} = ${total - modifier}`; | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  | 	ctx.reply(message + "\n\n" + totalMessage, { parse_mode: "Markdown" }); | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										48
									
								
								commands/expand.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								commands/expand.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | function expand(words, text) { | ||||||
|  |  | ||||||
|  | 	const letters = text.trim().toLowerCase().split(""); | ||||||
|  | 	// Build a dictionary with lowercase letters as keys | ||||||
|  | 	const dict = {}; | ||||||
|  | 	words.forEach(word => { | ||||||
|  |  | ||||||
|  | 		if (word == "") | ||||||
|  | 			return; | ||||||
|  | 		const initial = word.split("")[0].toLowerCase(); | ||||||
|  | 		if (initial in dict) | ||||||
|  | 			dict[initial].push(word); | ||||||
|  | 		else | ||||||
|  | 			dict[initial] = [word]; | ||||||
|  |  | ||||||
|  | 	}); | ||||||
|  | 	return letters.map((letter) => { | ||||||
|  |  | ||||||
|  | 		if (!(letter.toLowerCase() in dict)) | ||||||
|  | 			return letter; | ||||||
|  | 		const wordsWithLetter = dict[letter.toLowerCase()]; | ||||||
|  | 		const word = wordsWithLetter[Math.floor(Math.random() * wordsWithLetter.length)]; | ||||||
|  | 		return word; | ||||||
|  |  | ||||||
|  | 	}).reduce((acc, cur) => acc + " " + cur).replace(/\s{2,}/g, " "); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | module.exports = (words = []) => (ctx) => { | ||||||
|  |  | ||||||
|  | 	words = words.filter(i => ! i.match(/'s$/)); | ||||||
|  | 	const message = ctx.message.text.replace(/^[^ ]+/, ""); | ||||||
|  | 	if (message) { | ||||||
|  |  | ||||||
|  | 		return expand(words, message); | ||||||
|  |  | ||||||
|  | 	} else { | ||||||
|  |  | ||||||
|  | 		if (ctx.message.reply_to_message && !ctx.message.reply_to_message.is_topic_message) | ||||||
|  | 			return expand(words, ctx.message.reply_to_message.text); | ||||||
|  | 		else | ||||||
|  | 			return "Need text to expand. Send /expand text or reply to a " | ||||||
|  | 			+ "message with /expand"; | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										28
									
								
								commands/feedback.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								commands/feedback.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | module.exports = (bot, feedback_id) => (ctx) => { | ||||||
|  |  | ||||||
|  | 	const message = ctx.message.text.replace(/^[^ ]+/, ""); | ||||||
|  | 	if (message) { | ||||||
|  |  | ||||||
|  | 		const from = ctx.message.from; | ||||||
|  | 		let contactable = "The developer might contact you regarding your feedback."; | ||||||
|  | 		let message; | ||||||
|  | 		if (from.username) { | ||||||
|  |  | ||||||
|  | 			message = `Feedback from: @${from.username}`; | ||||||
|  |  | ||||||
|  | 		} else { | ||||||
|  |  | ||||||
|  | 			contactable = "The developer might not be able to contact you due to lack of your username."; | ||||||
|  | 			message = `Feedback from User ${from.id}`; | ||||||
|  |  | ||||||
|  | 		} | ||||||
|  | 		bot.telegram.sendMessage(feedback_id, `${message} ${ctx.message.text}`).catch(console.log); | ||||||
|  | 		return `Thanks for the feedback! ${contactable}`; | ||||||
|  |  | ||||||
|  | 	} else { | ||||||
|  |  | ||||||
|  | 		return "To send feedback type in /feedback followed by the feedback. Note that developers may contact you regarding the feedback."; | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										104
									
								
								commands/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								commands/index.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | |||||||
|  | const random = require("./random"); | ||||||
|  | const insults_fun = require("./insult"); | ||||||
|  | const words_fun = require("./words"); | ||||||
|  | const is = require("./is"); | ||||||
|  | const weebify = require("./weebify"); | ||||||
|  | const absurdify = require("./absurdify"); | ||||||
|  | const feedback = require("./feedback"); | ||||||
|  | const media_wiki = require("./media_wiki"); | ||||||
|  | const info = require("./info"); | ||||||
|  | const expand = require("./expand"); | ||||||
|  | const roleplay = require("./roleplay"); | ||||||
|  | const suggest = require("./suggest"); | ||||||
|  | const dice = require("./dice"); | ||||||
|  |  | ||||||
|  | module.exports = (bot, [ questions, kys, insults, commands_list, words, roleplay_data ], feedback_id, apiToken, ugokiRoot, axios) => { | ||||||
|  |  | ||||||
|  | 	bot.command("question", (ctx) => ctx.reply(random(questions)())); | ||||||
|  | 	bot.command("word", (ctx) => ctx.reply(random(words)())); | ||||||
|  | 	bot.command("words", (ctx) => ctx.reply(words_fun(random, words)(ctx))); | ||||||
|  | 	bot.telegram.getMe() | ||||||
|  | 		.then(bot_user => { | ||||||
|  |  | ||||||
|  | 			const default_text = (command, text) => `Do you want to ${text} ` | ||||||
|  | 				+ `yourself?\nIf no, reply to someone with /${command} to ${command}` | ||||||
|  | 				+ ` them or run /${command} username/name.\nYou can suggest ` | ||||||
|  | 				+ `more /${command} replies using /feedback`; | ||||||
|  |  | ||||||
|  | 			bot.command("insult", (ctx) => ctx.reply(insults_fun(random, | ||||||
|  | 				insults, default_text("insult", "insult"), "Watch who you talk" | ||||||
|  | 				+ " to.", ["@" + bot_user.username, bot_user.firstName])(ctx))); | ||||||
|  |  | ||||||
|  | 			bot.command("kys", (ctx) => ctx.reply(insults_fun(random, kys, | ||||||
|  | 				default_text("kys", "kill"), "I can't be killed.", | ||||||
|  | 				["@" + bot_user.username, bot_user.firstName])(ctx))); | ||||||
|  |  | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | 	bot.command("commands", (ctx) => ctx.reply(commands_list.join("\n"), {parse_mode: "html"})); | ||||||
|  | 	bot.command("is", (ctx) => ctx.reply(is(random)(ctx))); | ||||||
|  | 	bot.command("are", (ctx) => ctx.reply(is(random)(ctx))); | ||||||
|  | 	bot.command("can", (ctx) => ctx.reply(is(random)(ctx))); | ||||||
|  | 	bot.command("will", (ctx) => ctx.reply(is(random)(ctx))); | ||||||
|  | 	bot.command("shall", (ctx) => ctx.reply(is(random)(ctx))); | ||||||
|  | 	bot.command("was", (ctx) => ctx.reply(is(random)(ctx))); | ||||||
|  | 	bot.command("do", (ctx) => ctx.reply(is(random)(ctx))); | ||||||
|  | 	bot.command("does", (ctx) => ctx.reply(is(random)(ctx))); | ||||||
|  | 	bot.command("did", (ctx) => ctx.reply(is(random)(ctx))); | ||||||
|  | 	bot.command("should", (ctx) => ctx.reply(is(random)(ctx))); | ||||||
|  | 	bot.command("coin", (ctx) => ctx.reply(random(["Heads", "Tails"])())); | ||||||
|  | 	bot.command("help", (ctx) => ctx.reply("You can either check /commands " | ||||||
|  | 		+ "for a short overview or check the [Help Page]" | ||||||
|  | 		+ "(https://t.me/quadnite/9).", {parse_mode: "Markdown"})); | ||||||
|  | 	bot.command("rate", (ctx) => ctx.reply("[Vote for me on Telegram " | ||||||
|  | 		+ "Directory!](https://t.me/tgdrbot?start=quadnite_bot)", {parse_mode: | ||||||
|  | 			"Markdown"})); | ||||||
|  | 	bot.command("weebify", (ctx) => ctx.reply(weebify()(ctx))); | ||||||
|  | 	bot.command("absurdify", (ctx) => ctx.reply(absurdify()(ctx))); | ||||||
|  | 	bot.command("feedback", (ctx) => ctx.reply(feedback(bot, feedback_id)(ctx))); | ||||||
|  | 	bot.command("wiki", (ctx) => media_wiki(axios, | ||||||
|  | 		"https://en.wikipedia.org/w/api.php")(ctx).then(x => ctx.reply(x, | ||||||
|  | 		{parse_mode: "HTML"}))); | ||||||
|  | 	bot.command("arch_wiki", (ctx) => media_wiki(axios, | ||||||
|  | 		"https://wiki.archlinux.org/api.php")(ctx).then(x => ctx.reply(x, | ||||||
|  | 		{parse_mode: "HTML"}))); | ||||||
|  | 	bot.command("info", (ctx) => ctx.reply(info()(ctx), {parse_mode: "Markdown"})); | ||||||
|  | 	bot.command("expand", (ctx) => ctx.reply(expand(words)(ctx))); | ||||||
|  | 	bot.command("start", (ctx) => ctx.reply("Hi, I am Quadnite. If you are " | ||||||
|  | 		+ "chatting with me in private, you are most likely doing it wrong. " | ||||||
|  | 		+ "Add me to a group for fun. To give feedback, use /feedback")); | ||||||
|  | 	bot.hears(/^\/?(\d*)d(\d+)(@\w+)?(\s*([-+])\s*(\d+))?$/i, dice()); | ||||||
|  |  | ||||||
|  | 	function getGetGif(command) { | ||||||
|  |  | ||||||
|  | 		const alias = roleplay_data[command].alias; | ||||||
|  | 		if (alias) | ||||||
|  | 			return getGetGif(alias); | ||||||
|  |  | ||||||
|  | 		return () => axios.get( | ||||||
|  | 			`category/${command}/gif`, | ||||||
|  | 			{ | ||||||
|  | 				baseURL: ugokiRoot | ||||||
|  | 			} | ||||||
|  | 		); | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	function getForms(name) { | ||||||
|  |  | ||||||
|  | 		if (roleplay_data[name].forms) | ||||||
|  | 			return roleplay_data[name].forms; | ||||||
|  | 		return getForms(roleplay_data[name].alias); | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Add all roleplay commands | ||||||
|  | 	Object.keys(roleplay_data).map(command => | ||||||
|  | 		bot.command(command, | ||||||
|  | 			(ctx) => roleplay(getForms(command), getGetGif(command))(ctx) | ||||||
|  | 		) | ||||||
|  | 	); | ||||||
|  |  | ||||||
|  | 	bot.command("suggest", (ctx) => suggest(axios, apiToken, ugokiRoot)(ctx)); | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										36
									
								
								commands/info.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								commands/info.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | module.exports = () => (ctx) => { | ||||||
|  |  | ||||||
|  | 	let text = ""; | ||||||
|  | 	const msg = ctx.message; | ||||||
|  | 	text += `Message ID: \`${msg.message_id}\`\n`; | ||||||
|  | 	text += `Chat ID: \`${msg.chat.id}\`\n`; | ||||||
|  | 	text += `User ID: \`${msg.from.id}\`\n`; | ||||||
|  | 	if (ctx.message.reply_to_message && !ctx.message.reply_to_message.is_topic_message) { | ||||||
|  |  | ||||||
|  | 		const reply = msg.reply_to_message; | ||||||
|  | 		text += "\n*Reply to*\n"; | ||||||
|  | 		text += `Message ID: \`${reply.message_id}\`\n`; | ||||||
|  | 		text += `Chat ID: \`${reply.chat.id}\`\n`; | ||||||
|  | 		text += `User ID: \`${reply.from.id}\`\n`; | ||||||
|  |  | ||||||
|  | 		if (reply.forward_from || reply.forward_from_chat) { | ||||||
|  |  | ||||||
|  | 			const forward = reply.forward_from ? reply.forward_from | ||||||
|  | 				:reply.forward_from_chat; | ||||||
|  | 			text += "\n*Forward from*\n"; | ||||||
|  | 			if (reply.forward_from) | ||||||
|  | 				text += "User ID: "; | ||||||
|  | 			else | ||||||
|  | 				text += "Channel ID: "; | ||||||
|  | 			text += `\`${forward.id}\`\n`; | ||||||
|  | 			text += "Message Date: `"; | ||||||
|  | 			const date = new Date(reply.forward_date*1000); | ||||||
|  | 			text += date.toUTCString(); | ||||||
|  | 			text += "`"; | ||||||
|  |  | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  | 	return text; | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										28
									
								
								commands/insult.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								commands/insult.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | module.exports = (random, kys, default_text, bot_text, excluded_names) => (ctx) => { | ||||||
|  |  | ||||||
|  | 	if (ctx.message.reply_to_message && !ctx.message.reply_to_message.is_topic_message) { | ||||||
|  |  | ||||||
|  | 		const { from } = ctx.message.reply_to_message; | ||||||
|  | 		const name = from.username ? "@" + from.username : from.first_name; | ||||||
|  | 		if (name == excluded_names[0]) | ||||||
|  | 			return bot_text; | ||||||
|  | 		return random(kys)().replace(/##name##/g, name); | ||||||
|  |  | ||||||
|  | 	} else { | ||||||
|  |  | ||||||
|  | 		const text_array = ctx.message.text.split(" "); | ||||||
|  | 		if (text_array.length > 1) { | ||||||
|  |  | ||||||
|  | 			const name = text_array.slice(1).reduce((i, j) => i + " " + j).trim(); | ||||||
|  | 			if (excluded_names.includes(name) | ||||||
|  | 				|| excluded_names.includes("@" + name)) | ||||||
|  | 				return bot_text; | ||||||
|  |  | ||||||
|  | 			return random(kys)().replace(/##name##/g, name); | ||||||
|  |  | ||||||
|  | 		} else | ||||||
|  | 			return default_text; | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										12
									
								
								commands/is.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								commands/is.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | module.exports = (random) => (ctx) => | ||||||
|  | { | ||||||
|  |  | ||||||
|  | 	const text_array = ctx.message.text.split(" "); | ||||||
|  | 	if (text_array.length == 1) | ||||||
|  | 		return "You know, you also have to ask the question."; | ||||||
|  |  | ||||||
|  | 	return random([["Yes", "Yep", "Yeah", "Yus", "Ja", "Ya", "Aye", "Ay", "Oui"], | ||||||
|  | 		["No", "Nopes", "Nu", "Nah", "Nein", "Naw", "Nay", "Yesn't"]][Math.round( | ||||||
|  | 		Math.random())])(); | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										22
									
								
								commands/media_wiki.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								commands/media_wiki.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | module.exports = (axios, url) => (ctx) => { | ||||||
|  |  | ||||||
|  | 	const message = ctx.message.text.replace(/^[^ ]+/, ""); | ||||||
|  | 	if (message) { | ||||||
|  |  | ||||||
|  | 		return axios.get(`${url}?action=opensearch&format=json&search=` | ||||||
|  | 			+ `${encodeURIComponent(message)}`) | ||||||
|  | 			.then((res) => { | ||||||
|  |  | ||||||
|  | 				const names = res.data[1]; | ||||||
|  | 				const urls = res.data[3]; | ||||||
|  | 				if (names.length == 0) | ||||||
|  | 					return "No results found"; | ||||||
|  | 				return "Results\n\n" + names.map((val, index) => | ||||||
|  | 					`<a href="${urls[index]}">${val}</a>`).join("\n"); | ||||||
|  |  | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 	} else | ||||||
|  | 		return Promise.resolve("Missing search query."); | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										5
									
								
								commands/random.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								commands/random.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | module.exports = (list = []) => (n = 1) => | ||||||
|  | 	Array(n) | ||||||
|  | 		.fill(0) | ||||||
|  | 		.map(() => list[Math.floor(Math.random() * list.length)]) | ||||||
|  | 		.join("\n"); | ||||||
							
								
								
									
										44
									
								
								commands/roleplay.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								commands/roleplay.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | function joinUsers(users) { | ||||||
|  |  | ||||||
|  | 	if (users.length == 1) | ||||||
|  | 		return users[0]; | ||||||
|  | 	return users.slice(0, users.length - 1).join(", ") | ||||||
|  | 		+ ` and ${users[users.length - 1]}`; | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | module.exports = (forms, getGif) => (ctx) => { | ||||||
|  |  | ||||||
|  | 	const message = ctx.message.text.replace(/^[^ ]+\s*/, "") | ||||||
|  | 		.match(/^((@\w+(\s+|$))*)(.*)/); | ||||||
|  | 	const users = message[1].trim().split(" ").filter(i => i.length); | ||||||
|  | 	const rtm = ctx.message.reply_to_message; | ||||||
|  | 	if (rtm && !rtm.is_topic_message) | ||||||
|  | 		users.push(rtm.from.username ? "@" + rtm.from.username | ||||||
|  | 			: rtm.from.first_name); | ||||||
|  | 	const reason = message[4]; | ||||||
|  | 	let reply = ""; | ||||||
|  | 	const from = ctx.message.from; | ||||||
|  | 	const user = from.username ? "@" + from.username : from.first_name; | ||||||
|  | 	if (users.length > 0 && reason.length > 0) | ||||||
|  | 		reply = forms.both | ||||||
|  | 			.replace("{}", user) | ||||||
|  | 			.replace("{}", joinUsers(users)) | ||||||
|  | 			.replace("{}", reason); | ||||||
|  | 	else if (users.length > 0) | ||||||
|  | 		reply = forms.others | ||||||
|  | 			.replace("{}", user) | ||||||
|  | 			.replace("{}", joinUsers(users)); | ||||||
|  | 	else if (reason.length > 0) | ||||||
|  | 		reply = forms.reason | ||||||
|  | 			.replace("{}", user) | ||||||
|  | 			.replace("{}", reason); | ||||||
|  | 	else | ||||||
|  | 		reply = forms.none | ||||||
|  | 			.replace("{}", user); | ||||||
|  |  | ||||||
|  | 	return getGif() | ||||||
|  | 		.then(gif => ctx.replyWithAnimation(gif.data.url, {caption: reply})); | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										84
									
								
								commands/suggest.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								commands/suggest.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | |||||||
|  | const ffmpeg = require("fluent-ffmpeg"); | ||||||
|  | const fs = require("fs"); | ||||||
|  | const FormData = require("form-data"); | ||||||
|  |  | ||||||
|  | function ugokiUpload(axios, ugokiRoot, ctx, category, path) { | ||||||
|  |  | ||||||
|  | 	const form = new FormData(); | ||||||
|  | 	form.append("file", fs.createReadStream(path)); | ||||||
|  | 	return axios.post(`new_suggestion/${category}`, form, | ||||||
|  | 		{ headers: form.getHeaders(), baseURL: ugokiRoot }) | ||||||
|  | 		.then(() => { | ||||||
|  |  | ||||||
|  | 			ctx.reply("Suggestion added."); | ||||||
|  | 			fs.unlink(path, () => {}); | ||||||
|  |  | ||||||
|  | 		}) | ||||||
|  | 		.catch((err) => { | ||||||
|  |  | ||||||
|  | 			console.error(err); | ||||||
|  | 			if (err.response && err.response.status == 404) | ||||||
|  | 				ctx.reply("Category doesn't exist"); | ||||||
|  | 			else if (err.response && err.response.status == 409) | ||||||
|  | 				ctx.reply("Already suggested / added."); | ||||||
|  | 			else | ||||||
|  | 				ctx.reply("No clue what the hell happened but adding suggestion failed."); | ||||||
|  |  | ||||||
|  | 		}); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = (axios, apiToken, ugokiRoot) => (ctx) => { | ||||||
|  |  | ||||||
|  | 	const category = ctx.message.text.split(" ")[1]; | ||||||
|  | 	const reply = ctx.message.reply_to_message; | ||||||
|  |  | ||||||
|  | 	if (category && reply && reply.animation) { | ||||||
|  |  | ||||||
|  | 		return ctx.telegram.getFile(reply.animation.file_id) | ||||||
|  | 			.then(resp => { | ||||||
|  |  | ||||||
|  | 				return axios({ | ||||||
|  | 					method: "get", | ||||||
|  | 					url: `https://api.telegram.org/file/bot${apiToken}/${resp.file_path}`, | ||||||
|  | 					responseType: "stream" | ||||||
|  | 				}) | ||||||
|  | 					.then(async (response) => { | ||||||
|  |  | ||||||
|  | 						let stream = response.data; | ||||||
|  | 						let path = `data/${resp.file_unique_id}`; | ||||||
|  | 						const writer = fs.createWriteStream(path); | ||||||
|  | 						if (!resp.file_path.match(/\.gif$/)) { | ||||||
|  |  | ||||||
|  | 							await stream.pipe(writer); | ||||||
|  | 							stream = ffmpeg(path) | ||||||
|  | 								.on("error", function () { | ||||||
|  |  | ||||||
|  | 									fs.unlink(path, () => {}); | ||||||
|  | 									ctx.reply("Something went wrong processing the gif"); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 								}) | ||||||
|  | 								.on("end", function () { | ||||||
|  |  | ||||||
|  | 									fs.unlink(path, () => {}); | ||||||
|  | 									ugokiUpload(axios, ugokiRoot, ctx, category, path + ".gif"); | ||||||
|  |  | ||||||
|  | 								}) | ||||||
|  | 								.output(path + ".gif") | ||||||
|  | 								.outputFormat("gif") | ||||||
|  | 								.run(); | ||||||
|  |  | ||||||
|  | 						} else | ||||||
|  | 							ugokiUpload(axios, ugokiRoot, category, ctx, path); | ||||||
|  |  | ||||||
|  | 					} | ||||||
|  | 					); | ||||||
|  |  | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 	} else | ||||||
|  | 		ctx.reply("Reply to a gif with /suggest [category] " | ||||||
|  | 			+ "to suggest it to be used for [category]"); | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										55
									
								
								commands/weebify.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								commands/weebify.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | |||||||
|  | function weebify(text) { | ||||||
|  |  | ||||||
|  | 	const dict = { | ||||||
|  | 		a : "卂", | ||||||
|  | 		b : "乃", | ||||||
|  | 		c : "匚", | ||||||
|  | 		d : "刀", | ||||||
|  | 		e : "乇", | ||||||
|  | 		f : "下", | ||||||
|  | 		g : "厶", | ||||||
|  | 		h : "卄", | ||||||
|  | 		i : "工", | ||||||
|  | 		j : "丁", | ||||||
|  | 		k : "长", | ||||||
|  | 		l : "乚", | ||||||
|  | 		m : "从", | ||||||
|  | 		n : "𠘨", | ||||||
|  | 		o : "口", | ||||||
|  | 		p : "尸", | ||||||
|  | 		q : "㔿", | ||||||
|  | 		r : "尺", | ||||||
|  | 		s : "丂", | ||||||
|  | 		t : "丅", | ||||||
|  | 		u : "凵", | ||||||
|  | 		v : "リ", | ||||||
|  | 		w : "山", | ||||||
|  | 		x : "乂", | ||||||
|  | 		y : "丫", | ||||||
|  | 		z : "乙" | ||||||
|  | 	}; | ||||||
|  | 	const text_array = text.toLowerCase().split(""); | ||||||
|  | 	return text_array.map((character) => | ||||||
|  | 		dict[character] ? dict[character] : character) | ||||||
|  | 		.join(""); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = () => (ctx) => { | ||||||
|  |  | ||||||
|  | 	const message = ctx.message.text.replace(/^[^ ]+/, ""); | ||||||
|  | 	if (message) { | ||||||
|  |  | ||||||
|  | 		return weebify(message); | ||||||
|  |  | ||||||
|  | 	} else { | ||||||
|  |  | ||||||
|  | 		if (ctx.message.reply_to_message && !ctx.message.reply_to_message.is_topic_message) | ||||||
|  | 			return weebify(ctx.message.reply_to_message.text); | ||||||
|  | 		else | ||||||
|  | 			return "Need text to weebify. Send /weebify text or reply to a " | ||||||
|  | 			+ "message with /weebify"; | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										21
									
								
								commands/words.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								commands/words.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | module.exports = (random, words) => (ctx) => { | ||||||
|  |  | ||||||
|  | 	const text_array = ctx.message.text.split(" "); | ||||||
|  | 	if (text_array.length == 1) { | ||||||
|  |  | ||||||
|  | 		return random(words)(10); | ||||||
|  |  | ||||||
|  | 	} else { | ||||||
|  |  | ||||||
|  | 		const input = parseInt(text_array[1]); | ||||||
|  | 		if (input && input > 0) | ||||||
|  | 			if (input < 50) | ||||||
|  | 				return random(words)(input); | ||||||
|  | 			else | ||||||
|  | 				return "Too many words."; | ||||||
|  | 		else | ||||||
|  | 			return "Not a valid number."; | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | }; | ||||||
							
								
								
									
										0
									
								
								data/.gitkeep
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								data/.gitkeep
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										499
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										499
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,499 @@ | |||||||
|  | { | ||||||
|  |   "name": "quadnite-bot", | ||||||
|  |   "version": "2.0.0", | ||||||
|  |   "lockfileVersion": 2, | ||||||
|  |   "requires": true, | ||||||
|  |   "packages": { | ||||||
|  |     "": { | ||||||
|  |       "name": "quadnite-bot", | ||||||
|  |       "version": "2.0.0", | ||||||
|  |       "license": "GPL-3.0", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@grammyjs/ratelimiter": "^1.2.0", | ||||||
|  |         "axios": "^0.21.0", | ||||||
|  |         "fluent-ffmpeg": "^2.1.2", | ||||||
|  |         "form-data": "^4.0.0", | ||||||
|  |         "telegraf": "^4.15.3" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/@grammyjs/ratelimiter": { | ||||||
|  |       "version": "1.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@grammyjs/ratelimiter/-/ratelimiter-1.2.0.tgz", | ||||||
|  |       "integrity": "sha512-xBkH/ATJsuv5JgVYX9yQM9DNg75Qqjw+gh82lVsBn4j+d0DkxxC+kuy6WFoB96Cb6oifQfaBJL8CTikdYG4v0A==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/@telegraf/types": { | ||||||
|  |       "version": "6.9.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@telegraf/types/-/types-6.9.1.tgz", | ||||||
|  |       "integrity": "sha512-bzqwhicZq401T0e09tu8b1KvGfJObPmzKU/iKCT5V466AsAZZWQrBYQ5edbmD1VZuHLEwopoOVY5wPP4HaLtug==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/abort-controller": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "event-target-shim": "^5.0.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=6.5" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/async": { | ||||||
|  |       "version": "3.2.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/async/-/async-3.2.1.tgz", | ||||||
|  |       "integrity": "sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/asynckit": { | ||||||
|  |       "version": "0.4.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", | ||||||
|  |       "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" | ||||||
|  |     }, | ||||||
|  |     "node_modules/axios": { | ||||||
|  |       "version": "0.21.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", | ||||||
|  |       "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "follow-redirects": "^1.14.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/buffer-alloc": { | ||||||
|  |       "version": "1.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", | ||||||
|  |       "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "buffer-alloc-unsafe": "^1.1.0", | ||||||
|  |         "buffer-fill": "^1.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/buffer-alloc-unsafe": { | ||||||
|  |       "version": "1.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", | ||||||
|  |       "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/buffer-fill": { | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", | ||||||
|  |       "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/combined-stream": { | ||||||
|  |       "version": "1.0.8", | ||||||
|  |       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", | ||||||
|  |       "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "delayed-stream": "~1.0.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.8" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/debug": { | ||||||
|  |       "version": "4.3.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", | ||||||
|  |       "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "ms": "2.1.2" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=6.0" | ||||||
|  |       }, | ||||||
|  |       "peerDependenciesMeta": { | ||||||
|  |         "supports-color": { | ||||||
|  |           "optional": true | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/delayed-stream": { | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", | ||||||
|  |       "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=0.4.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/event-target-shim": { | ||||||
|  |       "version": "5.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", | ||||||
|  |       "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=6" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/fluent-ffmpeg": { | ||||||
|  |       "version": "2.1.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz", | ||||||
|  |       "integrity": "sha1-yVLeIkD4EuvaCqgAbXd27irPfXQ=", | ||||||
|  |       "dependencies": { | ||||||
|  |         "async": ">=0.2.9", | ||||||
|  |         "which": "^1.1.1" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=0.8.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/follow-redirects": { | ||||||
|  |       "version": "1.14.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", | ||||||
|  |       "integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==", | ||||||
|  |       "funding": [ | ||||||
|  |         { | ||||||
|  |           "type": "individual", | ||||||
|  |           "url": "https://github.com/sponsors/RubenVerborgh" | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=4.0" | ||||||
|  |       }, | ||||||
|  |       "peerDependenciesMeta": { | ||||||
|  |         "debug": { | ||||||
|  |           "optional": true | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/form-data": { | ||||||
|  |       "version": "4.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", | ||||||
|  |       "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "asynckit": "^0.4.0", | ||||||
|  |         "combined-stream": "^1.0.8", | ||||||
|  |         "mime-types": "^2.1.12" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 6" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/isexe": { | ||||||
|  |       "version": "2.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", | ||||||
|  |       "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" | ||||||
|  |     }, | ||||||
|  |     "node_modules/mime-db": { | ||||||
|  |       "version": "1.49.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", | ||||||
|  |       "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.6" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/mime-types": { | ||||||
|  |       "version": "2.1.32", | ||||||
|  |       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", | ||||||
|  |       "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "mime-db": "1.49.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.6" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/mri": { | ||||||
|  |       "version": "1.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", | ||||||
|  |       "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=4" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/ms": { | ||||||
|  |       "version": "2.1.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", | ||||||
|  |       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/node-fetch": { | ||||||
|  |       "version": "2.7.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", | ||||||
|  |       "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "whatwg-url": "^5.0.0" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": "4.x || >=6.0.0" | ||||||
|  |       }, | ||||||
|  |       "peerDependencies": { | ||||||
|  |         "encoding": "^0.1.0" | ||||||
|  |       }, | ||||||
|  |       "peerDependenciesMeta": { | ||||||
|  |         "encoding": { | ||||||
|  |           "optional": true | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/p-timeout": { | ||||||
|  |       "version": "4.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-4.1.0.tgz", | ||||||
|  |       "integrity": "sha512-+/wmHtzJuWii1sXn3HCuH/FTwGhrp4tmJTxSKJbfS+vkipci6osxXM5mY0jUiRzWKMTgUT8l7HFbeSwZAynqHw==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=10" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/safe-compare": { | ||||||
|  |       "version": "1.1.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/safe-compare/-/safe-compare-1.1.4.tgz", | ||||||
|  |       "integrity": "sha512-b9wZ986HHCo/HbKrRpBJb2kqXMK9CEWIE1egeEvZsYn69ay3kdfl9nG3RyOcR+jInTDf7a86WQ1d4VJX7goSSQ==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "buffer-alloc": "^1.2.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/sandwich-stream": { | ||||||
|  |       "version": "2.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/sandwich-stream/-/sandwich-stream-2.0.2.tgz", | ||||||
|  |       "integrity": "sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ==", | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">= 0.10" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/telegraf": { | ||||||
|  |       "version": "4.15.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/telegraf/-/telegraf-4.15.3.tgz", | ||||||
|  |       "integrity": "sha512-pm2ZQAisd0YlUvnq6xdymDfoQR++8wTalw0nfw7Tjy0va+V/0HaBLzM8kMNid8pbbt7GHTU29lEyA5CAAr8AqA==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@telegraf/types": "^6.9.1", | ||||||
|  |         "abort-controller": "^3.0.0", | ||||||
|  |         "debug": "^4.3.4", | ||||||
|  |         "mri": "^1.2.0", | ||||||
|  |         "node-fetch": "^2.6.8", | ||||||
|  |         "p-timeout": "^4.1.0", | ||||||
|  |         "safe-compare": "^1.1.4", | ||||||
|  |         "sandwich-stream": "^2.0.2" | ||||||
|  |       }, | ||||||
|  |       "bin": { | ||||||
|  |         "telegraf": "lib/cli.mjs" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": "^12.20.0 || >=14.13.1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/tr46": { | ||||||
|  |       "version": "0.0.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", | ||||||
|  |       "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/webidl-conversions": { | ||||||
|  |       "version": "3.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", | ||||||
|  |       "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" | ||||||
|  |     }, | ||||||
|  |     "node_modules/whatwg-url": { | ||||||
|  |       "version": "5.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", | ||||||
|  |       "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "tr46": "~0.0.3", | ||||||
|  |         "webidl-conversions": "^3.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "node_modules/which": { | ||||||
|  |       "version": "1.3.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", | ||||||
|  |       "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", | ||||||
|  |       "dependencies": { | ||||||
|  |         "isexe": "^2.0.0" | ||||||
|  |       }, | ||||||
|  |       "bin": { | ||||||
|  |         "which": "bin/which" | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "dependencies": { | ||||||
|  |     "@grammyjs/ratelimiter": { | ||||||
|  |       "version": "1.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@grammyjs/ratelimiter/-/ratelimiter-1.2.0.tgz", | ||||||
|  |       "integrity": "sha512-xBkH/ATJsuv5JgVYX9yQM9DNg75Qqjw+gh82lVsBn4j+d0DkxxC+kuy6WFoB96Cb6oifQfaBJL8CTikdYG4v0A==" | ||||||
|  |     }, | ||||||
|  |     "@telegraf/types": { | ||||||
|  |       "version": "6.9.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@telegraf/types/-/types-6.9.1.tgz", | ||||||
|  |       "integrity": "sha512-bzqwhicZq401T0e09tu8b1KvGfJObPmzKU/iKCT5V466AsAZZWQrBYQ5edbmD1VZuHLEwopoOVY5wPP4HaLtug==" | ||||||
|  |     }, | ||||||
|  |     "abort-controller": { | ||||||
|  |       "version": "3.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", | ||||||
|  |       "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", | ||||||
|  |       "requires": { | ||||||
|  |         "event-target-shim": "^5.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "async": { | ||||||
|  |       "version": "3.2.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/async/-/async-3.2.1.tgz", | ||||||
|  |       "integrity": "sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==" | ||||||
|  |     }, | ||||||
|  |     "asynckit": { | ||||||
|  |       "version": "0.4.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", | ||||||
|  |       "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" | ||||||
|  |     }, | ||||||
|  |     "axios": { | ||||||
|  |       "version": "0.21.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", | ||||||
|  |       "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", | ||||||
|  |       "requires": { | ||||||
|  |         "follow-redirects": "^1.14.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "buffer-alloc": { | ||||||
|  |       "version": "1.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", | ||||||
|  |       "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", | ||||||
|  |       "requires": { | ||||||
|  |         "buffer-alloc-unsafe": "^1.1.0", | ||||||
|  |         "buffer-fill": "^1.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "buffer-alloc-unsafe": { | ||||||
|  |       "version": "1.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", | ||||||
|  |       "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" | ||||||
|  |     }, | ||||||
|  |     "buffer-fill": { | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", | ||||||
|  |       "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==" | ||||||
|  |     }, | ||||||
|  |     "combined-stream": { | ||||||
|  |       "version": "1.0.8", | ||||||
|  |       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", | ||||||
|  |       "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", | ||||||
|  |       "requires": { | ||||||
|  |         "delayed-stream": "~1.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "debug": { | ||||||
|  |       "version": "4.3.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", | ||||||
|  |       "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", | ||||||
|  |       "requires": { | ||||||
|  |         "ms": "2.1.2" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "delayed-stream": { | ||||||
|  |       "version": "1.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", | ||||||
|  |       "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" | ||||||
|  |     }, | ||||||
|  |     "event-target-shim": { | ||||||
|  |       "version": "5.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", | ||||||
|  |       "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" | ||||||
|  |     }, | ||||||
|  |     "fluent-ffmpeg": { | ||||||
|  |       "version": "2.1.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz", | ||||||
|  |       "integrity": "sha1-yVLeIkD4EuvaCqgAbXd27irPfXQ=", | ||||||
|  |       "requires": { | ||||||
|  |         "async": ">=0.2.9", | ||||||
|  |         "which": "^1.1.1" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "follow-redirects": { | ||||||
|  |       "version": "1.14.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", | ||||||
|  |       "integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==" | ||||||
|  |     }, | ||||||
|  |     "form-data": { | ||||||
|  |       "version": "4.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", | ||||||
|  |       "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", | ||||||
|  |       "requires": { | ||||||
|  |         "asynckit": "^0.4.0", | ||||||
|  |         "combined-stream": "^1.0.8", | ||||||
|  |         "mime-types": "^2.1.12" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "isexe": { | ||||||
|  |       "version": "2.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", | ||||||
|  |       "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" | ||||||
|  |     }, | ||||||
|  |     "mime-db": { | ||||||
|  |       "version": "1.49.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", | ||||||
|  |       "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==" | ||||||
|  |     }, | ||||||
|  |     "mime-types": { | ||||||
|  |       "version": "2.1.32", | ||||||
|  |       "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", | ||||||
|  |       "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", | ||||||
|  |       "requires": { | ||||||
|  |         "mime-db": "1.49.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "mri": { | ||||||
|  |       "version": "1.2.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", | ||||||
|  |       "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" | ||||||
|  |     }, | ||||||
|  |     "ms": { | ||||||
|  |       "version": "2.1.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", | ||||||
|  |       "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" | ||||||
|  |     }, | ||||||
|  |     "node-fetch": { | ||||||
|  |       "version": "2.7.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", | ||||||
|  |       "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", | ||||||
|  |       "requires": { | ||||||
|  |         "whatwg-url": "^5.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "p-timeout": { | ||||||
|  |       "version": "4.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-4.1.0.tgz", | ||||||
|  |       "integrity": "sha512-+/wmHtzJuWii1sXn3HCuH/FTwGhrp4tmJTxSKJbfS+vkipci6osxXM5mY0jUiRzWKMTgUT8l7HFbeSwZAynqHw==" | ||||||
|  |     }, | ||||||
|  |     "safe-compare": { | ||||||
|  |       "version": "1.1.4", | ||||||
|  |       "resolved": "https://registry.npmjs.org/safe-compare/-/safe-compare-1.1.4.tgz", | ||||||
|  |       "integrity": "sha512-b9wZ986HHCo/HbKrRpBJb2kqXMK9CEWIE1egeEvZsYn69ay3kdfl9nG3RyOcR+jInTDf7a86WQ1d4VJX7goSSQ==", | ||||||
|  |       "requires": { | ||||||
|  |         "buffer-alloc": "^1.2.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "sandwich-stream": { | ||||||
|  |       "version": "2.0.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/sandwich-stream/-/sandwich-stream-2.0.2.tgz", | ||||||
|  |       "integrity": "sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ==" | ||||||
|  |     }, | ||||||
|  |     "telegraf": { | ||||||
|  |       "version": "4.15.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/telegraf/-/telegraf-4.15.3.tgz", | ||||||
|  |       "integrity": "sha512-pm2ZQAisd0YlUvnq6xdymDfoQR++8wTalw0nfw7Tjy0va+V/0HaBLzM8kMNid8pbbt7GHTU29lEyA5CAAr8AqA==", | ||||||
|  |       "requires": { | ||||||
|  |         "@telegraf/types": "^6.9.1", | ||||||
|  |         "abort-controller": "^3.0.0", | ||||||
|  |         "debug": "^4.3.4", | ||||||
|  |         "mri": "^1.2.0", | ||||||
|  |         "node-fetch": "^2.6.8", | ||||||
|  |         "p-timeout": "^4.1.0", | ||||||
|  |         "safe-compare": "^1.1.4", | ||||||
|  |         "sandwich-stream": "^2.0.2" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "tr46": { | ||||||
|  |       "version": "0.0.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", | ||||||
|  |       "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" | ||||||
|  |     }, | ||||||
|  |     "webidl-conversions": { | ||||||
|  |       "version": "3.0.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", | ||||||
|  |       "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" | ||||||
|  |     }, | ||||||
|  |     "whatwg-url": { | ||||||
|  |       "version": "5.0.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", | ||||||
|  |       "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", | ||||||
|  |       "requires": { | ||||||
|  |         "tr46": "~0.0.3", | ||||||
|  |         "webidl-conversions": "^3.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "which": { | ||||||
|  |       "version": "1.3.1", | ||||||
|  |       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", | ||||||
|  |       "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", | ||||||
|  |       "requires": { | ||||||
|  |         "isexe": "^2.0.0" | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										31
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | { | ||||||
|  |   "name": "quadnite-bot", | ||||||
|  |   "version": "2.0.0", | ||||||
|  |   "description": "A Telegram bot that makes chats in group more fun.", | ||||||
|  |   "main": "bot.js", | ||||||
|  |   "scripts": { | ||||||
|  |     "start": "node bot.js" | ||||||
|  |   }, | ||||||
|  |   "repository": { | ||||||
|  |     "type": "git", | ||||||
|  |     "url": "git+ssh://git@gitlab.com/ceda_ei/Quadnite-Bot.git" | ||||||
|  |   }, | ||||||
|  |   "keywords": [ | ||||||
|  |     "bot", | ||||||
|  |     "telegram", | ||||||
|  |     "telegram-bot" | ||||||
|  |   ], | ||||||
|  |   "author": "Ceda EI", | ||||||
|  |   "license": "GPL-3.0", | ||||||
|  |   "bugs": { | ||||||
|  |     "url": "https://gitlab.com/ceda_ei/Quadnite-Bot/issues" | ||||||
|  |   }, | ||||||
|  |   "homepage": "https://gitlab.com/ceda_ei/Quadnite-Bot#readme", | ||||||
|  |   "dependencies": { | ||||||
|  |     "@grammyjs/ratelimiter": "^1.2.0", | ||||||
|  |     "axios": "^0.21.0", | ||||||
|  |     "fluent-ffmpeg": "^2.1.2", | ||||||
|  |     "form-data": "^4.0.0", | ||||||
|  |     "telegraf": "^4.15.3" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										71
									
								
								static/commands_list.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								static/commands_list.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | |||||||
|  | <b>Random</b> | ||||||
|  |  | ||||||
|  | coin - Tosses a coin | ||||||
|  | wiki - Search Wikipedia | ||||||
|  | arch_wiki - Search the Arch wiki | ||||||
|  | kys - Kill yourself | ||||||
|  | insult - As expected, insults | ||||||
|  |  | ||||||
|  | <b>Wordplay</b> | ||||||
|  |  | ||||||
|  | question - Get a random question | ||||||
|  | word - Get a random word | ||||||
|  | words - Get n random words | ||||||
|  | weebify - Weebifies the given text | ||||||
|  | absurdify - mAke tExT aBSUrd | ||||||
|  | expand - Expands a given abbreviation | ||||||
|  |  | ||||||
|  | <b>Ask a question</b> | ||||||
|  | <code> | ||||||
|  | is       are   can | ||||||
|  | will     did   shall | ||||||
|  | was      do    does | ||||||
|  | should | ||||||
|  | </code> | ||||||
|  | <b>Roleplay</b> | ||||||
|  | <code> | ||||||
|  | angry       bite | ||||||
|  | blush       bored | ||||||
|  | bonk        boop | ||||||
|  | chase       cheer | ||||||
|  | cringe      cry | ||||||
|  | cuddle      dab | ||||||
|  | dance       die | ||||||
|  | eat         facepalm | ||||||
|  | feed        glomp | ||||||
|  | happy       hate | ||||||
|  | holdhands   hide | ||||||
|  | highfive    hug | ||||||
|  | kill        kiss | ||||||
|  | laugh       lick | ||||||
|  | love        lurk | ||||||
|  | nervous     no | ||||||
|  | nom         nuzzle | ||||||
|  | panic       pat | ||||||
|  | peck        poke | ||||||
|  | pout        run | ||||||
|  | shoot       shrug | ||||||
|  | sip         slap | ||||||
|  | sleep       snuggle | ||||||
|  | stab        tease | ||||||
|  | think       thumbsup | ||||||
|  | tickle      triggered | ||||||
|  | twerk       wag | ||||||
|  | wave        wink | ||||||
|  | yes | ||||||
|  | </code> | ||||||
|  | <b>Miscellaneous</b> | ||||||
|  |  | ||||||
|  | help - Need help? Go here | ||||||
|  | feedback - Send feedback, suggestions for kys, insult text | ||||||
|  | rate - Rate me on TGDR | ||||||
|  |  | ||||||
|  | <b>Dice</b> | ||||||
|  |  | ||||||
|  | <code>[num]d[sides] [modifier]</code> | ||||||
|  |  | ||||||
|  | <i>num</i> is the number of the dices to roll. (Optional) | ||||||
|  | <i>sides</i> is the number of sides of the dice. (Required) | ||||||
|  | <i>modifier</i> is in the form of + or - followed by a number. (Optional) | ||||||
|  |  | ||||||
|  | <i>Examples</i>: 1d6, 2d10 + 5, 3d20 - 2, 2d20 | ||||||
| @@ -67,3 +67,20 @@ Everyone has the right to be stupid but ##name## is abusing the privilege. | |||||||
| ##name## I’d tell you how I really feel, but I wasn’t born with enough middle fingers to express myself in this case. | ##name## I’d tell you how I really feel, but I wasn’t born with enough middle fingers to express myself in this case. | ||||||
| ##name## Stupidity’s not a crime, so feel free to go. | ##name## Stupidity’s not a crime, so feel free to go. | ||||||
| ##name## I’d tell you to go fuck yourself, but that would be cruel and unusual punishment. | ##name## I’d tell you to go fuck yourself, but that would be cruel and unusual punishment. | ||||||
|  | I've finally found how ##name## is related to their pants, they're both full of shit. | ||||||
|  | There has been a rumor going around about ##name## acting like a dumbass. They're not acting. | ||||||
|  | ##name## calling you an idiot would be an insult to stupid people. | ||||||
|  | ##name## you know how laughter is supposed to be the best medicine? I'm surprised you haven't received an award for your face. | ||||||
|  | ##name## you're the reason why shampoo bottles need directions. | ||||||
|  | They say trash takes 10-1000 years to go away, I sure hope you're going for a speedrun ##name##. | ||||||
|  | ##name## makes me wish I had less eyes and ears. | ||||||
|  | ##name## if you ran as much as your mouth maybe people would actually like you. | ||||||
|  | ##name## mother nature takes pity on you. | ||||||
|  | If I had a face like ##name##'s I would file a lawsuit against my parents. | ||||||
|  | ##name## I'm glad to see you finally graduated kindergarten.....oh no, I'm sorry I thought- | ||||||
|  | It makes me really sad to see how much time it takes ##name## to get ready in the morning, not that it makes much of a difference. | ||||||
|  | ##name## I would try to insult you but it would take you the rest of the day to figure it out. | ||||||
|  | ##name## I'm surprised your portraits don't hang themselves. | ||||||
|  | Many people think ##name## is a vampire because their reflection quit on the first day. | ||||||
|  | ##name## you make satan consider going to church. | ||||||
|  | When god said 'Let there be light' he should have reconsidered after meeting ##name##. | ||||||
| @@ -26,7 +26,7 @@ | |||||||
| ##name## You should try playing snake and ladders, with real snakes and no ladders. | ##name## You should try playing snake and ladders, with real snakes and no ladders. | ||||||
| ##name## Dance naked on a couple of HT wires. | ##name## Dance naked on a couple of HT wires. | ||||||
| ##name## An active volcano is the best swimming pool for you. | ##name## An active volcano is the best swimming pool for you. | ||||||
| ##name## You shoulf try hot bath in a volcano. | ##name## You should try hot bath in a volcano. | ||||||
| ##name## Try to spend one day in a coffin and it will be yours forever. | ##name## Try to spend one day in a coffin and it will be yours forever. | ||||||
| ##name## Hit Uranium with a slow moving neutron in your presence. It will be a worthwhile experience. | ##name## Hit Uranium with a slow moving neutron in your presence. It will be a worthwhile experience. | ||||||
| ##name## You can be the first person to step on the sun. Have a try. | ##name## You can be the first person to step on the sun. Have a try. | ||||||
| @@ -1,4 +1,3 @@ | |||||||
| name? |  | ||||||
| How old are you? | How old are you? | ||||||
| Whats your Birthday? | Whats your Birthday? | ||||||
| What starsign does that make it? | What starsign does that make it? | ||||||
| @@ -606,32 +605,32 @@ On a scale of 1-10 how bitchy would you say you are? | |||||||
| On a scale of 1-10 how polite would you say you are? | On a scale of 1-10 how polite would you say you are? | ||||||
| On a scale of 1-10 how attractive would you say you are? | On a scale of 1-10 how attractive would you say you are? | ||||||
| If you could be any famous person who would you be and why? | If you could be any famous person who would you be and why? | ||||||
| Whats your favourite animal beginning with the letter A? | Whats your favourite animal? | ||||||
| Whats your favourite item of clothing beginning with the letter B? | Whats your favourite item of clothing? | ||||||
| Whats your favourite expleitive beginning with the letter C? | Whats your favourite expleitive? | ||||||
| Whats your favourite boys name beginning with the letter D? | Whats your favourite boys name? | ||||||
| Whats your favourite girls name beginning with the letter E? | Whats your favourite girls name? | ||||||
| Whats your favourite book beginning with the letter F? | Whats your favourite book? | ||||||
| Whats your favourite bodypart beginning with the letter G? | Whats your favourite bodypart? | ||||||
| Whats your favourite musical instrument beginning with the letter H? | Whats your favourite musical instrument? | ||||||
| Whats your favourite song beginning with the letter I? | Whats your favourite song? | ||||||
| Whats your favourite actress beginning with the letter J? | Whats your favourite actress? | ||||||
| Whats your favourite actor beginning with the letter K? | Whats your favourite actor? | ||||||
| Whats your favourite film beginning with the letter L? | Whats your favourite film? | ||||||
| Whats your favourite tv show beginning with the letter M? | Whats your favourite tv show? | ||||||
| Whats your favourite game beginning with the letter N? | Whats your favourite game? | ||||||
| Whats your favourite non alcoholic drink beginning with the letter O? | Whats your favourite non alcoholic drink? | ||||||
| Whats your favourite food beginning with the letter P? | Whats your favourite food? | ||||||
| Whats your favourite band beginning with the letter Q? | Whats your favourite band? | ||||||
| Whats your favourite author beginning with the letter R? | Whats your favourite author? | ||||||
| Whats your favourite sport beginning with the letter S? | Whats your favourite sport? | ||||||
| Whats your favourite job beginning with the letter T? | Whats your favourite job? | ||||||
| Whats your favourite mythical creature beginning with the letter U? | Whats your favourite mythical creature? | ||||||
| Whats your favourite alcoholic drink beginning with the letter V? | Whats your favourite alcoholic drink? | ||||||
| Whats your favourite cartoon character beginning with the letter W? | Whats your favourite cartoon character? | ||||||
| Whats your favourite word beginning with the letter X? | Whats your favourite word? | ||||||
| Whats your favourite city beginning with the letter Y? | Whats your favourite city? | ||||||
| Whats your favourite country beginning with the letter Z? | Whats your favourite country? | ||||||
| Do you get seasick? | Do you get seasick? | ||||||
| If you discovered a new species of dinosaur what would you call it? | If you discovered a new species of dinosaur what would you call it? | ||||||
| Do you own a paddling pool? | Do you own a paddling pool? | ||||||
| @@ -1233,28 +1232,7 @@ If you were to remake a movie, what actors would you cast? | |||||||
| If you were to replace a character in your favourite movie, who would you replace with who? | If you were to replace a character in your favourite movie, who would you replace with who? | ||||||
| Under rated actor who deserves to be famous in your opinion? | Under rated actor who deserves to be famous in your opinion? | ||||||
| Who’s your favourite celebrity with the same birthday or name as you? | Who’s your favourite celebrity with the same birthday or name as you? | ||||||
| What’s your favorite movie beginning with the letter A? | What’s your favorite movie? | ||||||
| What’s your fav movie beginning with the letter B? |  | ||||||
| What’s your fav movie beginning with the letter C? |  | ||||||
| What’s your fav movie beginning with the letter D? |  | ||||||
| What’s your fav movie beginning with the letter E? |  | ||||||
| What’s your fav movie beginning with the letter F? |  | ||||||
| What’s your fav movie beginning with the letter G? |  | ||||||
| What’s your fav movie beginning with the letter H? |  | ||||||
| What’s your fav movie beginning with the letter I? |  | ||||||
| What’s your fav movie beginning with the letter J? |  | ||||||
| What’s your fav movie beginning with the letter K? |  | ||||||
| What’s your fav movie beginning with the letter L? |  | ||||||
| What’s your fav movie beginning with the letter M? |  | ||||||
| What’s your fav movie beginning with the letter N? |  | ||||||
| What’s your fav movie beginning with the letter O? |  | ||||||
| What’s your fav movie beginning with the letter P? |  | ||||||
| What’s your fav movie beginning with the letter S? |  | ||||||
| What’s your fav movie beginning with the letter Q? |  | ||||||
| What’s your fav movie beginning with the letter V? |  | ||||||
| What’s your fav movie beginning with the letter X? |  | ||||||
| What’s your fav movie beginning with the letter Y? |  | ||||||
| What’s your fav movie beginning with the letter Z? |  | ||||||
| What movie would you wish to come to life? | What movie would you wish to come to life? | ||||||
| Movies you think one should watch before dying? | Movies you think one should watch before dying? | ||||||
| Favourite actor who has not won a oscar yet? | Favourite actor who has not won a oscar yet? | ||||||
| @@ -1576,28 +1554,7 @@ What is your favourite cheat in GTA? | |||||||
| What car do you prefer to drive in GTA? | What car do you prefer to drive in GTA? | ||||||
| Hardest mission you’ve done in GTA? | Hardest mission you’ve done in GTA? | ||||||
| Easiest mission you’ve done in GTA? | Easiest mission you’ve done in GTA? | ||||||
| What’s your favourite game beginning with the letter A? | What’s your favourite game? | ||||||
| What’s your favourite game beginning with the letter B? |  | ||||||
| What’s your favourite game beginning with the letter C? |  | ||||||
| What’s your favourite game beginning with the letter D? |  | ||||||
| What’s your favourite game beginning with the letter E? |  | ||||||
| What’s your favourite game beginning with the letter F? |  | ||||||
| What’s your favourite game beginning with the letter G? |  | ||||||
| What’s your favourite game beginning with the letter H? |  | ||||||
| What’s your favourite game beginning with the letter I? |  | ||||||
| What’s your favourite game beginning with the letter J? |  | ||||||
| What’s your favourite game beginning with the letter K? |  | ||||||
| What’s your favourite game beginning with the letter L? |  | ||||||
| What’s your favourite game beginning with the letter M? |  | ||||||
| What’s your favourite game beginning with the letter N? |  | ||||||
| What’s your favourite game beginning with the letter O? |  | ||||||
| What’s your favourite game beginning with the letter P? |  | ||||||
| What’s your favourite game beginning with the letter S? |  | ||||||
| What’s your favourite game beginning with the letter Q? |  | ||||||
| What’s your favourite game beginning with the letter V? |  | ||||||
| What’s your favourite game beginning with the letter X? |  | ||||||
| What’s your favourite game beginning with the letter Y? |  | ||||||
| What’s your favourite game beginning with the letter Z? |  | ||||||
| Do you usually win or lose when playing against friends? | Do you usually win or lose when playing against friends? | ||||||
| What are your parents inputs on you gaming? | What are your parents inputs on you gaming? | ||||||
| What type of games do you like to play with your partner? | What type of games do you like to play with your partner? | ||||||
| @@ -1632,8 +1589,7 @@ What impact do you think phone’s have had on the world? | |||||||
| Life without smartphone be like? | Life without smartphone be like? | ||||||
| Have you ever did a prank call on anyone? If so, who and how did you prank them? | Have you ever did a prank call on anyone? If so, who and how did you prank them? | ||||||
| What was their reaction? | What was their reaction? | ||||||
| Have you ever been prank called? | Have you ever been prank called? What was your reaction? | ||||||
| What was your reaction? |  | ||||||
| Favourite smartphone logo? | Favourite smartphone logo? | ||||||
| Your favourite iphone? | Your favourite iphone? | ||||||
| Your favourite samsung phone? | Your favourite samsung phone? | ||||||
| @@ -1651,28 +1607,7 @@ Worst app you’ve installed? | |||||||
| Do you prefer free or paid apps? | Do you prefer free or paid apps? | ||||||
| Have you bought any paid apps? If so which? | Have you bought any paid apps? If so which? | ||||||
| Most expensive paid app you bought and were you satisfied with it? | Most expensive paid app you bought and were you satisfied with it? | ||||||
| What’s your favourite mobile app beginning with the letter A? | What’s your favourite mobile app? | ||||||
| What’s your favourite mobile app beginning with the letter B? |  | ||||||
| What’s your favourite mobile app beginning with the letter C? |  | ||||||
| What’s your favourite mobile app beginning with the letter D? |  | ||||||
| What’s your favourite mobile appbeginning with the letter E? |  | ||||||
| What’s your favourite mobile app beginning with the letter F? |  | ||||||
| What’s your favourite mobile app beginning with the letter G? |  | ||||||
| What’s your favourite mobile app beginning with the letter H? |  | ||||||
| What’s your favourite mobile app beginning with the letter I? |  | ||||||
| What’s your favourite mobile app beginning with the letter J? |  | ||||||
| What’s your favourite mobile app beginning with the letter K? |  | ||||||
| What’s your favourite mobile app beginning with the letter L? |  | ||||||
| What’s your favourite mobile app beginning with the letter M? |  | ||||||
| What’s your favourite mobile app beginning with the letter N? |  | ||||||
| What’s your favourite mobile app beginning with the letter O? |  | ||||||
| What’s your favourite mobile app beginning with the letter P? |  | ||||||
| What’s your favourite mobile app beginning with the letter S? |  | ||||||
| What’s your favourite mobile app beginning with the letter Q? |  | ||||||
| What’s your favourite mobile app beginning with the letter V? |  | ||||||
| What’s your favourite mobile app beginning with the letter X? |  | ||||||
| What’s your favourite mobile app beginning with the letter Y? |  | ||||||
| What’s your favourite mobile app beginning with the letter Z? |  | ||||||
| How do you usually take your photos? (With camera, phone? etc) | How do you usually take your photos? (With camera, phone? etc) | ||||||
| What software do you use to backup your photos? | What software do you use to backup your photos? | ||||||
| Total number of photos you’ve in your gallery? | Total number of photos you’ve in your gallery? | ||||||
| @@ -1755,4 +1690,3 @@ How do you memorize your numbers? | |||||||
| Have you ever been stuck in a bad situation but had no phone? | Have you ever been stuck in a bad situation but had no phone? | ||||||
| How many signal bars do you usually get in your room? | How many signal bars do you usually get in your room? | ||||||
| What service provider do you think is the best and why so? | What service provider do you think is the best and why so? | ||||||
| 
 |  | ||||||
							
								
								
									
										476
									
								
								static/roleplay.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										476
									
								
								static/roleplay.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,476 @@ | |||||||
|  | { | ||||||
|  | 	"angry": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is angry", | ||||||
|  | 			"others": "{} is angry at {}", | ||||||
|  | 			"reason": "{} is angry because {}", | ||||||
|  | 			"both": "{} is angry at {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"bite": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is biting", | ||||||
|  | 			"others": "{} is biting {}", | ||||||
|  | 			"reason": "{} is biting because {}", | ||||||
|  | 			"both": "{} is biting {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"blush": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is blushing", | ||||||
|  | 			"others": "{} is blushing at {}", | ||||||
|  | 			"reason": "{} is blushing because {}", | ||||||
|  | 			"both": "{} is blushing at {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"bored": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is bored", | ||||||
|  | 			"others": "{}, {} are bored", | ||||||
|  | 			"reason": "{} is bored because {}", | ||||||
|  | 			"both": "{}, {} are bored because {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"bonk": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is bonking", | ||||||
|  | 			"others": "{} is bonking {}", | ||||||
|  | 			"reason": "{} is bonking because {}", | ||||||
|  | 			"both": "{} is bonking {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"boop": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is booping", | ||||||
|  | 			"others": "{} is booping {}", | ||||||
|  | 			"reason": "{} is booping because {}", | ||||||
|  | 			"both": "{} is booping {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"chase": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is chasing", | ||||||
|  | 			"others": "{} is chasing {}", | ||||||
|  | 			"reason": "{} is chasing because {}", | ||||||
|  | 			"both": "{} is chasing {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"cheer": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is cheering", | ||||||
|  | 			"others": "{} is cheering for {}", | ||||||
|  | 			"reason": "{} is cheering because {}", | ||||||
|  | 			"both": "{} is cheering for {} because {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"cringe": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is cringing", | ||||||
|  | 			"others": "{} is cringing at {}", | ||||||
|  | 			"reason": "{} is cringing because {}", | ||||||
|  | 			"both": "{} is cringing at {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"cry": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is crying", | ||||||
|  | 			"others": "{} is crying at {}", | ||||||
|  | 			"reason": "{} is crying because {}", | ||||||
|  | 			"both": "{} is crying at {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"cuddle": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is cuddling", | ||||||
|  | 			"others": "{} is cuddling with {}", | ||||||
|  | 			"reason": "{} is cuddling because {}", | ||||||
|  | 			"both": "{} is cuddling with {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"dab": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is dabing", | ||||||
|  | 			"others": "{} is dabing at {}", | ||||||
|  | 			"reason": "{} is dabing because {}", | ||||||
|  | 			"both": "{} is dabing at {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"dance": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is dancing", | ||||||
|  | 			"others": "{} is dancing with {}", | ||||||
|  | 			"reason": "{} is dancing because {}", | ||||||
|  | 			"both": "{} is dancing with {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"die": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is dying", | ||||||
|  | 			"others": "{} is dying with {}", | ||||||
|  | 			"reason": "{} is dying because {}", | ||||||
|  | 			"both": "{} is dying with {} because {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"eat": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is eating", | ||||||
|  | 			"others": "{} is eating with {}", | ||||||
|  | 			"reason": "{} is eating because {}", | ||||||
|  | 			"both": "{} is eating with {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"facepalm": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is facepalming", | ||||||
|  | 			"others": "{} is facepalming at {}", | ||||||
|  | 			"reason": "{} is facepalming because {}", | ||||||
|  | 			"both": "{} is facepalming at {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"feed": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is eating", | ||||||
|  | 			"others": "{} is feeding {}", | ||||||
|  | 			"reason": "{} is eating because {}", | ||||||
|  | 			"both": "{} is feeding {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"glomp": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is glomping", | ||||||
|  | 			"others": "{} is glomping {}", | ||||||
|  | 			"reason": "{} is glomping because {}", | ||||||
|  | 			"both": "{} is glomping {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"handhold": { | ||||||
|  | 		"alias": "holdhands" | ||||||
|  | 	}, | ||||||
|  | 	"happy": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is happy", | ||||||
|  | 			"others": "{} is happy with {}", | ||||||
|  | 			"reason": "{} is happy because {}", | ||||||
|  | 			"both": "{} is happy with {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"hate": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is hating", | ||||||
|  | 			"others": "{} is hating {}", | ||||||
|  | 			"reason": "{} is hating because {}", | ||||||
|  | 			"both": "{} is hating {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"holdhands": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is holding hands", | ||||||
|  | 			"others": "{} is holding hands with {}", | ||||||
|  | 			"reason": "{} is holding hands because {}", | ||||||
|  | 			"both": "{} is holding hands with {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"hide": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is hiding", | ||||||
|  | 			"others": "{} is hiding from {}", | ||||||
|  | 			"reason": "{} is hiding because {}", | ||||||
|  | 			"both": "{} is hiding from {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"highfive": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is high fiving", | ||||||
|  | 			"others": "{} is high fiving with {}", | ||||||
|  | 			"reason": "{} is high fiving because {}", | ||||||
|  | 			"both": "{} is high fiving with {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"hug": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is hugging", | ||||||
|  | 			"others": "{} is hugging {}", | ||||||
|  | 			"reason": "{} is hugging because {}", | ||||||
|  | 			"both": "{} is hugging at {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"kill": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is killing", | ||||||
|  | 			"others": "{} is killing {}", | ||||||
|  | 			"reason": "{} is killing because {}", | ||||||
|  | 			"both": "{} is killing {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"kiss": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is kissing", | ||||||
|  | 			"others": "{} is kissing {}", | ||||||
|  | 			"reason": "{} is kissing because {}", | ||||||
|  | 			"both": "{} is kissing {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"laugh": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is laughing", | ||||||
|  | 			"others": "{} is laughing with {}", | ||||||
|  | 			"reason": "{} is laughing because {}", | ||||||
|  | 			"both": "{} is laughing with {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"lick": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is licking", | ||||||
|  | 			"others": "{} is licking {}", | ||||||
|  | 			"reason": "{} is licking {}", | ||||||
|  | 			"both": "{} is licking {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"love": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is loving", | ||||||
|  | 			"others": "{} is loving {}", | ||||||
|  | 			"reason": "{} is loving because {}", | ||||||
|  | 			"both": "{} is loving {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"lurk": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is lurking", | ||||||
|  | 			"others": "{} is lurking from {}", | ||||||
|  | 			"reason": "{} is lurking because {}", | ||||||
|  | 			"both": "{} is lurking from {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"nervous": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is nervous", | ||||||
|  | 			"others": "{} is nervous with {}", | ||||||
|  | 			"reason": "{} is nervous because {}", | ||||||
|  | 			"both": "{} is nervous with {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"no": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is saying no", | ||||||
|  | 			"others": "{} is saying no to {}", | ||||||
|  | 			"reason": "{} is saying no because {}", | ||||||
|  | 			"both": "{} is saying no to {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"nom": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is noming", | ||||||
|  | 			"others": "{} is noming {}", | ||||||
|  | 			"reason": "{} is noming because {}", | ||||||
|  | 			"both": "{} is noming {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"nuzzle": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is nuzzling", | ||||||
|  | 			"others": "{} is nuzzling {}", | ||||||
|  | 			"reason": "{} is nuzzling because {}", | ||||||
|  | 			"both": "{} is nuzzling {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"panic": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is panicking", | ||||||
|  | 			"others": "{} is panicking at {}", | ||||||
|  | 			"reason": "{} is panicking because {}", | ||||||
|  | 			"both": "{} is panicking at {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"pat": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is patting", | ||||||
|  | 			"others": "{} is patting {}", | ||||||
|  | 			"reason": "{} is patting because {}", | ||||||
|  | 			"both": "{} is patting {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"peck": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is pecking", | ||||||
|  | 			"others": "{} is pecking {}", | ||||||
|  | 			"reason": "{} is pecking because {}", | ||||||
|  | 			"both": "{} is pecking {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"poke": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is poking", | ||||||
|  | 			"others": "{} is poking {}", | ||||||
|  | 			"reason": "{} is poking because {}", | ||||||
|  | 			"both": "{} is poking {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"pout": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is pouting", | ||||||
|  | 			"others": "{} is pouting at {}", | ||||||
|  | 			"reason": "{} is pouting because {}", | ||||||
|  | 			"both": "{} is pouting at {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"run": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is running", | ||||||
|  | 			"others": "{} is running from {}", | ||||||
|  | 			"reason": "{} is running because {}", | ||||||
|  | 			"both": "{} is running from {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"runs": { | ||||||
|  | 		"alias": "run" | ||||||
|  | 	}, | ||||||
|  | 	"shoot": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is shooting", | ||||||
|  | 			"others": "{} is shooting {}", | ||||||
|  | 			"reason": "{} is shooting because {}", | ||||||
|  | 			"both": "{} is shooting {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"shrug": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is shrugging", | ||||||
|  | 			"others": "{} is shrugging at {}", | ||||||
|  | 			"reason": "{} is shrugging because {}", | ||||||
|  | 			"both": "{} is shrugging at {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"sip": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is sipping", | ||||||
|  | 			"others": "{} is sipping with {}", | ||||||
|  | 			"reason": "{} is sipping because {}", | ||||||
|  | 			"both": "{} is sipping with {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"slap": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is slapping", | ||||||
|  | 			"others": "{} is slapping {}", | ||||||
|  | 			"reason": "{} is slapping because {}", | ||||||
|  | 			"both": "{} is slapping {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"sleep": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is sleeping", | ||||||
|  | 			"others": "{} is sleeping with {}", | ||||||
|  | 			"reason": "{} is sleeping because {}", | ||||||
|  | 			"both": "{} is sleeping {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"sob": { | ||||||
|  | 		"alias": "sobs" | ||||||
|  | 	}, | ||||||
|  | 	"sobs": { | ||||||
|  | 		"alias": "cry", | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is sobbing", | ||||||
|  | 			"others": "{} is sobbing due to {}", | ||||||
|  | 			"reason": "{} is sobbing because {}", | ||||||
|  | 			"both": "{} is sobbing due to {} because {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"snuggle": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is snuggling", | ||||||
|  | 			"others": "{} is snuggling {}", | ||||||
|  | 			"reason": "{} is snuggling because {}", | ||||||
|  | 			"both": "{} is snuggling {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"stab": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is stabbing", | ||||||
|  | 			"others": "{} is stabbing {}", | ||||||
|  | 			"reason": "{} is stabbing because {}", | ||||||
|  | 			"both": "{} is stabbing {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"tease": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is teasing", | ||||||
|  | 			"others": "{} is teasing {}", | ||||||
|  | 			"reason": "{} is teasing because {}", | ||||||
|  | 			"both": "{} is teasing {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"think": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is thinking", | ||||||
|  | 			"others": "{} is thinking with {}", | ||||||
|  | 			"reason": "{} is thinking because {}", | ||||||
|  | 			"both": "{} is thinking with {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"thumbsup": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is giving a thumbs up", | ||||||
|  | 			"others": "{} is giving a thumbs up to {}", | ||||||
|  | 			"reason": "{} is giving a thumbs up because {}", | ||||||
|  | 			"both": "{} is giving a thumbs up to {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"tickle": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is tickling", | ||||||
|  | 			"others": "{} is tickling {}", | ||||||
|  | 			"reason": "{} is tickling because {}", | ||||||
|  | 			"both": "{} is tickling {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"triggered": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is triggered", | ||||||
|  | 			"others": "{} is triggered by {}", | ||||||
|  | 			"reason": "{} is triggered because {}", | ||||||
|  | 			"both": "{} is triggered by {} because {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"twerk": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is twerking", | ||||||
|  | 			"others": "{} is twerking with {}", | ||||||
|  | 			"reason": "{} is twerking because {}", | ||||||
|  | 			"both": "{} is twerking with {} because {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"wag": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is wagging", | ||||||
|  | 			"others": "{} is wagging at {}", | ||||||
|  | 			"reason": "{} is wagging because {}", | ||||||
|  | 			"both": "{} is wagging at {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"wave": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is waving", | ||||||
|  | 			"others": "{} is waving at {}", | ||||||
|  | 			"reason": "{} is waving because {}", | ||||||
|  | 			"both": "{} is waving at {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"wink": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is winking", | ||||||
|  | 			"others": "{} is winking at {}", | ||||||
|  | 			"reason": "{} is winking because {}", | ||||||
|  | 			"both": "{} is winking at {} for {}" | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 	"yes": { | ||||||
|  | 		"forms": { | ||||||
|  | 			"none": "{} is saying yes", | ||||||
|  | 			"others": "{} is saying yes to {}", | ||||||
|  | 			"reason": "{} is saying yes because {}", | ||||||
|  | 			"both": "{} is saying yes to {} for {}" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										123115
									
								
								static/words.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123115
									
								
								static/words.txt
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										564
									
								
								webhook.php
									
									
									
									
									
								
							
							
						
						
									
										564
									
								
								webhook.php
									
									
									
									
									
								
							| @@ -1,564 +0,0 @@ | |||||||
| <?php |  | ||||||
| # vim: set tabstop=2 shiftwidth=2 expandtab: |  | ||||||
| $bot_name = "quadnite_bot"; |  | ||||||
| $bot_api = require('api_key.php'); |  | ||||||
|  |  | ||||||
| // Checks whether the given command is the same as the entered command |  | ||||||
| function check_command($command) { |  | ||||||
|   global $bot_name; |  | ||||||
|   global $decoded; |  | ||||||
|   $command_list = explode(" ", $decoded->{"message"}->{"text"}); |  | ||||||
|   if ($command_list[0] == $command || $command_list[0] == $command . "@" . $bot_name) { |  | ||||||
|     return True; |  | ||||||
|   } |  | ||||||
|   else { |  | ||||||
|     return False; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Send code back to the sender. |  | ||||||
| function send_code($post_message, $reply=false) { |  | ||||||
|   global $decoded; |  | ||||||
|   global $bot_api; |  | ||||||
|   global $chat_id; |  | ||||||
|   $url = 'https://api.telegram.org/bot' . $bot_api . '/sendMessage'; |  | ||||||
|   $post_msg = array('chat_id' => $chat_id, 'text' => '```\n ' . $post_message . '```', 'parse_mode' => 'markdown' ); |  | ||||||
|   if ($reply != false) { |  | ||||||
|     if ($reply === true){ |  | ||||||
|       $post_msg['reply_to_message_id'] = $decoded->{'message'}->{'message_id'}; |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       $post_msg['reply_to_message_id'] = $reply; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   $options = array( |  | ||||||
|     'http' => array( |  | ||||||
|       'header' => "Content-type: application/x-www-form-urlencoded\r\n", |  | ||||||
|       'method' => 'POST', |  | ||||||
|       'content' => http_build_query($post_msg) |  | ||||||
|     ) |  | ||||||
|   ); |  | ||||||
|   $context = stream_context_create($options); |  | ||||||
|   $result = file_get_contents($url, false, $context); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Send text back to the sender. |  | ||||||
| function send_text($post_message, $reply=false) { |  | ||||||
|   global $decoded; |  | ||||||
|   global $bot_api; |  | ||||||
|   global $chat_id; |  | ||||||
|   $url = 'https://api.telegram.org/bot' . $bot_api . '/sendMessage'; |  | ||||||
|   $post_msg = array('chat_id' => $chat_id, 'text' =>$post_message ); |  | ||||||
|   if ($reply != false) { |  | ||||||
|     if ($reply === true){ |  | ||||||
|       $post_msg['reply_to_message_id'] = $decoded->{'message'}->{'message_id'}; |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       $post_msg['reply_to_message_id'] = $reply; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   $options = array( |  | ||||||
|     'http' => array( |  | ||||||
|       'header' => "Content-type: application/x-www-form-urlencoded\r\n", |  | ||||||
|       'method' => 'POST', |  | ||||||
|       'content' => http_build_query($post_msg) |  | ||||||
|     ) |  | ||||||
|   ); |  | ||||||
|   $context = stream_context_create($options); |  | ||||||
|   $result = file_get_contents($url, false, $context); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Send html back to the sender. |  | ||||||
| function send_html($post_message, $reply=false) { |  | ||||||
|   global $decoded; |  | ||||||
|   global $bot_api; |  | ||||||
|   global $chat_id; |  | ||||||
|   $url = 'https://api.telegram.org/bot' . $bot_api . '/sendMessage'; |  | ||||||
|   $post_msg = array('chat_id' => $chat_id, 'text' =>$post_message, 'parse_mode' => 'html'); |  | ||||||
|   if ($reply != false) { |  | ||||||
|     if ($reply === true){ |  | ||||||
|       $post_msg['reply_to_message_id'] = $decoded->{'message'}->{'message_id'}; |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       $post_msg['reply_to_message_id'] = $reply; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   $options = array( |  | ||||||
|     'http' => array( |  | ||||||
|       'header' => "Content-type: application/x-www-form-urlencoded\r\n", |  | ||||||
|       'method' => 'POST', |  | ||||||
|       'content' => http_build_query($post_msg) |  | ||||||
|     ) |  | ||||||
|   ); |  | ||||||
|   $context = stream_context_create($options); |  | ||||||
|   $result = file_get_contents($url, false, $context); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Send gif back to the sender. |  | ||||||
| function send_gif($gif_url, $reply=false) { |  | ||||||
|   global $decoded; |  | ||||||
|   global $bot_api; |  | ||||||
|   global $chat_id; |  | ||||||
|   $url = 'https://api.telegram.org/bot' . $bot_api . '/sendAnimation'; |  | ||||||
|   $post_msg = array('chat_id' => $chat_id, 'animation' => $gif_url ); |  | ||||||
|   if ($reply != false) { |  | ||||||
|     if ($reply === true){ |  | ||||||
|       $post_msg['reply_to_message_id'] = $decoded->{'message'}->{'message_id'}; |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       $post_msg['reply_to_message_id'] = $reply; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   $options = array( |  | ||||||
|     'http' => array( |  | ||||||
|       'header' => "Content-type: application/x-www-form-urlencoded\r\n", |  | ||||||
|       'method' => 'POST', |  | ||||||
|       'content' => http_build_query($post_msg) |  | ||||||
|     ) |  | ||||||
|   ); |  | ||||||
|   $context = stream_context_create($options); |  | ||||||
|   $result = file_get_contents($url, false, $context); |  | ||||||
|   return $result; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function forward_message($to_chat_id) { |  | ||||||
|   global $decoded; |  | ||||||
|   global $bot_api; |  | ||||||
|   global $chat_id; |  | ||||||
|   $message_id = $decoded->{"message"}->{"message_id"}; |  | ||||||
|   $url = 'https://api.telegram.org/bot' . $bot_api . '/forwardMessage'; |  | ||||||
|   $post_msg = array('chat_id' => $to_chat_id, 'message_id' => $message_id, 'from_chat_id' => $chat_id); |  | ||||||
|   $options = array( |  | ||||||
|     'http' => array( |  | ||||||
|       'header' => "Content-type: application/x-www-form-urlencoded\r\n", |  | ||||||
|       'method' => 'POST', |  | ||||||
|       'content' => http_build_query($post_msg) |  | ||||||
|     ) |  | ||||||
|   ); |  | ||||||
|   $context = stream_context_create($options); |  | ||||||
|   $result = file_get_contents($url, false, $context); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Generates random words |  | ||||||
| function rand_words($onewordmode) { |  | ||||||
|   global $command_list; |  | ||||||
|   if($onewordmode == 1){ |  | ||||||
|     $num = 1; |  | ||||||
|   } |  | ||||||
|   else { |  | ||||||
|     if (isset($command_list[1])) { |  | ||||||
|       $num = $command_list[1]; |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       $num = 10; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   $num++; |  | ||||||
|   $words = array(); |  | ||||||
|   if (is_integer($num)) { |  | ||||||
|     if ($num > 50) { |  | ||||||
|       send_text("Too many words.", true); |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|     $wordlist = file("/usr/share/dict/words"); |  | ||||||
|     for ($word=1; $word < $num; $word++) { |  | ||||||
|       $words[] = $wordlist[rand(0,count($wordlist))]; |  | ||||||
|     } |  | ||||||
|     send_text(implode(' ', $words)); |  | ||||||
|   } |  | ||||||
|   else { |  | ||||||
|     send_text("Ever heard of numbers?", true); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function rand_question() { |  | ||||||
|   $questions = file('rand_questions.txt'); |  | ||||||
|   $question = $questions[rand(0,count($questions))]; |  | ||||||
|   send_text($question); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function media_wiki($base_url) { |  | ||||||
|   global $command_list; |  | ||||||
|   $search_query = ""; |  | ||||||
|   for ($i=1; $i < count($command_list); $i++) { |  | ||||||
|     $search_query .= $command_list[$i]; |  | ||||||
|     if ($i < count($command_list) - 1) { |  | ||||||
|       $search_query .= " "; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   if (preg_match('/^\s*$/', $search_query)) { |  | ||||||
|     send_text('Missing search query'); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   $url = $base_url . "?action=opensearch&format=json&search=" . urlencode($search_query); |  | ||||||
|   $a = json_decode(file_get_contents($url)); |  | ||||||
|   $names = $a[1]; |  | ||||||
|   $urls = $a[3]; |  | ||||||
|   if (count($names) == 0) { |  | ||||||
|     send_text("No result found", true); |  | ||||||
|     return false; |  | ||||||
|   } |  | ||||||
|   $text = "Results\n"; |  | ||||||
|   for ($i = 0 ; $i < count($names) ; $i++){ |  | ||||||
|     $text .= "<a href='" . $urls[$i] . "'>" . $names[$i] . "</a>\n"; |  | ||||||
|   } |  | ||||||
|   send_html($text); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function coin() { |  | ||||||
|   $random = rand(0,1); |  | ||||||
|   if ($random == 1) { |  | ||||||
|     send_text('Heads', true); |  | ||||||
|   } |  | ||||||
|   else { |  | ||||||
|     send_text('Tails', true); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function get_gif($force) { |  | ||||||
|   if ($force){ |  | ||||||
|     $param = "yes"; |  | ||||||
|   } |  | ||||||
|   else { |  | ||||||
|     $param = "no"; |  | ||||||
|   } |  | ||||||
|   $url = "https://yesno.wtf/api?force=" . $param; |  | ||||||
|   $result = file_get_contents($url); |  | ||||||
|   $json = json_decode($result); |  | ||||||
|   $image_url = $json->{"image"}; |  | ||||||
|   return $image_url; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function yes_or_no() { |  | ||||||
|   global $command_list; |  | ||||||
|   if (!isset($command_list[1])){ |  | ||||||
|     send_text('You know, you also have to ask the question.', true); |  | ||||||
|     return false; |  | ||||||
|   } |  | ||||||
|   $yes_replies = array("Yes", "Yep", "Yeah", "Yus", "Ja", "Ya", "Aye", "Ay", "Oui"); |  | ||||||
|   $no_replies = array("No", "Nopes", "Nu", "Nah", "Nein", "Naw", "Nay", "Yesn't"); |  | ||||||
|   $random = rand(0,1); |  | ||||||
|   $random2 = rand(0, 10); |  | ||||||
|   if ($random == 1) { |  | ||||||
|     $yes = $yes_replies[array_rand($yes_replies)]; |  | ||||||
|     send_text($yes, true); |  | ||||||
|     if ($random2 == 5){ |  | ||||||
|       send_gif(get_gif(True)); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   else { |  | ||||||
|     $no = $no_replies[array_rand($no_replies)]; |  | ||||||
|     send_text($no, true); |  | ||||||
|     if ($random2 == 33){ |  | ||||||
|       send_gif(get_gif(False)); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Kill yourself |  | ||||||
| function kys() { |  | ||||||
|   global $decoded; |  | ||||||
|   global $bot_name; |  | ||||||
|   global $command_list; |  | ||||||
|   $kys = file('kys.txt'); |  | ||||||
|   $random_kys = $kys[rand(0,count($kys)-1)]; |  | ||||||
|   if ($decoded->{'message'}->{'reply_to_message'}->{'from'}->{'username'} == $bot_name){ |  | ||||||
|     send_text("I can't be killed.", true); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   if (isset($decoded->{'message'}->{'reply_to_message'})) { |  | ||||||
|     if (isset($decoded->{'message'}->{'reply_to_message'}->{'from'}->{'username'})){ |  | ||||||
|       $username = '@' . $decoded->{'message'}->{'reply_to_message'}->{'from'}->{'username'}; |  | ||||||
|       $random_kys = preg_replace('/##name##/', $username, $random_kys); |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       $first_name = $decoded->{'message'}->{'reply_to_message'}->{'from'}->{'first_name'}; |  | ||||||
|       $random_kys = preg_replace('/##name##/', $first_name, $random_kys); |  | ||||||
|     } |  | ||||||
|     send_text($random_kys); |  | ||||||
|   } |  | ||||||
|   elseif (isset($command_list[1])){ |  | ||||||
|     $username = $command_list[1]; |  | ||||||
|     if ($username == "@quadnite_bot" || $username == "Quadnite" || $username == "quadnite"){ |  | ||||||
|       send_text("I can't be killed.", true); |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       $random_kys = preg_replace('/##name##/', $username, $random_kys); |  | ||||||
|       send_text($random_kys); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   else { |  | ||||||
|     send_text("Do you want to kill yourself?\nIf no, reply to someone with /kys to kill them or run /kys username/name.\nYou can suggest more /kys replies using /feedback", true); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Insult |  | ||||||
| function send_insult() { |  | ||||||
|   global $decoded; |  | ||||||
|   global $bot_name; |  | ||||||
|   global $command_list; |  | ||||||
|   $insults = file('insults.txt'); |  | ||||||
|   $random_insult = $insults[rand(0,count($insults)-1)]; |  | ||||||
|   if ($decoded->{'message'}->{'reply_to_message'}->{'from'}->{'username'} == $bot_name){ |  | ||||||
|     send_text("Watch who you talk to.", true); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   if (isset($decoded->{'message'}->{'reply_to_message'})) { |  | ||||||
|     if (isset($decoded->{'message'}->{'reply_to_message'}->{'from'}->{'username'})){ |  | ||||||
|       $username = '@' . $decoded->{'message'}->{'reply_to_message'}->{'from'}->{'username'}; |  | ||||||
|       $random_insult = preg_replace('/##name##/', $username, $random_insult); |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       $first_name = $decoded->{'message'}->{'reply_to_message'}->{'from'}->{'first_name'}; |  | ||||||
|       $random_insult = preg_replace('/##name##/', $first_name, $random_insult); |  | ||||||
|     } |  | ||||||
|     send_text($random_insult); |  | ||||||
|   } |  | ||||||
|   elseif (isset($command_list[1])){ |  | ||||||
|     $username = $command_list[1]; |  | ||||||
|     if ($username == "@quadnite_bot" || $username == "Quadnite" || $username == "quadnite"){ |  | ||||||
|       send_text("Watch who you talk to.", true); |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       $random_insult = preg_replace('/##name##/', $username, $random_insult); |  | ||||||
|       send_text($random_insult); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   else { |  | ||||||
|     send_text("Do you want to insult yourself?\nIf no, reply to someone with /insult to insult them or run /insult username/name.\nYou can suggest more /kys replies using /feedback", true); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function feedback(){ |  | ||||||
|   global $command_list; |  | ||||||
|   if (isset($command_list[1])){ |  | ||||||
|     forward_message(-1001168939936); |  | ||||||
|     send_text("Thank you for the feedback"); |  | ||||||
|   } |  | ||||||
|   else { |  | ||||||
|     send_text("To send feedback type in /feedback followed by the feedback", true); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Sends back JSON |  | ||||||
| function json() { |  | ||||||
|   global $var; |  | ||||||
|   $pretty_json = json_encode(json_decode($var), JSON_PRETTY_PRINT); |  | ||||||
|   send_text($pretty_json); |  | ||||||
| } |  | ||||||
| // Start Message |  | ||||||
| function start() { |  | ||||||
|   send_text('Hi, I am Quadnite. If you are chatting with me in private, you are most likely doing it wrong. Add me to a group for fun. To give feedback, use /feedback'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function rate() { |  | ||||||
|   send_html('<a href="https://t.me/tgdrbot?start=quadnite_bot">Vote for me on Telegram Directory!</a>'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function help() { |  | ||||||
|   send_html('You can either check /commands for a short overview or check the <a href="https://t.me/quadnite/9">Help Page</a>.'); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function commands() { |  | ||||||
|   send_text(file_get_contents('command_list.txt')); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function weebify() { |  | ||||||
|   global $decoded; |  | ||||||
|   global $command_list; |  | ||||||
|   if(count($command_list) <= 1){ |  | ||||||
|     send_text("Need text to weebify. Send /weebify text", true); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   $letters = array( |  | ||||||
|     "a" => "卂", |  | ||||||
|     "b" => "乃", |  | ||||||
|     "c" => "匚", |  | ||||||
|     "d" => "刀", |  | ||||||
|     "e" => "乇", |  | ||||||
|     "f" => "下", |  | ||||||
|     "g" => "厶", |  | ||||||
|     "h" => "卄", |  | ||||||
|     "i" => "工", |  | ||||||
|     "j" => "丁", |  | ||||||
|     "k" => "长", |  | ||||||
|     "l" => "乚", |  | ||||||
|     "m" => "从", |  | ||||||
|     "n" => "𠘨", |  | ||||||
|     "o" => "口", |  | ||||||
|     "p" => "尸", |  | ||||||
|     "q" => "㔿", |  | ||||||
|     "r" => "尺", |  | ||||||
|     "s" => "丂", |  | ||||||
|     "t" => "丅", |  | ||||||
|     "u" => "凵", |  | ||||||
|     "v" => "リ", |  | ||||||
|     "w" => "山", |  | ||||||
|     "x" => "乂", |  | ||||||
|     "y" => "丫", |  | ||||||
|     "z" => "乙" |  | ||||||
|   ); |  | ||||||
|   $chars = str_split(preg_replace('/^\/[^ ]+ /', '', strtolower($decoded->{"message"}->{"text"}))); |  | ||||||
|   $text = ""; |  | ||||||
|   foreach($chars as $char){ |  | ||||||
|     if(key_exists($char, $letters)) { |  | ||||||
|       $text .= $letters[$char]; |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       $text .= $char; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   send_text($text, true); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function absurdify() { |  | ||||||
|   global $decoded; |  | ||||||
|   global $command_list; |  | ||||||
|   if(count($command_list) <= 1){ |  | ||||||
|     send_text("Need text to absurdify. Send /absurdify text", true); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   $chars = str_split(preg_replace('/^\/[^ ]+ /', '', strtolower($decoded->{"message"}->{"text"}))); |  | ||||||
|   $text = ""; |  | ||||||
|   foreach($chars as $char){ |  | ||||||
|     if (rand(0,1) == 0){ |  | ||||||
|       $text .= strtolower($char); |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       $text .= strtoupper($char); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   send_text($text, true); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Get JSON from post, store it and decode it. |  | ||||||
| $var = file_get_contents('php://input'); |  | ||||||
| $decoded = json_decode($var); |  | ||||||
|  |  | ||||||
| // Store the chat ID |  | ||||||
| $chat_id = $decoded->{"message"}->{"chat"}->{"id"}; |  | ||||||
|  |  | ||||||
| $modules = array( |  | ||||||
|   array( |  | ||||||
|     "command" => "/start", |  | ||||||
|     "function" => "start();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/word", |  | ||||||
|     "function" => "rand_words(1);" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/words", |  | ||||||
|     "function" => "rand_words(0);" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/question", |  | ||||||
|     "function" => "rand_question();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/arch_wiki", |  | ||||||
|     "function" => "media_wiki('https://wiki.archlinux.org/api.php');" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/wiki", |  | ||||||
|     "function" => "media_wiki('https://en.wikipedia.org/w/api.php');" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/coin", |  | ||||||
|     "function" => "coin();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/is", |  | ||||||
|     "function" => "yes_or_no();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/are", |  | ||||||
|     "function" => "yes_or_no();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/can", |  | ||||||
|     "function" => "yes_or_no();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/will", |  | ||||||
|     "function" => "yes_or_no();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/shall", |  | ||||||
|     "function" => "yes_or_no();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/was", |  | ||||||
|     "function" => "yes_or_no();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/does", |  | ||||||
|     "function" => "yes_or_no();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/did", |  | ||||||
|     "function" => "yes_or_no();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/should", |  | ||||||
|     "function" => "yes_or_no();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/do", |  | ||||||
|     "function" => "yes_or_no();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/kys", |  | ||||||
|     "function" => "kys();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/json", |  | ||||||
|     "function" => "json();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/help", |  | ||||||
|     "function" => "help();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/insult", |  | ||||||
|     "function" => "send_insult();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/feedback", |  | ||||||
|     "function" => "feedback();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/rate", |  | ||||||
|     "function" => "rate();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/commands", |  | ||||||
|     "function" => "commands();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/weebify", |  | ||||||
|     "function" => "weebify();" |  | ||||||
|   ), |  | ||||||
|   array( |  | ||||||
|     "command" => "/absurdify", |  | ||||||
|     "function" => "absurdify();" |  | ||||||
|   ) |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| if (!isset($decoded->{"message"}->{"text"})){ |  | ||||||
|   exit(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if (isset($decoded->{"message"}->{"pinned_message"})){ |  | ||||||
|   exit(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| $command_list = explode(" ", $decoded->{"message"}->{"text"}); |  | ||||||
|  |  | ||||||
| foreach ($modules as $module ) { |  | ||||||
|   if (check_command($module["command"])) { |  | ||||||
|     eval($module["function"]); |  | ||||||
|     exit(); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| ?> |  | ||||||
		Reference in New Issue
	
	Block a user