Muthu Kumar
7 years ago
5 changed files with 134 additions and 9 deletions
@ -1,14 +1,92 @@ |
|||
const { spawn } = require('child_process'); |
|||
const { EOL } = require('os'); |
|||
|
|||
const Telegraf = require('telegraf'); |
|||
const config = require('./config') |
|||
const { path } = require('./util/index.js'); |
|||
|
|||
const bot = new Telegraf(config.apiKey) |
|||
const config = require('./config.js'); |
|||
const validator = require('./lib/validator'); |
|||
const responder = require('./lib/responseHandler.js'); |
|||
|
|||
bot.command('start', ctx => { |
|||
return ctx.reply('Bot succesfully started!'); |
|||
}) |
|||
const dateOptions = { |
|||
weekday: 'long', |
|||
year: 'numeric', |
|||
month: 'long', |
|||
day: 'numeric', |
|||
hour: 'numeric', |
|||
minute: 'numeric', |
|||
}; |
|||
|
|||
const bot = new Telegraf(config.botApiKey); |
|||
const sessions = []; |
|||
sessions.history = []; |
|||
|
|||
bot.use((ctx, next) => |
|||
validator(ctx) |
|||
.then(next) |
|||
.catch(responder.fail( |
|||
`Username Not authenticated!` |
|||
))); |
|||
|
|||
bot.command('start', |
|||
ctx => { |
|||
ctx.replyWithHTML('Welcome to tsh -- <code>Telegram Shell!</code>'); |
|||
const newProc = spawn('bash', { |
|||
cwd: '/home' |
|||
}); |
|||
newProc.stdout.setEncoding('utf8'); |
|||
sessions.push(newProc); |
|||
sessions.currentSession = newProc; |
|||
}); |
|||
|
|||
bot.hears('hi', ctx => { |
|||
return ctx.reply('Hey!, How are you?'); |
|||
bot.command('ls', |
|||
ctx => ctx.reply( |
|||
sessions.reduce((acc, _, index) => |
|||
acc ? `${acc}\n${index}` : `${index}`, '') |
|||
|| `No sessions found. Start one with /start.` |
|||
)); |
|||
|
|||
bot.command('attach', |
|||
ctx => { |
|||
const text = path(['update', 'message', 'text'], ctx); |
|||
const sessionIndex = parseInt(text.replace('/attach ', '').trim()); |
|||
if(Number.isNaN(sessionIndex) || !sessions[sessionIndex]) return responder.fail('Session not found. /ls for list of sessions')(ctx); |
|||
sessions.currentSession = sessions[sessionIndex]; |
|||
return responder.success(`Reattached to shell ${sessionIndex}`)(ctx); |
|||
}); |
|||
|
|||
bot.command('detach', |
|||
ctx => { |
|||
const text = path(['update', 'message', 'text'], ctx); |
|||
const sessionIndex = parseInt(text.replace('/detach ', '').trim()); |
|||
const currentSession = text.trim() === '/detach' ? sessions.currentSession : sessions[sessionIndex]; |
|||
if(!currentSession) return responder.fail('Session not found. /ls for list of sessions.')(ctx); |
|||
sessions.currentSession = undefined; |
|||
return responder.success(`Detached from shell ${sessionIndex}`)(ctx); |
|||
}); |
|||
|
|||
bot.command('kill', |
|||
ctx => { |
|||
const text = path(['update', 'message', 'text'], ctx); |
|||
const sessionIndex = parseInt(text.replace('/kill ', '').trim()); |
|||
if(Number.isNaN(sessionIndex) || !sessions[sessionIndex]) return responder.fail('Session not found. /ls for list of sessions.')(ctx); |
|||
const disconnect = sessions[sessionIndex]; |
|||
delete sessions[sessionIndex]; |
|||
if(disconnect === sessions.currentSession) sessions.currentSession = undefined; |
|||
disconnect.kill(); |
|||
ctx.reply('Session killed. /ls for list of sessions.') |
|||
}) |
|||
|
|||
bot.use(ctx => { |
|||
if(!sessions.currentSession) return responder.fail('No active session. Start one with /start or view list of sessions by sending /ls.')(ctx); |
|||
const cmd = ctx.update.message.text; |
|||
const history = `${new Date().toLocaleDateString('en-IN', dateOptions)}: ${cmd}`; |
|||
sessions.history.push(history); |
|||
console.log(history); |
|||
sessions.currentSession.stdin.write(cmd + EOL); |
|||
sessions.currentSession.stdout.on('data', d => responder.success(d)(ctx)); |
|||
sessions.currentSession.stdout.on('error', e => responder.success(e)(ctx)); |
|||
}); |
|||
|
|||
bot.startPolling(); |
|||
console.log(`Polling for updates.`); |
|||
|
@ -0,0 +1,3 @@ |
|||
const process = ctx => { |
|||
const { text } = ctx.update.message; |
|||
} |
@ -0,0 +1,34 @@ |
|||
const success = response => ctx => response ? ctx.reply(response) : null; |
|||
const { EOL } = require('os'); |
|||
const { path } = require('../util/index.js'); |
|||
|
|||
const convertCtx = ctx => { |
|||
const message = path(['update', 'message'], ctx); |
|||
const { id, first_name, username, language_code } = path(['from'], message); |
|||
const { text } = message; |
|||
return JSON.stringify({ |
|||
id, |
|||
first_name, |
|||
username, |
|||
language_code, |
|||
text, |
|||
}, null, 2); |
|||
}; |
|||
|
|||
const fail = response => ctx => { |
|||
if(!response |
|||
|| !path(['update', 'message'], ctx) |
|||
) return; |
|||
console.log( |
|||
EOL, |
|||
response, |
|||
EOL, |
|||
`With context: `, |
|||
convertCtx(ctx), |
|||
); |
|||
return ctx.reply(response); |
|||
}; |
|||
|
|||
module.exports = { |
|||
success, fail, |
|||
}; |
@ -0,0 +1,10 @@ |
|||
const { path } = require('../util/index.js'); |
|||
const config = require('../config.js'); |
|||
|
|||
const validate = |
|||
ctx => { |
|||
if(!path(['update', 'message', 'from', 'id'], ctx)) return Promise.reject(ctx); |
|||
return (ctx.update.message.from.id === config.masterID) ? Promise.resolve(ctx) : Promise.reject(ctx); |
|||
} |
|||
|
|||
module.exports = validate; |
Loading…
Reference in new issue