Skip to content

Instantly share code, notes, and snippets.

@UrsaDK

UrsaDK/Slack-IRC.md

Last active Mar 4, 2016
Embed
What would you like to do?
Slack IRC gateway: Controlling user's AWAY status

Controlling AWAY status on Slack IRC

Slack is an excellent team communication tool, which can be accessed in a number of different ways: via the web, via Slack's own client, XMPP gateway, etc. My trouble started when I tried accessing Slack via their IRC gateway.

To start with, everything worked great. I appeared online and my user was reported as present and accounted for, available, not away. However, after 30 minutes, which is Slack's default inactivity timeout, my IRC client (Textual 5) started reporting me as away. This happened despite me being online and active in one of Slack channels throughout this entire time.

Clearing the AWAY status with IRC's /away didn't work (though, annoyingly enough, you can set your user as AWAY by doing something like /away brb). A quick search online revealed that inability to clear AWAY status is a well know "feature" of the Slack gateway. IRSSI guys have been talking about fixing it in Sep, 2014.

So, after a quick read of

I decided to fix the issue by hooking into Slack's web API and clearing away status manually with curl -L https://slack.com/api/users.setActive?token=${SLACK-TOKEN}. However, that didn't work either, even though Slack WebAPI server responded with {"ok":true}. My user remained "away".

So, I figured it's time to go and speak to Slack's support. After a brief back-and-forth it turned out that they are aware of the initial issue (IRC /away command not working) and are currently working hard on fixing it. However, issues with user.setActive and users.setPresence API methods were new to them:

  • Slack Support:

    Thanks for getting in touch and sorry for the troubles there. This is a known bug with our IRC gateways for now, but the good news is that we're working on an overhaul that should make that work better.

    Regarding the users.setActive method—that doesn't actually change your status, but instead makes an API call to reset auto-away timer.

    However, if your status has already been set to away, you'll want to instead use the users.setPresence method to change it to active as a workaround.

  • Me:

    As you said, IRC client or no IRC client WebAPI should still be working, but it appears that there is an issue there: last_activity timestamp is NOT updated when the client is connected over IRC and user.setPresence or user.setActive commands are received over WebAPI. This happens despite those commands returning a SUCCESS.

    For all those curious, the debugging session is available as a gist.

  • Slack Support:

    You're right that the user.setActive call does not affect last activity when you're not connected to a Slack client, and only through the gateway. Terribly sorry for the misconception there! For now, I think we can both agree that making /away a proper toggle instead of requiring a workaround with the API would be the best way forward.

    I've highlight this quirk on our API methods to the gateways team. In the meantime, sending any message to the message server should also be changing your status if you've been set to auto-away (you can simply send a bump to @slackbot over the gateway and that should clear the away status).

So it appears that until Slack fixes the behaviour of the /away command on their IRC gateway, our best bet at staying "present" on their service is to send a message to @slackbot over the IRC gateway every half hour or so. One thing to mention though, it only works if the message invokes a response from slackbot. So, I guess it's a good job that slackbot is a very polite bot that knows to responds promptly to a simple "hello"!

/msg slackbot hello

Now, if only Slack IRC supported the /timer command ...

Debugging Slack WebAPI

The following is a record of the debugging session used to identify a problem with Slack WebAPI's user.setActive and user.setPresencecommands when the client is connected via Slack IRC gateway.

Setup

Acquire API token by visiting api.slack.com/web and looking in the "Authentication" section, towards the bottom of the page. Record it so that so that it can be used by the other commands in this session:

$ export SLACK-TOKEN=[the-value-of-the-user-token]

Acuire user id by running the following command and recording the value of user_id:

$ curl -L https://slack.com/api/auth.test?token=${SLACK-TOKEN}
$ export SLACK-USER=[the-value-of-user_id]

Ensure that recorded values, used through out this session, are correct and that Slack WebAPI is reachable:

$ curl -L "https://slack.com/api/users.info?user=${SLACK-USER}&token=${SLACK-TOKEN}"

{
    "ok": true,
    "user": {
        ...
        "is_admin": true,
        "is_owner": true,
        "is_primary_owner": true,
        "is_restricted": false,
        "is_ultra_restricted": false,
        "is_bot": false,
        "has_files": false,
        "has_2fa": false
    }
}

No client connected

  • IRC client: disconnected
  • OS X client: disconnected

$ curl -L "https://slack.com/api/users.getPresence?user=${SLACK-USER}&token=${SLACK-TOKEN}"

{
    "ok": true,
    "presence": "away",
    "online": false,
    "auto_away": false,
    "manual_away": false,
    "connection_count": 0
}

WebAPI correctly identifies 0 connections.

