2

I have a function and a few helper functions that are supposed to access Slack message history and return the first message that matches a certain number string.

I have tested the code extensively on my computer's Node.js environment to verify it works and is correct. However, I can't get it to work inside the run-time environment of Twilio Function; I keep getting the error "Missing name in function declaration.", and the function just won't chain properly or work like a function at all.

What am I doing wrong?

exports.handler = function(context, event, callback) {

    if(event.event){
         if(event.event.channel == context.CHANNEL_ID){
            if(event.event.subtype){
                console.log("bot posting");
                if(event.event.thread_ts){
                    console.log("bot posting in thread");
                    console.log(event);
                }
                else{
                    console.log("bot posting in channel");
                    console.log(event);
                }
            }
            else{
                console.log("staff posting");
                if(event.event.thread_ts){
                    console.log("staff posting in thread");
                    console.log(event);
                }
                else{
                    console.log("staff posting in channel");
                    console.log(event);
                }
            }
         }
    }
    else{
        console.log("incoming sms message");
        console.log(typeof event.From);
    }


    returnTS("6049248010").then(function (ts) {
        console.log(ts);
    });

    callback(null);
};


var getSlackHistory = async function (ts) {

    try {
        var response;

        if (typeof ts === 'undefined') {
            response = await got('https://slack.com/api/channels.history?'
                + 'token=' + context.TWILIO_TOKEN
                + '&channel=' + context.TWILIO_CHANNEL_ID);
        }
        else {
            response = await got('https://slack.com/api/channels.history?'
                + 'token=' + context.TWILIO_TOKEN
                + '&channel=' + context.TWILIO_CHANNEL_ID
                + '&latest=' + ts);
        }

        return await JSON.parse(response.body);
    }
    catch (error) { console.log("failure"); }

}

var getAllSlackHistory = async function () {
    var message_history = [];
    try {
        var response = await getSlackHistory();
        //  console.log(response.messages[response.messages.length - 1].ts);
        for (var i = 0; i < response.messages.length; i++) {
            message_history.push(response.messages[i]);
        }
        while (response.has_more) {
            response = await getSlackHistory(response.messages[response.messages.length - 1].ts);
            for (var i = 0; i < response.messages.length; i++) {
                message_history.push(response.messages[i]);
            }
        }
        return await message_history;
    }
    catch (error) {
        console.log(error);
    }

}

var returnTS = async function (numberString) {
    try {
        var message_history = await getAllSlackHistory();
        //console.log(message_history.length);
        // console.log(numberString);
        for (var i = 0; i < message_history.length; i++) {
            //  console.log(message_history[i].text);
            // console.log(message_history[i].text.includes(numberString));
            if (message_history[i].text.includes(numberString))
                //  console.log(message_history[i].ts);
                return message_history[i].ts;
        }
    }
    catch (error) {
        console.log(error);
    }
}
lizziepika
  • 3,231
  • 1
  • 14
  • 23
  • Is this a hoisting issue? Have you tried assigning your functions before the handler function? – philnash May 17 '19 at 23:10
  • hey, srry for late reply, i have tried assigning my functions after the handler function outside its scope and before, it still doesn't work; in fact any async function triggers the "Missing name in function declaration." error and basically doesn't work. – Kevin Huang May 19 '19 at 00:30
  • This is weird, I'll need more time to investigate, but will hopefully come up with something for you soon. – philnash May 19 '19 at 21:21
  • Hey, thanks for your help, really appreciate it; I did a little bit of trial-and-error, essentially this is what I've learned so far: 1) twilio function callback automatically terminates any asynchronous method within the function 2) to stop this automatic termination you can remove the twilio callback function line, but then the entire function will just automatically terminate after 5 sec. Essentially, asynchronous method and twilio function runtime don't play nice with each other. The error message seems to have no effect but comes up automatically whenever the async keyword is used. – Kevin Huang May 22 '19 at 16:28
  • Ah, I hadn't read your code in depth, apologies! I think I might have an answer for you. – philnash May 22 '19 at 23:16

1 Answers1

2

Twilio developer evangelist here.

As you said in the comments, this has to do with asynchronous operations and the callback to Twilio Functions.

Currently, the final few lines of your function are:

  returnTS("6049248010").then(function (ts) {
      console.log(ts);
  });

  callback(null);
};

returnTS is an asynchronous function, returning a promise in this case. Twilio Functions will cease all operations once you call the callback function (or after 5 seconds) so in this case you should only call the callback once your asynchronous functions are complete. If you move the call to callback within the promise callback, then things should work as you expect. Try the following instead:

  returnTS("6049248010").then(function (ts) {
      console.log(ts);
      callback(null);
  });
};
philnash
  • 70,667
  • 10
  • 60
  • 88