javascript - 为什么 Twilio 和 Firebase 不能使用 Node.js 协同工作?

标签 javascript node.js firebase heroku twilio

为什么 twiml.message() 在一个地方工作但在另一个地方不工作?

我想从 firebase 读取并使用 twiml/Twilio 通过 SMS 文本发送结果。代码工作的地方和不工作的地方用箭头注释。

输出应该是:“Zoey 最后一次出现在(地点)是在(时间)。”

const accountSid = '**********************************';
const authToken = '*********************************;

// require the Twilio module and create a REST client
const client = require('twilio')(accountSid, authToken);

const http = require('http');
const express = require('express');
const MessagingResponse = require('twilio').twiml.MessagingResponse;
const bodyParser = require('body-parser');
var firebase = require('firebase');
var admin = require("firebase-admin");
var message = "N/A";

// setting the configurations for firebase
var config = {
  apiKey: "***************************************",
  authDomain: "*************.firebaseapp.com",
  databaseURL: "https://**********.firebaseio.com",
};

firebase.initializeApp(config);

const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/reply', (req, res) => {
  const twiml = new MessagingResponse();
  console.log("sending: " + message);
  twiml.message(message);
});

app.post('/', (req, res) => {
  const twiml = new MessagingResponse();
  app.use(bodyParser());
  if(req.body.Body == 'Zoey') {
    // Send the message back with last known location.
    var body = 'Zoey was last seen in ';

    var databaseRef = firebase.database().ref();
    databaseRef.once('value').then(function(snap) {
      // Get the location
      var lastLocation = snap.val().lastLocation;
      console.log("last location:" + lastLocation);
      body += lastLocation;

      body += ' at ';

      // Get the timestamp
      var timestamp = snap.val().timestamp;
      console.log("at " + timestamp);
      body += timestamp;
      console.log(body);
      message = body;
      twiml.message(body); //<---------------This doesn't work
    });
  } else {
    // Bad text message. Send the error message.
    var errorMessage = 'Please type Zoey and try again!';
    twiml.message(errorMessage);
  }
  twiml.message("This Works");//<----------------This Works!
  res.writeHead(200, {'Content-Type': 'text/xml'});
  res.end(twiml.toString());
}).listen(process.env.PORT || 5000);

http.createServer(app).listen(1337, () => {
console.log('Server starting! Express server listening on port 1337');
});

最佳答案

我无法测试,但请为 app.post('/', ... 试试这个节


app.post('/', (req, res) => {

    const twiml = new MessagingResponse();

    app.use(bodyParser());

    if (req.body.Body == 'Zoey') {
        // Send the message back with last known location.
        var body = 'Zoey was last seen in ';

        var databaseRef = firebase.database().ref();

        databaseRef.once('value')
            .then(function (snap) {
                // Get the location
                var lastLocation = snap.val().lastLocation;
                body += lastLocation;
                body += ' at ';

                // Get the timestamp
                var timestamp = snap.val().timestamp;
                console.log("at " + timestamp);
                body += timestamp;

                return body;
            })
            .then(body => {
                twiml.message(body);
                res.writeHead(200, { 'Content-Type': 'text/xml' });
                res.end(twiml.toString());

            });

    } else {
        // Bad text message. Send the error message.
        var errorMessage = 'Please type Zoey and try again!';
        twiml.message(errorMessage);
        res.writeHead(200, { 'Content-Type': 'text/xml' });
        res.end(twiml.toString());

    }

}).listen(process.env.PORT || 5000);

Update: explanation

如果您查看原始代码,您会发现 if/else用于为 Twilio 设置消息的语句。在 if/else 之后,您有发送响应的代码。

if (req.body.Body == 'Zoey') {
  // go to Firebase
  // use data from Firebase to include in message
  // it will take some time to receive the response from Firebase
  // somewhere in here set the message for Twilio

} else {
  // don't go anywhere
  // occurring at the same time
  // somewhere in here set the message for Twilio

}

// respond to Twilio  
// executed immediately 
// it does not wait for Firebase to respond
res.writeHead(200, { 'Content-Type': 'text/xml' });
res.end(twiml.toString());

Sending the response to Twilio without waiting for Firebase to respond is a problem, so..., let's look at the "Firebase section".

var databaseRef = firebase.database().ref();
databaseRef.once('value')
.then(
    // execute a function when we get the response from Firebase
    // somewhere in here set the message for Twilio
);

我们能做的是

var databaseRef = firebase.database().ref();
databaseRef.once('value')
.then(
    // execute a function when we get the response from Firebase
    // return the message for Twilio
)
.then(
    // set the message for Twilio, using the argument 
    // passed by the return of the previous ".then()"
    // respond to Twilio
);

所以,代码变成:

if (req.body.Body == 'Zoey') {
    // go to Firebase
    // use data from Firebase to include in message

    var databaseRef = firebase.database().ref();
    databaseRef.once('value')
        .then(function (snap) {
            // execute code when we get the response from Firebase

            // return the message for Twilio
            // "theMessage" will be passed to the next ".then()"
            return theMessage;
        })
        .then(function (theArgument) {
            // execute code when we get the return from the previous ".then()"
            // set the message for Twilio, using the argument 
            twiml.message(theArgument);

            // respond to Twilio
            res.writeHead(200, { 'Content-Type': 'text/xml' });
            res.end(twiml.toString());
        });

} else {
    // don't go anywhere, set the message for Twilio
    twiml.message("Please type Zoey and try again!");

    // respond to Twilio  
    res.writeHead(200, { 'Content-Type': 'text/xml' });
    res.end(twiml.toString());

}

I'm sure this (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) explains promises better than me.


注意:可以去掉第二个.then()如果你移动 // respond to Twilio码起来,在第一个.then()的末尾.

关于javascript - 为什么 Twilio 和 Firebase 不能使用 Node.js 协同工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50182368/

相关文章:

javascript - Sequelize.js 包括返回不正确的数据

JavaScript-如何将 "message"div 更改为黄色

node.js - 304 Not Modified When If-None-Match 有效

javascript - 如何在 for 循环中使用 node.js 中的 Request 函数并让它以正确的顺序返回输出?

javascript - FCM : firebase getToken options( ServiceWorkerRegistration, vapidKey)

ios - 设置值时重复子节点 Firebase

javascript - 每个主题的图像链接

javascript - jQuery 过滤函数选择器错误

mysql - 计算带有多个包含的 Sequelize 的连接

node.js - 更新 CloudFunctions 上的子集合