Only IRC client connected

  • IRC client: connected
  • OS X client: disconnected

$ curl -L "https://slack.com/api/users.getPresence?user=${SLACK-USER}&token=${SLACK-TOKEN}"

{
    "ok": true,
    "presence": "active",
    "online": true,
    "auto_away": false,
    "manual_away": false,
    "connection_count": 1,
    "last_activity": 1434565130
}

WebAPI correctly identifies that only one client is connected.

Next step is to issue a user.setActive request and see what happens to the last_activity timestamp.

$ curl -L "https://slack.com/api/users.setActive?token=${SLACK-TOKEN}"

{
    "ok": true
}

$ curl -L "https://slack.com/api/users.getPresence?user=${SLACK-USER}&token=${SLACK-TOKEN}"

{
    "ok": true,
    "presence": "active",
    "online": true,
    "auto_away": false,
    "manual_away": false,
    "connection_count": 1,
    "last_activity": 1434565130
}

Interestingly, even though users.setActive succeeded, last_activity timestamp has not been updated.

A similar problem occurs with users.setPresence: last_activity timestamp is not updated, despite the initial users.setPresence request succeeding. As demonstrated bellow:

$ curl -L "https://slack.com/api/users.setPresence?presence=away&token=${SLACK-TOKEN}"

{
    "ok": true
}

$ curl -L "https://slack.com/api/users.getPresence?user=${SLACK-USER}&token=${SLACK-TOKEN}"

{
    "ok": true,
    "presence": "away",
    "online": true,
    "auto_away": false,
    "manual_away": true,
    "connection_count": 1,
    "last_activity": 1434565130
}

$ curl -L "https://slack.com/api/users.setPresence?presence=auto&token=${SLACK-TOKEN}"

{
    "ok": true
}

$ curl -L "https://slack.com/api/users.getPresence?user=${SLACK-USER}&token=${SLACK-TOKEN}"

{
    "ok": true,
    "presence": "active",
    "online": true,
    "auto_away": false,
    "manual_away": false,
    "connection_count": 1,
    "last_activity": 1434565130
}

Only OS X client connected

  • IRC client: disconnected
  • OS X client: connected, app is "hidden", no actions within the app itself are taken

Re-running the above set of requests while connected with Slack's official OS X client, shows that both users.setActive and users.setPresence methods work as expected and update last_activity timestamp every time they are called.

$ curl -L "https://slack.com/api/users.getPresence?user=${SLACK-USER}&token=${SLACK-TOKEN}"

{
    "ok": true,
    "presence": "active",
    "online": true,
    "auto_away": false,
    "manual_away": false,
    "connection_count": 1,
    "last_activity": 1434565999
}

$ curl -L "https://slack.com/api/users.setActive?token=${SLACK-TOKEN}"

{
    "ok": true
}

$ curl -L "https://slack.com/api/users.getPresence?user=${SLACK-USER}&token=${SLACK-TOKEN}"

{
    "ok": true,
    "presence": "active",
    "online": true,
    "auto_away": false,
    "manual_away": false,
    "connection_count": 1,
    "last_activity": 1434566150
}

$ curl -L "https://slack.com/api/users.setPresence?presence=away&token=${SLACK-TOKEN}"

{
    "ok": true
}

$ curl -L "https://slack.com/api/users.getPresence?user=${SLACK-USER}&token=${SLACK-TOKEN}"

{
    "ok": true,
    "presence": "away",
    "online": true,
    "auto_away": false,
    "manual_away": true,
    "connection_count": 1,
    "last_activity": 1434566199
}

$ curl -L "https://slack.com/api/users.setPresence?presence=auto&token=${SLACK-TOKEN}"

{
    "ok": true
}

$ curl -L "https://slack.com/api/users.getPresence?user=${SLACK-USER}&token=${SLACK-TOKEN}"

{
    "ok": true,
    "presence": "active",
    "online": true,
    "auto_away": false,
    "manual_away": false,
    "connection_count": 1,
    "last_activity": 1434566350
}
@blalor

This comment has been minimized.

Copy link

@blalor blalor commented Mar 4, 2016

This appears to be improved? Maybe? Now it seems that AWAY -- regardless of the presence of the message -- toggles your presence.

[07:02:09]  <*raw>  YOU -> [AWAY]
[07:02:09]  <*raw>  IRC -> [:irc.tinyspeck.com 305 :You are no longer marked as being away]
[07:02:13]  <*raw>  YOU -> [AWAY]
[07:02:13]  <*raw>  IRC -> [:irc.tinyspeck.com 306 :You have been marked as being away]

AWAY without a message is supposed to remove your away status.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment