diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..63276e5 --- /dev/null +++ b/README.MD @@ -0,0 +1,17 @@ +# PHOTO RESIZE BOT # + +Telegram bot for resize image using telegraf + + +## INSTALLATION ## + + talk to BOT Father with /newbot + + place BOT_TOKEN to .env + + npm install && npm start + +## Contribution ## + +Feel free to folk & create pr 😁 + diff --git a/bot.js b/bot.js deleted file mode 100644 index e69de29..0000000 diff --git a/index.js b/index.js index d129945..8fdc062 100644 --- a/index.js +++ b/index.js @@ -15,237 +15,33 @@ const i18n = new I18n({ defaultLocale: 'en' }) -const { BOT_TOKEN, WEBHOOK_URL } = process.env +const token = process.env.BOT_TOKEN const PORT = process.env.PORT || 3003 -//if (!WEBHOOK_URL) throw new Error('"WEBHOOK_URL" env var is required!') -if (!BOT_TOKEN) throw new Error('"BOT_TOKEN" env var is required!') +if (!token) throw new Error('"BOT_TOKEN" env var is required!') -const bot = new Telegraf(BOT_TOKEN) +const bot = new Telegraf(token) const app = fastify() const SECRET_PATH = `/sec/${bot.secretPathComponent()}` app.post(SECRET_PATH, (req, rep) => bot.handleUpdate(req.body, rep.raw)) -let current_step = 0 -let img_width, img_height, img_type, img_id, list_img_id - - -/* bot.start((ctx) => { - bot.telegram.getChat(ctx.message.chat.id) - .then(chat => { - //console.log(chat) - }) - .catch(err => console.error(err)) - - ctx.reply('Welcome to πŸ’— Resize Image Bot πŸ”₯ \nYou can use this bot to resize any image you want.', replyMarkup) -}) */ -/* -bot.command('help', (ctx) => { - ctx.reply(`1. Using /resize to start resizing process.\n2. Input your Image.\n3. Input your desired size.\n4. Input your output type.`) -}) - -bot.command('language', async (ctx) => { - return await ctx.reply('Please choose your language', - { - reply_markup: { - inline_keyboard: [ - - [ { text: 'πŸ‡¬πŸ‡§ English', callback_data: 'langus' }, { text: 'πŸ‡»πŸ‡³ VietNam', callback_data: 'langvn' } ], - - [ { text: "πŸ‡«πŸ‡· FranΓ§ais", callback_data: "langfr" }, { text: 'πŸ‡―πŸ‡΅ Feedback', callback_data: 'langjp' } ] - ] - } - } - ) -}) -bot.command('resize', (ctx) => { - current_step = 1 - ctx.reply(`Please send your image πŸ–ΌοΈ :`) -}) - -bot.action('resize', (ctx) => { - current_step = 1 - ctx.reply(`Please send your image πŸ–ΌοΈ :`) -}) -bot.action('premium', (ctx) => { - ctx.reply(`We are working on premium feature πŸ‘·`) -}) - -bot.action('PNG', (ctx) => { - if (current_step === 4) { - current_step = 0 - args = { - ctx, - fileId: img_id, - width: img_width, - height: img_height, - type: "png" - } - - convertImage(args) - } else { - ctx.reply(i18n.__('resize_more')) - } -}) -bot.action('JPG', (ctx) => { - if (current_step === 4) { - current_step = 0 - args = { - ctx, - fileId: img_id, - width: img_width, - height: img_height, - type: "jpg" - } - - convertImage(args) - } else { - ctx.reply(i18n.__('resize_more')) - } -}) -bot.action('GIF', (ctx) => { - if (current_step === 4) { - current_step = 0 - args = { - ctx, - fileId: img_id, - width: img_width, - height: img_height, - type: "gif" - } - - convertImage(args) - } else { - ctx.reply(i18n.__('resize_more')) - } -}) -bot.action('BMP', (ctx) => { - if (current_step === 4) { - current_step = 0 - args = { - ctx, - fileId: img_id, - width: img_width, - height: img_height, - type: "bmp" - } - - convertImage(args) - } else { - ctx.reply(i18n.__('resize_more')) - } -}) - -bot.on('message', (ctx) => { - - console.log(ctx.update.message) - switch (current_step) { - case 1: - if (ctx.update.message.media_group_id) { - ctx.reply(`We will use your last πŸ–ΌοΈ :`) - } else { - if (ctx.update.message.photo) { - const files = ctx.update.message.photo - if (files) { - // I am getting the bigger image - img_id = files[files.length - 1].file_id - // Proceed downloading - } - current_step = 2 - ctx.reply(` - Your desired Image Width (px) πŸ“: - `) - } else if (ctx.update.message.document) { - current_step = 2 - img_id = ctx.update.message.document.file_id - ctx.reply(` - Your desired Image Width (px) πŸ“: - `) - } else { - ctx.reply(`Please send your image πŸ–ΌοΈ :`) - } - } - break - case 2: - if (isNumeric(ctx.update.message.text)) { - img_width = Number(ctx.update.message.text) - current_step = 3 - ctx.reply(` - Your desired Image Height (px) πŸ“ : - `) - } else { - ctx.reply(` - Your desired Image Width (px) (Number only) πŸ“: - `) - } - break - case 3: - if (isNumeric(ctx.update.message.text)) { - img_height = Number(ctx.update.message.text) - current_step = 4 - ctx.reply(` - Your desired Image type πŸ“ : - `, { - reply_markup: { - inline_keyboard: [ - - [ { text: "PNG", callback_data: "PNG" } ], - [ { text: "JPG", callback_data: "JPG" } ], - [ { text: "GIF", callback_data: "GIF" } ], - [ { text: "BMP", callback_data: "BMP" } ] - ] - } - }) - } else { - ctx.reply(` - Your desired Image Height (px) (Number only) πŸ“ : - `) - } - break - case 4: - - break - - default: - ctx.reply('Welcome to πŸ’— Resize Image Bot πŸ”₯ \nYou can use this bot to resize any image you want.', replyMarkup) - break - } -}) - -bot.on('inline_query', (ctx) => { - const result = [] - // Explicit usage - ctx.telegram.answerInlineQuery(ctx.inlineQuery.id, result) - - // Using context shortcut - ctx.answerInlineQuery(result) -}) - -bot.on('callback_query', (ctx) => { - // Explicit usage - ctx.telegram.answerCbQuery(ctx.callbackQuery.id) - console.log(ctx.callbackQuery) - // Using context shortcut - ctx.answerCbQuery() -}) -*/ const isNumeric = (str) => { if (typeof str != "string") return false // we only process strings! return !isNaN(str) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)... !isNaN(parseFloat(str)) // ...and ensure strings of whitespace fail } const convertImage = async (args) => { - const { ctx, fileId, width, height, type } = args - if (fileId && height && height) { - ctx.telegram.getFileLink(fileId).then( async (url) => { + const { ctx, type } = args + if (ctx.scene.session.imageData.fileId && ctx.scene.session.imageData.img_width && ctx.scene.session.imageData.img_height) { + ctx.telegram.getFileLink(ctx.scene.session.imageData.fileId).then( async (url) => { try { - const inputBuffer = (await axios({ url: url.href, responseType: "arraybuffer" })).data + const inputBuffer = (axios({ url: url.href, responseType: "arraybuffer" })).data switch (type) { case "png": sharp(inputBuffer) - .resize(width, height) + .resize(ctx.scene.session.imageData.img_width, ctx.scene.session.imageData.img_height) .toFile(`./public/images/profiles/${ctx.update.update_id}.${type}`, (err, info) => { if (!err) { current_step = 0 @@ -262,7 +58,7 @@ const convertImage = async (args) => { break case "jpg": sharp(inputBuffer) - .resize(width, height) + .resize(ctx.scene.session.imageData.img_width, ctx.scene.session.imageData.img_height) .jpeg({ mozjpeg: true }) .toFile(`./public/images/profiles/${ctx.update.update_id}.${type}`, (err, info) => { if (!err) { @@ -280,7 +76,7 @@ const convertImage = async (args) => { break case "gif": sharp(inputBuffer) - .resize(width, height) + .resize(ctx.scene.session.imageData.img_width, ctx.scene.session.imageData.img_height) .toFile(`./public/images/profiles/${ctx.update.update_id}.${type}`, (err, info) => { if (!err) { current_step = 0 @@ -297,7 +93,7 @@ const convertImage = async (args) => { break case "bmp": sharp(inputBuffer) - .resize(width, height) + .resize(ctx.scene.session.imageData.img_width, ctx.scene.session.imageData.img_height) .toFile(`./public/images/profiles/${ctx.update.update_id}.${type}`, (err, info) => { if (!err) { current_step = 0 @@ -346,14 +142,10 @@ bot.start((ctx) => { }) - const resizeStepHandler = new Composer() resizeStepHandler.action('png', async (ctx) => { args = { ctx, - fileId: img_id, - width: img_width, - height: img_height, type: "png" } return await convertImage(args) @@ -361,9 +153,6 @@ resizeStepHandler.action('png', async (ctx) => { resizeStepHandler.action('jpg', async (ctx) => { args = { ctx, - fileId: img_id, - width: img_width, - height: img_height, type: "jpg" } return await convertImage(args) @@ -371,9 +160,6 @@ resizeStepHandler.action('jpg', async (ctx) => { resizeStepHandler.action('gif', async (ctx) => { args = { ctx, - fileId: img_id, - width: img_width, - height: img_height, type: "gif" } return await convertImage(args) @@ -381,9 +167,6 @@ resizeStepHandler.action('gif', async (ctx) => { resizeStepHandler.action('bmp', async (ctx) => { args = { ctx, - fileId: img_id, - width: img_width, - height: img_height, type: "bmp" } return await convertImage(args) @@ -391,33 +174,30 @@ resizeStepHandler.action('bmp', async (ctx) => { const resizeWizard = new Scenes.WizardScene('resize-wizard', async (ctx) => { - await ctx.reply(i18n.__('send_image')) - /* //Necessary for store the input - ctx.scene.session.user = {} - //Store the telegram user id - ctx.scene.session.user.userId = ctx.from.id */ + ctx.reply(i18n.__('send_image')) + ctx.scene.session.imageData = {} return ctx.wizard.next() }, async (ctx) => { console.log('step img: ', ctx.message) //Validate the photo if (ctx.message.media_group_id) { - await ctx.reply(`We will use your last πŸ–ΌοΈ :`) + ctx.reply(`We will use your last πŸ–ΌοΈ :`) } else { if (ctx.message.photo) { const files = ctx.message.photo if (files) { - img_id = files[files.length - 1].file_id + ctx.scene.session.imageData.fileId = files[files.length - 1].file_id } - await ctx.reply(i18n.__('input_image_width')) + ctx.reply(i18n.__('input_image_width')) return ctx.wizard.next() } else if (ctx.message.document) { - img_id = ctx.message.document.file_id - await ctx.reply(i18n.__('input_image_width')) + ctx.scene.session.imageData.fileId = ctx.message.document.file_id + ctx.reply(i18n.__('input_image_width')) return ctx.wizard.next() } else { - await ctx.reply(i18n.__('send_image')) + ctx.reply(i18n.__('send_image')) console.log( 'no image' ) @@ -427,7 +207,7 @@ const resizeWizard = new Scenes.WizardScene('resize-wizard', (ctx) => { //Validate width if (isNumeric(ctx.message.text)) { - img_width = Number(ctx.message.text) + ctx.scene.session.imageData.img_width = Number(ctx.message.text) ctx.reply(i18n.__('input_image_height')) return ctx.wizard.next() } else { @@ -437,8 +217,8 @@ const resizeWizard = new Scenes.WizardScene('resize-wizard', }, async (ctx) => { if (isNumeric(ctx.update.message.text)) { - img_height = Number(ctx.update.message.text) - await ctx.reply(i18n.__('input_image_type'), { + ctx.scene.session.imageData.img_height = Number(ctx.update.message.text) + ctx.reply(i18n.__('input_image_type'), { reply_markup: { inline_keyboard: [ @@ -451,7 +231,7 @@ const resizeWizard = new Scenes.WizardScene('resize-wizard', }) return ctx.wizard.next() } else { - await ctx.reply(i18n.__('input_image_height_note')) + ctx.reply(i18n.__('input_image_height_note')) } }, @@ -466,32 +246,26 @@ const languageChangeHandler = new Composer() languageChangeHandler.action('langus', async (ctx) => { i18n.setLocale('en') ctx.reply(i18n.__('saved_language')) - return ctx.scene.leave() + return ctx.wizard.next() }) languageChangeHandler.action('langvn', async (ctx) => { i18n.setLocale('vn') ctx.reply(i18n.__('saved_language')) - return ctx.scene.leave() + return ctx.wizard.next() }) languageChangeHandler.action('langfr', async (ctx) => { i18n.setLocale('fr') ctx.reply(i18n.__('saved_language')) - return ctx.scene.leave() + return ctx.wizard.next() }) languageChangeHandler.action('langjp', async (ctx) => { i18n.setLocale('jp') ctx.reply(i18n.__('saved_language')) - return ctx.scene.leave() + return ctx.wizard.next() }) const languageWizard = new Scenes.WizardScene('language-wizard', async (ctx) => { - await ctx.reply(i18n.__('choose_language'), - /* Markup.keyboard( - [ - [ Markup.button.callback('πŸ‡¬πŸ‡§ English', 'langus'), Markup.button.callback('πŸ‡»πŸ‡³ TiαΊΏng Việt', 'langvn') ], - [ Markup.button.callback('πŸ‡«πŸ‡· FranΓ§ais', 'langfr'), Markup.button.callback('πŸ‡―πŸ‡΅ ζ—₯本', 'langjp') ] - ] - ) */ + ctx.reply(i18n.__('choose_language'), { reply_markup: { inline_keyboard: [ @@ -503,12 +277,14 @@ const languageWizard = new Scenes.WizardScene('language-wizard', ) return ctx.wizard.next() }, - languageChangeHandler + languageChangeHandler, + (ctx) => { + return ctx.scene.leave() //<- Leaving a scene will clear the session automatically + } ) - - const stage = new Scenes.Stage([resizeWizard, languageWizard]) + bot.use(session()) bot.use(stage.middleware()) bot.command('/resize', (ctx) => ctx.scene.enter('resize-wizard')) @@ -517,10 +293,6 @@ bot.action('resize', (ctx) => ctx.scene.enter('resize-wizard') ) bot.launch() -/* bot.telegram.setWebhook(WEBHOOK_URL + SECRET_PATH).then(() => { - console.log('Webhook is set on', WEBHOOK_URL) -}) */ - app.listen(PORT).then(() => { console.log('Listening on port', PORT) }) \ No newline at end of file diff --git a/locales/fr.json b/locales/fr.json index 1aa81de..e070182 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -1,4 +1,17 @@ { - "saved_language": "Thanks, your language has been saved.", - "resize_more": "Do you want to resize more πŸ”₯ ? /resize" + "saved_language": "Merci, your language has been saved.", + "resize_more": "Do you want to resize more πŸ”₯ ? /resize", + "start_resize": "Start Resize", + "premium": "Premium", + "welcome_message": "Welcome to πŸ’— Resize Image Bot πŸ”₯ \nYou can use this bot to resize any image you want.", + "send_image": "Please send your image πŸ–ΌοΈ :", + "input_image_width": "Your desired Image Width (px) πŸ“:", + "input_image_width_note": "Your desired Image Width (px) (Number only) πŸ“:", + "input_image_height": "Your desired Image Height (px) πŸ“ :", + "input_image_height_note": "Your desired Image Height (px) (Number only) πŸ“ :", + "input_image_type": "Your desired Image type πŸ“ :", + "choose_language": "Please choose your language", + "resize_output_error": "Error, please try another output 😣", + "resize_error": "Can not convert your Image ! Please try again 😫", + "resized_caption": "Here is your image πŸ₯°" } \ No newline at end of file diff --git a/locales/ja.json b/locales/ja.json deleted file mode 100644 index 9e26dfe..0000000 --- a/locales/ja.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/locales/jp.json b/locales/jp.json index 1aa81de..dbd7ec7 100644 --- a/locales/jp.json +++ b/locales/jp.json @@ -1,4 +1,17 @@ { "saved_language": "Thanks, your language has been saved.", - "resize_more": "Do you want to resize more πŸ”₯ ? /resize" + "resize_more": "Do you want to resize more πŸ”₯ ? /resize", + "start_resize": "Start Resize", + "premium": "Premium", + "welcome_message": "Welcome to πŸ’— Resize Image Bot πŸ”₯ \nYou can use this bot to resize any image you want.", + "send_image": "Please send your image πŸ–ΌοΈ :", + "input_image_width": "Your desired Image Width (px) πŸ“:", + "input_image_width_note": "Your desired Image Width (px) (Number only) πŸ“:", + "input_image_height": "Your desired Image Height (px) πŸ“ :", + "input_image_height_note": "Your desired Image Height (px) (Number only) πŸ“ :", + "input_image_type": "Your desired Image type πŸ“ :", + "choose_language": "Please choose your language", + "resize_output_error": "Error, please try another output 😣", + "resize_error": "Can not convert your Image ! Please try again 😫", + "resized_caption": "Here is your image πŸ₯°" } \ No newline at end of file diff --git a/package.json b/package.json index fbcfa8b..6b6b589 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "", "main": "index.js", "scripts": { + "start": "node index.js", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { diff --git a/payment.js b/payment.js deleted file mode 100644 index e69de29..0000000