Как перенести данные из одного метода в другой в Node.js? - PullRequest
0 голосов
/ 05 мая 2018

Я использую Telegram bot API и AWS S3 для чтения данных из корзины. Мне нужно использовать данные из метода s3 в методе Telgraf , но я не знаю, как:

'use strict'

const Telegraf = require('telegraf');
const bot = new Telegraf('TOKEN')

var AWS = require('aws-sdk')
var s3 = new AWS.S3({
    accessKeyId: 'key',
    secretAccessKey: 'secret'
}) 

var params = {Bucket: 'myBucket', Key:"ipsum.txt"};

var s3Promise = s3.getObject(params, function(err, data) {
    if (err) console.log(err, err.stack);
    else              
    var words= data.Body.toString(); //WHAT I WANT IN IN COMMAND METHOD
    console.log('\n' + words+ '\n') //Returns ipsum.txt as string on console
})

bot.command('s', (ctx) => { //Bot Command
    s3Promise; //Returns ipsum.txt as string on console
    ctx.reply('Check console') //Meesage in Telegram
    //ctx.reply(<I WANT data.Body.toSting() HERE>)
});

const { PORT = 3000 } = process.env
bot.startWebhook('/', null, PORT)

Как использовать данные из метода s3.getObject в ctx.reply ()?

Ответы [ 3 ]

0 голосов
/ 05 мая 2018

Как подсказывает Luca , я вызвал bot.command внутри s3.getObject, и он работает!

s3.getObject(params, function(err, data) {
        if (err) console.log(err, err.stack); // an error occurred
        else              
        bot.command('s', (ctx) => {
            ctx.reply('Succesfully read from S3:\n\n' + data.Body.toString())
        });
    })
0 голосов
/ 05 мая 2018

Если вы хотите отправить файл как вложение, вы должны использовать: ctx.replyWithDocument. Кроме того, ваша проблема: Как мне вернуть ответ от асинхронного вызова?

В этом конкретном случае вы можете использовать s3.getObject(params).promise(), чтобы избежать API обратного вызова и легко использовать его в вашем bot.command слушателе.

Используя async/await (Node> = 7.6) ваш код может быть написан следующим образом

'use strict';

const Telegraf = require('telegraf');
const bot = new Telegraf('TOKEN');

const AWS = require('aws-sdk');
const s3 = new AWS.S3({
    accessKeyId: 'key',
    secretAccessKey: 'secret'
});

const params = {
    Bucket: 'myBucket',
    Key: 'ipsum.txt'
};

bot.command('s', async ctx => { // Bot Command

    try {

        // If you're sending always the same file and it won't change
        // too much, you can cache it to avoid the external call everytime
        const data = await s3.getObject(params).promise();

        ctx.reply('Check console'); // Message in Telegram

        // This will send the file as an attachment
        ctx.replyWithDocument({
            source: data.Body,
            filename: params.Key
        });

        // or just as text
        ctx.reply(data.Body.toString());

    } catch(e) {
        // S3 failed
        ctx.reply('Oops');
        console.log(e);
    }
});

const {
    PORT = 3000
} = process.env;

bot.startWebhook('/', null, PORT);

Более подробную информацию о том, как работать с файлами, можно найти в telegraf docs

PS: Я проверил код, и он полностью работает:

enter image description here

0 голосов
/ 05 мая 2018

Хотя я не использовал S3, я знаю, что сервисы AWS добавили поддержку Promises в их реализации, чтобы избежать использования обратных вызовов. Лично я предпочитаю использовать обещания, так как считаю, что они приводят к более читабельному коду.

Я думаю, что следующее должно решить вашу проблему.

'use strict'

const Telegraf = require('telegraf');
const bot = new Telegraf('TOKEN')

var AWS = require('aws-sdk')
var s3 = new AWS.S3({
    accessKeyId: 'key',
    secretAccessKey: 'secret'
}) 

var params = {Bucket: 'myBucket', Key:"ipsum.txt"};

bot.command('s', (ctx) => {
  s3.getObject(params).promise()
  .then(data => {
    ctx.reply('Check console');
    ctx.reply(data.Body.toString());
  }, err => console.log(err, err.stack));
})

const { PORT = 3000 } = process.env
bot.startWebhook('/', null, PORT)
...