Skip to content
This repository has been archived by the owner on Feb 17, 2019. It is now read-only.

Commit

Permalink
Format
Browse files Browse the repository at this point in the history
  • Loading branch information
lwl12 committed Jan 2, 2019
1 parent 0667f23 commit d886a6b
Show file tree
Hide file tree
Showing 5 changed files with 2,861 additions and 94 deletions.
55 changes: 55 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
"plugins": ["prettier"],
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"env": {
"node": true,
"es6": true
},
"rules": {
"no-console": 0,
"block-scoped-var": 1,
"curly": 1,
"eqeqeq": 1,
"no-global-assign": 1,
"no-implicit-globals": 1,
"no-labels": 1,
"no-multi-str": 1,
"comma-spacing": 1,
"comma-style": 1,
"func-call-spacing": 1,
"keyword-spacing": 1,
"linebreak-style": 1,
"lines-around-comment": 1,
"no-multiple-empty-lines": 1,
"space-infix-ops": 1,
"arrow-spacing": 1,
"no-var": 1,
"prefer-const": 1,
"no-unsafe-negation": 1,
"array-callback-return": 1,
"dot-notation": 1,
"no-eval": 1,
"no-extend-native": 1,
"no-extra-label": 1,
"semi": 1,
"space-before-blocks": 1,
"space-in-parens": 1,
"space-unary-ops": 1,
"spaced-comment": 1,
"arrow-body-style": 1,
"arrow-parens": 1,
"no-restricted-imports": 1,
"no-duplicate-imports": 1,
"no-useless-computed-key": 1,
"no-useless-rename": 1,
"rest-spread-spacing": 1,
"no-trailing-spaces": 1,
"no-control-regex": 0,
"prettier/prettier": 0,
"no-await-in-loop": 1
}
}
7 changes: 7 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"printWidth": 233,
"tabWidth": 4,
"singleQuote": true,
"trailingComma": "es5",
"arrowParens": "always"
}
164 changes: 87 additions & 77 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
require('dotenv').config();
const jwt = require('jsonwebtoken');
const Telegraf = require('telegraf');
const CryptoJS = require("crypto-js");
const CryptoJS = require('crypto-js');
const escapeHtml = require('escape-html');
const request = require('request-promise');
const telegrafAws = require('telegraf-aws');
const commandParts = require('telegraf-command-parts');

const bot = new Telegraf(process.env.BOT_TOKEN, {
telegram: {
webhookReply: false
}
webhookReply: false,
},
});

bot.use(commandParts());
Expand All @@ -20,45 +20,46 @@ bot.telegram.getMe().then((botInfo) => {
});

const updateHandler = telegrafAws(bot, {
timeout: 3000
timeout: 3000,
});


bot.command('start', async (ctx) => {
if (ctx.message.chat.type !== "private") {
if (ctx.message.chat.type !== 'private') {
return 0;
}

try {
const pasteID = ctx.state.command.args;
if (!pasteID) {
ctx.telegram.webhookReply = true;
throw new Error("This bot is only using to verify machine-generated code, you may check out https://github.com/TG-reCAPTCHA/Telegram-reCAPTCHA-Bot for more information.");
throw new Error('This bot is only using to verify machine-generated code, you may check out https://github.com/TG-reCAPTCHA/Telegram-reCAPTCHA-Bot for more information.');
}

const response = await request({
url: 'https://bytebin.lucko.me/' + pasteID,
resolveWithFullResponse: true
resolveWithFullResponse: true,
});
if (response && (response.statusCode !== 200)) {
throw new Error("Error when trying to retrieve payload from Pastebin, you may try to use the backup method provided in the verification page or just rest for a while and try again.\n" +
"Status code: " + (response && response.statusCode));
if (response && response.statusCode !== 200) {
throw new Error(
'Error when trying to retrieve payload from Pastebin, you may try to use the backup method provided in the verification page or just rest for a while and try again.\n' +
'Status code: ' +
(response && response.statusCode)
);
}

const payload = JSON.parse(
CryptoJS.AES.decrypt(response.body, ctx.message.from.id.toString()).toString(CryptoJS.enc.Utf8)
);
const payload = JSON.parse(CryptoJS.AES.decrypt(response.body, ctx.message.from.id.toString()).toString(CryptoJS.enc.Utf8));

if (!payload || !payload.jwt || !payload.gresponse) {
throw new Error();
}

return await verifyUser(payload, ctx);
} catch (err) {
let msg = "Invalid data from Pastebin, please try again later or use the backup method provided in the verification page.";
if (err.__proto__.toString() == 'Error' && err.message) {
if (err.message === "Malformed UTF-8 data") {
msg = "You can't verify account for another person. \nIf you sure you are now trying to verify yourself account instead of others, please try to use the backup method shown in verify page or just rest for a while and try again.";
let msg = 'Invalid data from Pastebin, please try again later or use the backup method provided in the verification page.';
if (err.__proto__.toString() === 'Error' && err.message) {
if (err.message === 'Malformed UTF-8 data') {
msg =
"You can't verify account for another person. \nIf you sure you are now trying to verify yourself account instead of others, please try to use the backup method shown in verify page or just rest for a while and try again.";
} else {
msg = err.message;
}
Expand All @@ -69,14 +70,14 @@ bot.command('start', async (ctx) => {
});

bot.command('verify', async (ctx) => {
if (ctx.message.chat.type !== "private") {
if (ctx.message.chat.type !== 'private') {
return 0;
}

try {
if (!ctx.state.command.args) {
ctx.telegram.webhookReply = true;
throw new Error("This bot is only using to verify machine-generated code, you may check out https://github.com/TG-reCAPTCHA/Telegram-reCAPTCHA-Bot for more information.");
throw new Error('This bot is only using to verify machine-generated code, you may check out https://github.com/TG-reCAPTCHA/Telegram-reCAPTCHA-Bot for more information.');
}

const payload = JSON.parse(new Buffer(ctx.state.command.args, 'base64').toString());
Expand All @@ -87,53 +88,60 @@ bot.command('verify', async (ctx) => {

return await verifyUser(payload, ctx);
} catch (err) {
var msg = "Invalid data, please try again later.";
if (err.__proto__.toString() == 'Error' && err.message) msg = err.message;
let msg = 'Invalid data, please try again later.';
if (err.__proto__.toString() === 'Error' && err.message) {
msg = err.message;
}
ctx.replyWithMarkdown(msg);
return 1;
}
});

bot.on('new_chat_members', async (ctx) => {
ctx.message.new_chat_members.filter(({
is_bot
}) => !is_bot).forEach(user => {
ctx.telegram.restrictChatMember(ctx.message.chat.id, user.id);
});

// Pre-reply user joins message, record message id to JWT for subsequent deletion operation.
ctx.message.new_chat_members.filter(({
is_bot
}) => !is_bot).forEach(async user => {
const {
message_id
} = await ctx.reply("Processing...", {
"reply_to_message_id": ctx.message.message_id
ctx.message.new_chat_members
.filter(({ is_bot }) => !is_bot)
.forEach((user) => {
ctx.telegram.restrictChatMember(ctx.message.chat.id, user.id);
});

const jwtoken = jwt.sign({
exp: Math.floor(Date.now() / 1000) + (60 * 10),
data: {
mid: message_id,
uid: user.id.toString(),
gid: ctx.message.chat.id.toString(),
gname: encodeURIComponent(ctx.message.chat.title)
}
}, process.env.JWT_SECRET);

const msg = `Dear <a href="tg://user?id=${user.id.toString()}">${escapeHtml(user.first_name)}</a>, with our Anti-SPAM policy, we kindly inform you that you need to click the following button to prove your human identity.\n\nThis link will only valid in 10 minutes, please complete verification as soon as possible, thanks for your cooperation.`;
ctx.telegram.editMessageText(ctx.message.chat.id, message_id, undefined, msg, {
parse_mode: "HTML",
reply_markup: JSON.stringify({
"inline_keyboard": [
[{
"text": "Go to verification page",
"url": "https://tg-recaptcha.github.io/#" + jwtoken + ";" + bot.options.username + ";" + process.env.G_SITEKEY
}]
]
})
// Pre-reply user joins message, record message id to JWT for subsequent deletion operation.
ctx.message.new_chat_members
.filter(({ is_bot }) => !is_bot)
.forEach(async (user) => {
const { message_id } = await ctx.reply('Processing...', {
reply_to_message_id: ctx.message.message_id,
});

const jwtoken = jwt.sign(
{
exp: Math.floor(Date.now() / 1000) + 60 * 10,
data: {
mid: message_id,
uid: user.id.toString(),
gid: ctx.message.chat.id.toString(),
gname: encodeURIComponent(ctx.message.chat.title),
},
},
process.env.JWT_SECRET
);

const msg = `Dear <a href="tg://user?id=${user.id.toString()}">${escapeHtml(
user.first_name
)}</a>, with our Anti-SPAM policy, we kindly inform you that you need to click the following button to prove your human identity.\n\nThis link will only valid in 10 minutes, please complete verification as soon as possible, thanks for your cooperation.`;
ctx.telegram.editMessageText(ctx.message.chat.id, message_id, undefined, msg, {
parse_mode: 'HTML',
reply_markup: JSON.stringify({
inline_keyboard: [
[
{
text: 'Go to verification page',
url: 'https://tg-recaptcha.github.io/#' + jwtoken + ';' + bot.options.username + ';' + process.env.G_SITEKEY,
},
],
],
}),
});
});
});

return 0;
});
Expand All @@ -142,20 +150,21 @@ async function verifyUser(payload, ctx) {
try {
const requestInfo = jwt.verify(payload.jwt, process.env.JWT_SECRET);
if (requestInfo.data.uid !== ctx.message.from.id.toString()) {
throw new Error("You can't verify account for another person. (`" + requestInfo.data.uid + "`, `" + ctx.message.from.id + "`)");
throw new Error("You can't verify account for another person. (`" + requestInfo.data.uid + '`, `' + ctx.message.from.id + '`)');
}

const response = await request.post({
url: 'https://www.google.com/recaptcha/api/siteverify',
form: {
secret: process.env.G_SECRETKEY,
response: payload.gresponse
response: payload.gresponse,
},
resolveWithFullResponse: true
resolveWithFullResponse: true,
});
if (response && (response.statusCode !== 200)) {
throw new Error("Error when trying to connect Google verification servers, you may try to use the backup method shown in verify page or just rest for a while and try again.\n" +
"Status code: " + (response && response.statusCode));
if (response && response.statusCode !== 200) {
throw new Error(
'Error when trying to connect Google verification servers, you may try to use the backup method shown in verify page or just rest for a while and try again.\n' + 'Status code: ' + (response && response.statusCode)
);
}

const result = JSON.parse(response.body);
Expand All @@ -164,24 +173,25 @@ async function verifyUser(payload, ctx) {
}

ctx.telegram.restrictChatMember(requestInfo.data.gid, requestInfo.data.uid, {
"can_send_messages": true,
"can_send_media_messages": true,
"can_send_other_messages": true,
"can_add_web_page_previews": true
can_send_messages: true,
can_send_media_messages: true,
can_send_other_messages: true,
can_add_web_page_previews: true,
});
//ctx.telegram.deleteMessage(requestInfo.data.gid, requestInfo.data.mid);
// ctx.telegram.deleteMessage(requestInfo.data.gid, requestInfo.data.mid);
ctx.telegram.editMessageText(requestInfo.data.gid, requestInfo.data.mid, undefined, `Passed. Verification takes: \`${Math.floor(new Date() / 1000) - requestInfo.iat}s\``, {
parse_mode: "markdown",
parse_mode: 'markdown',
reply_markup: JSON.stringify({
"inline_keyboard": []
})
inline_keyboard: [],
}),
});
ctx.replyWithHTML(`Congratulations~ We already verified you, now you can enjoy your chatting with <code>${escapeHtml(decodeURIComponent(requestInfo.data.gname))}</code>'s members!`);
return 0;
} catch (err) {
var msg = "Sorry, but we can't verify you now. You may like to quit and rejoin the group and try again.\n\n" +
"Technical details: ```" + err + "```";
if (err.__proto__.toString() == 'Error' && err.message) msg = err.message;
let msg = "Sorry, but we can't verify you now. You may like to quit and rejoin the group and try again.\n\n" + 'Technical details: ```' + err + '```';
if (err.__proto__.toString() === 'Error' && err.message) {
msg = err.message;
}
ctx.replyWithMarkdown(msg);
return 1;
}
Expand All @@ -192,6 +202,6 @@ exports.handler = (event, ctx, callback) => {
};

if (!(process.env.LAMBDA_TASK_ROOT && process.env.AWS_EXECUTION_ENV)) {
console.log("Start Polling...");
console.log('Start Polling...');
bot.startPolling();
}
}
16 changes: 16 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@
"repository": "https://github.com/TG-reCAPTCHA/Telegram-reCAPTCHA-Bot.git",
"author": "lwl12 <i@lwl12.com>",
"license": "MIT",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"format": "eslint \"index.js\" --fix && prettier \"index.js\" --write",
"lint": "eslint \"index.js\" && prettier-check \"index.js\"",
"test": "yarn run lint"
},
"devDependencies": {
"eslint": "5.11.1",
"eslint-config-prettier": "3.3.0",
"eslint-plugin-prettier": "3.0.1",
"lint-staged": "8.1.0",
"nodemon": "1.18.9",
"prettier": "1.15.3",
"prettier-check": "2.0.0"
},
"dependencies": {
"crypto-js": "^3.1.9-1",
"dotenv": "^6.2.0",
Expand Down
Loading

0 comments on commit d886a6b

Please sign in to comment.