StackStorm / hubot-stackstorm

Hubot plugin for integration with StackStorm event-driven infrastructure automation platform.
Apache License 2.0
49 stars 39 forks source link

Update Slack adapter #209

Open blag opened 4 years ago

blag commented 4 years ago

Our Slack adapter automatically chunks up messages that are "too large" (>7900 characters) and sends the message chunks separately, scheduling the next chunk to send after a 300ms delay:

    var chunks = split_message.text.match(/[\s\S]{1,7900}/g);
    var sendChunk = function (i) {
      content.pretext = i === 0 ? pretext + split_message.pretext : null;
      content.text = chunks[i];
      content.fallback = chunks[i];
      robot.adapter.client.send(envelope, {'attachments': [content]});

      if (chunks.length > ++i) {
        setTimeout(function(){ sendChunk(i); }, 300);
      }
    };
    sendChunk(0);

But, the Slack plugin for Hubot now supports passing a callback as the last "message" of the messages parameter:

  send: (envelope, messages...) ->
    callback = ->
    if typeof(messages[messages.length - 1]) == "function"
      callback = messages.pop()
    messagePromises = messages.map (message) =>
      return Promise.resolve() if typeof(message) is "function"
      # NOTE: perhaps do envelope manipulation here instead of in the client (separation of concerns)
      @client.send(envelope, message) unless message is ""
    Promise.all(messagePromises).then(callback.bind(null, null), callback)

That means that we should be able to update the Slack adapter to use the adapter.send() function and utilize the callback function:

    var messages_to_send = messages.buildMessages(data.extra.slack);
    var sendMessage = function (i) {
      if (i < messages_to_send.length) {
        robot.adapter.send(envelope, messages_to_send[i], function () {
          sendMessage(i+1);
        });
      }
    };
    sendMessage(0);

  ...

    var chunks = split_message.text.match(/[\s\S]{1,7900}/g);
    var sendChunk = function (i) {
      if (i < chunks.length) {
        var _content = _.clone(content);
        _content.pretext = i === 0 ? pretext + split_message.pretext : null;
        _content.text = chunks[i];
        _content.fallback = chunks[i];
        robot.adapter.send(envelope, {'attachments': [_content]}, function () {
          sendChunk(i+1);
        });
      }
    };
    sendChunk(0);

There's a possibility that we could also use async/await with this.

Finally, the Slack adapter has seen initial code to support Coffeescript 2, but it was reverted later. There does seem to be some movement on this though, because the Slack adapter not supporting Coffeescript 2 means that we are pinning against Coffeescript 1 (via the coffee-script package), and that is holding back updates for other Hubot plugins.