如何在Node.js中将数据从一种方法传输到另一种方法?

时间:2018-05-05 15:07:46

标签: javascript node.js amazon-web-services amazon-s3 telegram

我使用Telegram bot API和AWS S3从存储桶中读取数据。我需要在Telgraf方法中使用s3方法中的数据,但我不知道如何:

'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)

如何在ctx.reply()中使用s3.getObject方法中的数据?

3 个答案:

答案 0 :(得分:1)

如果要将文件作为附件发送,则必须使用:ctx.replyWithDocument。除此之外,您的问题是:How do I return the response from an asynchronous call?

在这种特殊情况下,您可以使用s3.getObject(params).promise()来避免使用回调API,并在bot.command侦听器中轻松使用它。

使用async/await(节点&gt; = 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

答案 1 :(得分:0)

虽然我没有使用过S3,但我确实知道AWS服务为其实现添加了对Promises的支持,以避免使用回调。就个人而言,我更喜欢使用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)

答案 2 :(得分:0)

正如Luca所建议的那样,我在s3.getObject中调用了bot.command并且它有效!

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())
        });
    })