#include <MsgBoxConstants.au3> ; to declare the Constants of MsgBox
Local $sRegex = "(?m)\/\*\*?\s*([\W\w]*?)\s*\*\/|\/\/\s*(.*)$"
Local $sString = "/**" & @CRLF & _
" * The Crypto Info Bot" & @CRLF & _
" *" & @CRLF & _
" * @author Denis Efremov <efremov.a.denis@gmail.com>" & @CRLF & _
" */" & @CRLF & _
"require('dotenv').load()" & @CRLF & _
"" & @CRLF & _
"const axios = require('axios')" & @CRLF & _
"const winston = require('winston')" & @CRLF & _
"const { inspect } = require('util')" & @CRLF & _
"const Telegraf = require('telegraf')" & @CRLF & _
"" & @CRLF & _
"const { session } = Telegraf" & @CRLF & _
"const {" & @CRLF & _
" API_URL," & @CRLF & _
" BOT_TOKEN," & @CRLF & _
" BOT_USERNAME," & @CRLF & _
" PAGE_SIZE," & @CRLF & _
" FIXED_LENGTH," & @CRLF & _
"} = process.env" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * Debug helper" & @CRLF & _
" *" & @CRLF & _
" * @param {Mixed} data The data" & @CRLF & _
" * @return {Mixed}" & @CRLF & _
" */" & @CRLF & _
"const debug = (data) => console.log(inspect(data, {" & @CRLF & _
" showHidden: true," & @CRLF & _
" colors: true," & @CRLF & _
" depth: 10," & @CRLF & _
"}))" & @CRLF & _
"" & @CRLF & _
"const logger = winston.createLogger({" & @CRLF & _
" level: 'info'," & @CRLF & _
" format: winston.format.json()," & @CRLF & _
" transports: [" & @CRLF & _
" new winston.transports.File({ filename: 'log/error.log', level: 'error' })," & @CRLF & _
" new winston.transports.File({ filename: 'log/combined.log' })," & @CRLF & _
" ]," & @CRLF & _
"})" & @CRLF & _
"" & @CRLF & _
"const formattedTime = (date) => date.toTimeString()" & @CRLF & _
"const formattedDate = (date) => date.toDateString()" & @CRLF & _
"const formattedDateTime = (date) => \`${formattedDate(date)} ${formattedTime(date)}\`" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * Create a new bot instance" & @CRLF & _
" *" & @CRLF & _
" * @type {Telegraf}" & @CRLF & _
" */" & @CRLF & _
"const bot = new Telegraf(BOT_TOKEN, { username: BOT_USERNAME })" & @CRLF & _
"" & @CRLF & _
"bot.use(session())" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * Render pagination buttons" & @CRLF & _
" *" & @CRLF & _
" * @param {String} ns The namespace" & @CRLF & _
" * @param {Number} page The page" & @CRLF & _
" * @param {Number} total The total" & @CRLF & _
" * @return {Object} Message parameters" & @CRLF & _
" */" & @CRLF & _
"const pagination = (namespace, page, total) => ({" & @CRLF & _
" reply_markup: {" & @CRLF & _
" inline_keyboard: [[" & @CRLF & _
" page !== 0" & @CRLF & _
" ? { text: `< Prev ${PAGE_SIZE}`, callback_data: `/${namespace}/prev` }" & @CRLF & _
" : { text: '----------', callback_data: '/noop' }," & @CRLF & _
" {" & @CRLF & _
" text: `${page * PAGE_SIZE} - ${(page + 1) * PAGE_SIZE} (${total})`," & @CRLF & _
" callback_data: '/noop'," & @CRLF & _
" }," & @CRLF & _
" page !== (total / PAGE_SIZE) - 1" & @CRLF & _
" ? { text: `Next ${PAGE_SIZE} >`, callback_data: `/${namespace}/next` }" & @CRLF & _
" : { text: '----------', callback_data: '/noop' }," & @CRLF & _
" ]]," & @CRLF & _
" }," & @CRLF & _
"})" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * Gets the rates." & @CRLF & _
" *" & @CRLF & _
" * @param {Number} start The start" & @CRLF & _
" * @param {Number} limit The limit" & @CRLF & _
" * @return {Promise} The rates" & @CRLF & _
" */" & @CRLF & _
"const getRates = (start, limit) => {" & @CRLF & _
" let url = `${API_URL}?convert=RUB`" & @CRLF & _
"" & @CRLF & _
" if (limit) {" & @CRLF & _
" url += `&limit=${limit}`" & @CRLF & _
" }" & @CRLF & _
"" & @CRLF & _
" if (start) {" & @CRLF & _
" url += `&start=${start}`" & @CRLF & _
" }" & @CRLF & _
"" & @CRLF & _
" return axios.get(url)" & @CRLF & _
"}" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * Gets the rate." & @CRLF & _
" *" & @CRLF & _
" * @param {String} asset The asset" & @CRLF & _
" * @return {Promise} The rate" & @CRLF & _
" */" & @CRLF & _
"const getRate = (asset) => axios.get(`${API_URL}${asset}/?convert=RUB`)" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * A currency message template" & @CRLF & _
" *" & @CRLF & _
" * @param {Object} rate The rate object" & @CRLF & _
" * @param {String} rate.name The name" & @CRLF & _
" * @param {String} rate.symbol The symbol" & @CRLF & _
" * @param {Number} rate.price_usd The price usd" & @CRLF & _
" * @param {Number} rate.price_rub The price rub" & @CRLF & _
" * @param {Number} rate.percent_change_1h:hour The percent change 1 h hour" & @CRLF & _
" * @param {Number} rate.percent_change_24h:day The percent change 24 h day" & @CRLF & _
" * @param {Number} rate.percent_change_7d:week The percent change 7 d week" & @CRLF & _
" * @return {String}" & @CRLF & _
" */" & @CRLF & _
"const templateMd = ({" & @CRLF & _
" name, symbol, price_usd, price_rub," & @CRLF & _
" percent_change_1h: hour," & @CRLF & _
" percent_change_24h: day," & @CRLF & _
" percent_change_7d: week," & @CRLF & _
"}) => `${name} *(${symbol})* \`!${symbol.toLowerCase()}\`" & @CRLF & _
"\`\`\`" & @CRLF & _
"==================" & @CRLF & _
"$ ${price_usd}" & @CRLF & _
"₽ ${price_rub}" & @CRLF & _
"==================" & @CRLF & _
"${hour > 0 ? '+' : ''}${parseFloat(hour).toFixed(FIXED_LENGTH)}% / 1h" & @CRLF & _
"${day > 0 ? '+' : ''}${parseFloat(day).toFixed(FIXED_LENGTH)}% / 24h" & @CRLF & _
"${week > 0 ? '+' : ''}${parseFloat(week).toFixed(FIXED_LENGTH)}% / 7d" & @CRLF & _
"\`\`\``" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * A currency message small template" & @CRLF & _
" *" & @CRLF & _
" * @param {Object} rate The rate object" & @CRLF & _
" * @param {String} rate.name The name" & @CRLF & _
" * @param {String} rate.symbol The symbol" & @CRLF & _
" * @param {Number} rate.price_usd The price usd" & @CRLF & _
" * @param {Number} rate.price_rub The price rub" & @CRLF & _
" * @return {String}" & @CRLF & _
" */" & @CRLF & _
"const smallTemplateMd = ({ name, symbol, price_usd, price_rub }) => `" & @CRLF & _
"${name} *(${symbol})* \`!${symbol.toLowerCase()}\`" & @CRLF & _
"\`\`\`" & @CRLF & _
"$ ${price_usd} | ₽ ${price_rub}" & @CRLF & _
"\`\`\``" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * Map command listaners" & @CRLF & _
" *" & @CRLF & _
" * @param {Object[]} rates The rates" & @CRLF & _
" * @return {Promise}" & @CRLF & _
" */" & @CRLF & _
"const mapCommands = async (/*rates*/) => rates.reduce((acc, rate) => {" & @CRLF & _
" const command = rate.symbol.toLowerCase()" & @CRLF & _
"" & @CRLF & _
" bot.hears(`!${command}`, async (ctx) => {" & @CRLF & _
" let intervalId" & @CRLF & _
" let response = await getRate(ctx.index[command]).catch((error) => {" & @CRLF & _
" debug(error)" & @CRLF & _
" clearInterval(intervalId)" & @CRLF & _
" })" & @CRLF & _
" let text = templateMd(response.data[0])" & @CRLF & _
" let message = await ctx.replyWithMarkdown(" & @CRLF & _
" `${text}" & @CRLF & _
"Updated: ${formattedTime(new Date()).slice(0, 8)}`" & @CRLF & _
" ).catch((error) => {" & @CRLF & _
" debug(error)" & @CRLF & _
" clearInterval(intervalId)" & @CRLF & _
" })" & @CRLF & _
"" & @CRLF & _
" message.text = text" & @CRLF & _
"" & @CRLF & _
" intervalId = setInterval(async () => {" & @CRLF & _
" response = await getRate(ctx.index[command]).catch((error) => {" & @CRLF & _
" debug(error)" & @CRLF & _
" clearInterval(intervalId)" & @CRLF & _
" })" & @CRLF & _
"" & @CRLF & _
" text = templateMd(response.data[0])" & @CRLF & _
"" & @CRLF & _
" if (text === message.text) {" & @CRLF & _
" return" & @CRLF & _
" }" & @CRLF & _
"" & @CRLF & _
" message = await ctx.tg.editMessageText(" & @CRLF & _
" ctx.chat.id," & @CRLF & _
" message.message_id," & @CRLF & _
" undefined," & @CRLF & _
" `${text}" & @CRLF & _
"Updated: ${formattedTime(new Date()).slice(0, 8)}`," & @CRLF & _
" { parse_mode: 'Markdown' }" & @CRLF & _
" ).catch((error) => {" & @CRLF & _
" debug(error)" & @CRLF & _
" clearInterval(intervalId)" & @CRLF & _
" })" & @CRLF & _
" message.text = text" & @CRLF & _
" }, 5000)" & @CRLF & _
" })" & @CRLF & _
"" & @CRLF & _
" acc[command] = rate.id" & @CRLF & _
"" & @CRLF & _
" return acc" & @CRLF & _
"}, {})" & @CRLF & _
"" & @CRLF & _
"bot.use((ctx, next) => {" & @CRLF & _
" logger.log({ level: 'info', message: ctx.message })" & @CRLF & _
" debug(ctx.message)" & @CRLF & _
" next()" & @CRLF & _
"})" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * The rates command" & @CRLF & _
" *" & @CRLF & _
" * @param {TelegrafContext} ctx The bot's context" & @CRLF & _
" */" & @CRLF & _
"bot.hears('!rates', async (ctx) => {" & @CRLF & _
" ctx.session.ratesPage = ctx.session.ratesPage || 0" & @CRLF & _
"" & @CRLF & _
" const { data } = await getRates(" & @CRLF & _
" ctx.session.ratesPage * PAGE_SIZE," & @CRLF & _
" (ctx.session.ratesPage * PAGE_SIZE) + PAGE_SIZE" & @CRLF & _
" )" & @CRLF & _
"" & @CRLF & _
" await ctx.replyWithMarkdown(" & @CRLF & _
" data.map(smallTemplateMd).join('')," & @CRLF & _
" pagination('rates', ctx.session.ratesPage, Object.keys(ctx.index).length)," & @CRLF & _
" ).catch(debug)" & @CRLF & _
"})" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * The time command" & @CRLF & _
" *" & @CRLF & _
" * @param {TelegrafContext} ctx The bot's context" & @CRLF & _
" */" & @CRLF & _
"bot.hears('!time', async (ctx) => {" & @CRLF & _
" const message = await ctx.replyWithMarkdown(formattedDateTime(new Date()))" & @CRLF & _
" .catch(debug)" & @CRLF & _
"" & @CRLF & _
" const intervalId = setInterval(async () => {" & @CRLF & _
" await ctx.tg.editMessageText(" & @CRLF & _
" ctx.chat.id," & @CRLF & _
" message.message_id," & @CRLF & _
" undefined," & @CRLF & _
" formattedDateTime(new Date())" & @CRLF & _
" ).catch((error) => {" & @CRLF & _
" debug(error)" & @CRLF & _
" clearInterval(intervalId)" & @CRLF & _
" })" & @CRLF & _
" }, 3000)" & @CRLF & _
"})" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * The currencies list command" & @CRLF & _
" *" & @CRLF & _
" * @param {TelegrafContext} ctx The bot's context" & @CRLF & _
" */" & @CRLF & _
"bot.hears('!list', async (ctx) => {" & @CRLF & _
" const text = Object.keys(ctx.index)" & @CRLF & _
" .map((key) => `" & @CRLF & _
"${ctx.index[key]} \`!${key}\``)" & @CRLF & _
" .join('')" & @CRLF & _
"" & @CRLF & _
" await ctx.replyWithMarkdown(text).catch(debug)" & @CRLF & _
"})" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * Change page action" & @CRLF & _
" *" & @CRLF & _
" * @param {TelegrafContext} ctx The bot's context" & @CRLF & _
" */" & @CRLF & _
"bot.action(/^/rates/(w+)$/, async (ctx) => {" & @CRLF & _
" const current = ctx.session.ratesPage || 0" & @CRLF & _
" const allKeys = Object.keys(ctx.index)" & @CRLF & _
" // klskdlskakdsl" & @CRLF & _
" switch (ctx.match[1]) {" & @CRLF & _
" case 'prev':" & @CRLF & _
" ctx.session.ratesPage = current > 0" & @CRLF & _
" ? current - 1 // slklklkl" & @CRLF & _
" : 0" & @CRLF & _
" break" & @CRLF & _
" case 'next':" & @CRLF & _
" ctx.session.ratesPage = current < (allKeys.length / PAGE_SIZE) - 1" & @CRLF & _
" ? current + 1" & @CRLF & _
" : (allKeys.length / PAGE_SIZE) - 1" & @CRLF & _
" break" & @CRLF & _
" default:" & @CRLF & _
" }" & @CRLF & _
"" & @CRLF & _
" const { data } = await getRates(ctx.session.ratesPage * PAGE_SIZE, PAGE_SIZE)" & @CRLF & _
" .catch(debug)" & @CRLF & _
"" & @CRLF & _
" await ctx.editMessageText(" & @CRLF & _
" data.map(smallTemplateMd).join('')," & @CRLF & _
" {" & @CRLF & _
" disable_web_page_preview: true," & @CRLF & _
" parse_mode: 'Markdown'," & @CRLF & _
" ...pagination('rates', ctx.session.ratesPage, allKeys.length)," & @CRLF & _
" }" & @CRLF & _
" ).catch(debug)" & @CRLF & _
"" & @CRLF & _
" return ctx.answerCbQuery()" & @CRLF & _
"})" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * Handles noop actions" & @CRLF & _
" *" & @CRLF & _
" * @param {TelegrafContext} ctx The bot's context" & @CRLF & _
" */" & @CRLF & _
"bot.action(/^/noop$/, async (ctx) => ctx.answerCbQuery())" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * Handles the help command" & @CRLF & _
" */" & @CRLF & _
"bot.command('help', async (ctx) => {" & @CRLF & _
" const message = await ctx.replyWithMarkdown(`" & @CRLF & _
"*Usage:*" & @CRLF & _
"" & @CRLF & _
"\`!list\` - List of all supported currencies without rates" & @CRLF & _
"\`!rates\` - Paginated list of all supported currencies with rates" & @CRLF & _
"\`!{TICKER}\` - Show rate of exact currency by its ticker" & @CRLF & _
"`)" & @CRLF & _
"" & @CRLF & _
" if (message) {" & @CRLF & _
" setTimeout(() => {" & @CRLF & _
" ctx.deleteMessage(message.message_id)" & @CRLF & _
" }, 7000)" & @CRLF & _
" }" & @CRLF & _
"})" & @CRLF & _
"" & @CRLF & _
"// bot.command('leave', async (ctx) => {" & @CRLF & _
"// ctx.tg.leaveChat(ctx.chat.id)" & @CRLF & _
"// })" & @CRLF & _
"" & @CRLF & _
"// bot.on('inline_query', async (ctx) => {" & @CRLF & _
"" & @CRLF & _
"// })" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * Init the bot" & @CRLF & _
" *" & @CRLF & _
" * @param {TelegrafContext} ctx The bot's context" & @CRLF & _
" */" & @CRLF & _
"const run = async (instance) => {" & @CRLF & _
" const { data } = await getRates().catch(console.log)" & @CRLF & _
"" & @CRLF & _
" instance.context.index = await mapCommands(data)" & @CRLF & _
" return instance" & @CRLF & _
"}" & @CRLF & _
"" & @CRLF & _
"/**" & @CRLF & _
" * Start the bot" & @CRLF & _
" *" & @CRLF & _
" * @param {Telegraf} instance The bot instance" & @CRLF & _
" */" & @CRLF & _
"run(bot).then((instance) => {" & @CRLF & _
" instance.startPolling()" & @CRLF & _
"})"
Local $sSubst = ""
Local $sResult = StringRegExpReplace($sString, $sRegex, $sSubst)
MsgBox($MB_SYSTEMMODAL, "Result", $sResult)
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for AutoIt, please visit: https://www.autoitscript.com/autoit3/docs/functions/StringRegExp.htm