docs: function SlackRtmOut(n) {
      RED.nodes.createNode(this, n);
  
      var node = this;
      this.client = n.client;
      this.clientNode = RED.nodes.getNode(this.client);
  
      node.status(statuses.disconnected);
  
      if (node.client) {
        SetConfigNodeConnectionListeners(node);
  
        node.on("input", function(msg) {
          SlackDebug("slack-rtm-out incomiming message", msg);
  
          /**
           * message, presence_sub, presence_query, ping, and typing.
           */
          var method = msg.topic;
          var options = msg.payload;
  
          if (
            !method ||
            typeof method !== "string" ||
            !method instanceof String
          ) {
            node.error("invalid msg.topic");
            return null;
          }
  
          /**
           * Try to help with common use case, set channel based on lookup if starts with @ or #
           */
          if (
            method == "message" &&
            (options.channel[0] == "@" || options.channel[0] == "#")
          ) {
            var channel = node.clientNode.findChannelByName(options.channel);
            if (channel && channel.id) {
              options.channel = channel.id;
            }
          }
  
          /**
           * special handling for simple use-case
           */
          if (method[0] == "@" || method[0] == "#") {
            var channel = node.clientNode.findChannelByName(method);
            if (!channel || !channel.id) {
              node.error("invalid channel: " + method);
              return null;
            }
            method = "message";
            options = {
              text: msg.payload,
              channel: channel.id
            };
          }
  
          /**
           * custom per-method logic
           */
          switch (method) {
            case "message":
              // force text to be a string
              options.text = ValueToString(options.text);
              break;
          }
  
          /**
           * something seems to block when it's not message events
           * keeping a hard-coded list for now until the 'bug' is squashed
           *
           * https://github.com/slackapi/node-slack-sdk/issues/706
           *
           * There's only 5 (public) writable events on RTM: message,
           * presence_sub, presence_query, ping, and typing.
           *
           * The only two that expect responses are message and ping.
           */
          var awaitReply = false;
          switch (method) {
            case "message":
            case "ping":
              awaitReply = true;
              break;
            case "presence_sub":
            case "presence_query":
            case "typing":
              awaitReply = false;
              break;
            default:
              /**
               * go ahead and let invalid methods await so a negative/error
               * response is returned
               */
              awaitReply = true;
              break;
          }
  
          node.status(statuses.sending);
          msg.slackState = node.clientNode.state;
  
          SlackDebug("slack-rtm-out call", method, options);
          node.clientNode.rtmClient
            .addOutgoingEvent(awaitReply, method, options)
            .then(res => {
              /**
               * mock a response for methods which return nothing
               * ie: everything but message and ping
               */
              if (typeof res === "undefined") {
                res = {
                  ok: true,
                  type: method
                };
              }
  
              SlackDebug("slack-rtm-out call response", res);
              msg.payload = res;
              node.send(msg);
              node.status(statuses.connected);
            })
            .catch(e => {
              SlackDebug("slack-rtm-out error response", e.data);
              msg.payload = e.data;
              node.send(msg);
              node.status(statuses.connected);
            });
        });
      } else {
        node.status(statuses.misconfigured);
      }
    }