Botkit: @users and #channels not linked

Created on 11 Mar 2016  路  10Comments  路  Source: howdyai/botkit

Botkit: 0.0.8
Node: v5.7.0
OS X: 10.11.3

I'm having trouble with linked names and I'm pretty sure, it's an oversight on my side.
Using bot.say() like the following posts the message, but doesn't link names:

bot.say({
  text:       message,
  channel:    generalID,
  link_names: 1
});

What am I doing wrong?

Most helpful comment

Okay, after doing some digging, I now understand a few things about the Slack API and Botkit that explains what we're seeing:

1) The Slack RTM API doesn't understand link_names.

At least, that's what's suggested by this error in the Message Builder:

image

2) The Slack Web API should understand link_names, since the documentation for chat.postMessage documents it.

3) Botkit sends messages to Slack using the RTM API, unless certain features are specified in the message being sent (see lines 303-308 of Slackbot_worker.js):

        /**
         * These options are not supported by the RTM
         * so if they are specified, we use the web API to send messages.
         */
        if (message.attachments || message.icon_emoji ||
            message.username || message.icon_url) {

4) bot.reply() is convenient, but annoying.

It does not pass the full message object that you give it as its first parameter to bot.say() -- instead, it creates a new msg object and populates msg.channel and msg.text to it, _unless_ you pass a non-string type value as the second paramter resp. This has the unfortunate side effect of making something like this not work as one might expect:

   var msg = {
       'link_names': 1,
       'parse': 'full',
       'channel': message.channel
   };
   bot.reply(msg, 'Here is my reply, @dossy.');

In theory, you could work around it like so:

   var msg = {
       'link_names': 1,
       'parse': 'full',
       'text': 'Here is my reply, @dossy.'
   };
   bot.reply({ 'channel': message.channel }, msg);

_Except_ for what I learned in parts 1-3 above. As is, Botkit will send the above example through as a RTM API call, and the link_names will be ignored. I suppose we should submit a PR to include parse and link_names to the conditional that makes Botkit use the Web API, but for now you can kinda work around it by sending an empty attachments array, like so:

   var msg = {
       'link_names': 1,
       'parse': 'full',
       'text': 'Here is my reply, @dossy.',
       'attachments': []
   };
   bot.reply({ 'channel': message.channel }, msg);

I tested this and it worked for me. I just wanted to at least prove that there _was_ a way to get the link_names functionality to actually work and that this wasn't a Slack documentation error, but rather a Botkit issue.

All 10 comments

What are the contents of message? Have you read https://api.slack.com/docs/formatting#linking_to_channels_and_users ?

Yes, I have and I've also read Parsing modes.
The content of message is something like: Hello @username, welcome to #general.
You append the attributes link_names or parse here, but it doesn't seem to work.

From parsing modes:

By default, Slack will not linkify channel names (starting with a '#') and usernames (starting with an '@'). You can enable this behavior by passing link_names=1 as an argument. This behavior is always enabled in parse=full mode (see below).

On the previous line of Slackbot_worker.js that you linked to:

            parse: message.parse || null,

Looking at the chat.postMessage API documentation:

parse full Optional
Change how messages are treated. Defaults to none. See below.

So, if you want link_names to function, you have to also set parse=full.

I tried using link_names=1 and parse=full, but that didn't work :cry:
I'll try again and report back :ok_hand:

Yeah, to be honest I never tried to get the link_names=1 functionality working, I use the control sequence method of linking to users and channels (e.g., <@U1234ABCD> and <#C1234ABCD>) which has worked for me.

That's how I got it working - but automatic linking would be much nicer.

Okay, after doing some digging, I now understand a few things about the Slack API and Botkit that explains what we're seeing:

1) The Slack RTM API doesn't understand link_names.

At least, that's what's suggested by this error in the Message Builder:

image

2) The Slack Web API should understand link_names, since the documentation for chat.postMessage documents it.

3) Botkit sends messages to Slack using the RTM API, unless certain features are specified in the message being sent (see lines 303-308 of Slackbot_worker.js):

        /**
         * These options are not supported by the RTM
         * so if they are specified, we use the web API to send messages.
         */
        if (message.attachments || message.icon_emoji ||
            message.username || message.icon_url) {

4) bot.reply() is convenient, but annoying.

It does not pass the full message object that you give it as its first parameter to bot.say() -- instead, it creates a new msg object and populates msg.channel and msg.text to it, _unless_ you pass a non-string type value as the second paramter resp. This has the unfortunate side effect of making something like this not work as one might expect:

   var msg = {
       'link_names': 1,
       'parse': 'full',
       'channel': message.channel
   };
   bot.reply(msg, 'Here is my reply, @dossy.');

In theory, you could work around it like so:

   var msg = {
       'link_names': 1,
       'parse': 'full',
       'text': 'Here is my reply, @dossy.'
   };
   bot.reply({ 'channel': message.channel }, msg);

_Except_ for what I learned in parts 1-3 above. As is, Botkit will send the above example through as a RTM API call, and the link_names will be ignored. I suppose we should submit a PR to include parse and link_names to the conditional that makes Botkit use the Web API, but for now you can kinda work around it by sending an empty attachments array, like so:

   var msg = {
       'link_names': 1,
       'parse': 'full',
       'text': 'Here is my reply, @dossy.',
       'attachments': []
   };
   bot.reply({ 'channel': message.channel }, msg);

I tested this and it worked for me. I just wanted to at least prove that there _was_ a way to get the link_names functionality to actually work and that this wasn't a Slack documentation error, but rather a Botkit issue.

Awesome, thanks for the descriptive answer. Great work! :+1:

I'll use an empty attachments array for now, maybe it's a good idea to make the difference between the RTM API and Web API more clear in documentation?

Ideally, the underlying plumbing (whether it's RTM or Web) should be abstracted away from the developer who uses Botkit - the issue is really with Botkit needing to force use of the Web API in more cases, like when parse and link_names are passed, basically extending that if condition in Slackbot_worker.js.

Glad we were able to work this out, though. It definitely had me puzzled.

link_names is deprecated use <@UDNSKZCOC> for user tagging.
https://api.slack.com/docs/formatting#linking_to_channels_and_users

Was this page helpful?
0 / 5 - 0 ratings