Glitch hosted Botkit Slack bot duplicates output if presently idle

Hello, really loving Glitch so far, thanks for the awesome platform! :grinning:

I’m currently using it to host a Botkit Slack bot, and for the most part, it’s been working great, however…

I’ve noticed that if the bot doesn’t get queried after a certain amount of time, it goes ‘idle’(It’s uptime counter resets), and when it gets queried in this ‘idle state’(may not be using the right lingo here), it duplicates the output of the query. After the initial query when it was idle, all following query output is normal(non-duplicated).

I’m currently using it to post PagerDuty information into Slack channels, so for example, if you “@pagerduty who’s on call?” while the bot is ‘idle’, you’ll get…
*- IT Escalation level 1 - John Smith | BACKUP ON CALL
*- IT Escalation level 1 - John Smith | BACKUP ON CALL
Then if you immediately ask it again, you’ll simply get…
*- IT Escalation level 1 - John Smith | BACKUP ON CALL

This seems to only happen when the bot gets a query while it’s in the ‘idle state’, then it’s fine for every query after that…

Searched this forum, Google, Botkit, and Slack for any clue as to what’s going on, and so far have been empty handed… it’s a real head scratcher for me. Maybe someone on here can throw me a bone :slight_smile:

1 Like

Difficult to know what’s causing this. Although for background in case you didn’t know, the idle state is expected - Glitch apps sleep after 5 mins of inactivity ( If you can share your project then we can take a closer look at this.

1 Like

Yeah, I assumed the idle state was expected behavior :slight_smile: Only thing that’s odd, is how the bot seems to duplicate output immediately upon resuming from the idle state, then behaves normally after that…

Here’s a Codeshare of the only Skill/code I’ve setup in the Botkit bot. Everything else is standard “out of the box” Botkit code.

Botkit repo I cloned

Thanks again for any light you’re able to shine on this!

1 Like

Hi @secomdevops,

I haven’t used any of the botkit code with Slack, but I did have a similar issue with one of my Slack integrations.

If you’re subscribing to the Slack Events API there’s an automatic retry of failed messages. If your app is too slow coming out of the idle state and replying, Slack will immediately retry. Because of the way that Glitch holds a request active while starting your app, it’s entirely possible you’ll get duplicate messages. I’d expect similar retry behavior on the rest of the Slack payloads (if you’re not using Events API).

The way I’ve handled that in a few of my Slack projects is to reply with 200 OK as soon as possible and then deal with the message as appropriate. That was sufficient to get my apps up and responding in time to avoid the triggering the retry, resulting in duplicated responses.

Hope that helps!

1 Like

It seems like you could also cache a few event_ids from the events and throw away ones that have already been seen.

1 Like

Awesome, thanks for the input, both those suggestions definitely make sense :slight_smile:

Things are busy right now, so it’ll be “weeks” before I find time to sit down and hammer out some code to try and fix this, but now I have a direction to go. I’ll post my solution/update once I make headway.

~Thanks again!

Hi @nathan, could you possibly elaborate on how you implemented this?


Hi Azhar,

It’s been a while since I last played with this, so my memory is a bit foggy. :fog: This route handler exhibits the “respond to Slack right away” behavior I mentioned:!/shadow-rooster?path=slack.js:132:0 (your cursor will be at the right line after following the link, but you’ll need to scroll down to see it)

  //, function (request, response) {
    if (request.body.challenge) {
      response.send(request.body.challenge) // reply to Slack attempting to configure the events API
    } else if (request.body.token === process.env.SLACK_TOKEN) {
      response.send('ok') // let Slack know we'll handle this
      handleEvent(request.body.event) // do whatever we need to do based on the message
    } else {
      response.status(400).send('nope') // if the request doesn't have

The handler below the “early return” version can’t return early, because we need to have the response to Slack actually have the results when dealing with interactive button messages.!/shadow-rooster?path=slack.js:144:0

Hope that helps!

(No guarantees about the app functioning, though… it’s been a year since I last used it)

1 Like