Giter VIP home page Giter VIP logo

rota-slackbot's Introduction

rota-slackbot

Rota is a Slack app + bot I wrote for internal company use to manage team rotations. This app was built with the Bolt JavaScript Slack app framework.

Commands

  • @rota new "[new-rotation-name]" [description] creates a new rotation; rotation names can contain only lowercase letters, numbers, and hyphens. Technically the description is optional, but everyone will benefit if you provide one.
  • @rota delete "[rotation]" deletes the rotation completely (use with caution!).
  • @rota "[rotation]" description [new description] updates the description for a rotation.
  • @rota "[rotation]" staff [@user1 @user2 @user3] adds staff to a rotation; a space-separated list of usernames is expected as a parameter with usernames in the order of desired rotation (rotations with a staff list can be assigned using assign next).
  • @rota "[rotation]" reset staff clears a rotation's staff list (use with caution!).
  • @rota "[rotation]" assign [@user] [optional handoff message] assigns someone to the rotation and, optionally, sends a DM to them with handoff information.
  • @rota "[rotation]" assign next [optional handoff message] assigns the next person in the staff list to a rotation and, optionally, sends a DM to them with handoff information.
  • @rota "[rotation]" unassign removes the current user assignment for a rotation.
  • @rota "[rotation]" who reports the name of a rotation's assigned user.
  • @rota "[rotation]" about displays the rotation's description and on-call user publicly, and displays the staff list only to the user who issued the commend (this is to prevent excessive notifications for everyone on staff).
  • @rota "[rotation]" [message] sends a direct message to the on-call user for the rotation, notifying them that your message needs attention.
  • @rota list displays a list of all currently known rotations.
  • @rota help shows how to use the bot.

Tips

Rota does not handle message scheduling or automate rotation assignments. But don't worry — since @rota is a bot and not slash commands, it plays well with others! Here are some ways you can use the @rota bot in conjunction with other Slack features / third party apps.

Rotation Reminders

You can set a recurring reminder with Slack's /remind slash command to remind a rotation's on-call user to assign the next person in the rotation at some regular interval. This must be done at the channel level. You must ensure that Rota has been added to the channel you're setting the reminder in, also. For example:

(With Rota present in a #channel)

/remind [#channel] "@rota "[rotation]" assign the next user in the rotation using `@rota "[rotation]" assign next"` every Monday at 9am

Use quotes as shown in the snippet above to avoid unexpected behavior.

Note: You can't directly remind the @rota bot to do anything. For instance, /remind @rota "[rotation]" some message in 5 minutes will not work because it will try to send a direct message to the bot user, not a rotation's assigned human user. Slack cannot do this, and it will tell you so. When using /remind, you need to set the reminder in a channel. Reminders come from Slackbot, and Rota and Slackbot can't talk to each other.

Scheduling Messages

You can schedule messages to be delivered later. This is useful in case the on-call user is outside of hours. This works with both the built-in /remind slash task (similar to above), and also with third party Slack apps like Gator. Schedule the message in a channel that the @rota bot has been added to. Like so:

(In a #channel)

/gator @rota "[rotation]" I need some help with task XYZ please

Note: Keep in mind that if you use /remind, the message will come from @Slackbot, not from your username. If you need the person on rotation to know the message was from you, either include your username in the reminder when you set it up, or use a third-party app that delivers the message later from your account (e.g., Gator does this).

Caveat: Because the company I work(ed) at used Gator, Rota has been tested with /remind (which is part of Slack's core) and /gator (this testing occurred a while back, so it may be out of date if Gator has made significant updates to their API). If you use a different third-party scheduling Slack app, keep in mind that its interactions with Rota are untested and I make no guarantees the integrations will work together. (If you want to submit issues requesting additional third party integration support, you may use the help wanted label because their maintenance will be up to the community. Please feel free to fork this repo, add support, and then submit a PR.)

Development

Prerequisite: A Slack workspace that you can test in (without disturbing or spamming your coworkers 😛). You can create a new Slack workspace for free here.

Slack App Initial Setup

  1. Create a new Slack app.
  2. Name your app rota and select your preferred development Slack workspace.
  3. In the OAuth & Permissions section, add "Bot Token Scopes" for app_mentions:read, chat:write, and incoming-webhook.
  4. Under App Home, make sure your bot and app's name are rota.
  • Toggle on "Always Show My Bot as Online".
  • Enable the Home Tab.
  • Enable the Messages Tab.
  1. Under Incoming Webhooks, click the toggle to switch "Activate Incoming Webhooks" On.
  2. Under Install App, click the "Install to Workspace" button to install to your team workspace. When prompted, choose a channel to install to (it can be any channel.) This will generate a "Bot User OAuth Access Token" (which you will need in order to configure your local environment variables). The token will be displayed after you've installed your app. Note that if you update any Scopes later, you'll have to reinstall your app.

Database Setup

  1. You can use mongoDB Atlas to persist the rotation data store. Sign up for an account and create a FREE cluster.
  2. Select your preferred Cloud Provider & Region. You may also give your cluster a name if you like.
  3. Your cluster will take a few minutes to deploy.
  4. Once it's complete, click the CONNECT button. This will open a modal where you can set up a connection to your database.
  5. Click Add a Different IP Address and enter 0.0.0.0/0. This allows connections from any IP (keep in mind you should ensure good authentication with this.)
  6. Create a MongoDB User. This is a database user, and these credentials will be used in your MONGO_URI. Enter a Username and use the button to Autogenerate Secure Password. Make note of the username and password, then click "Create MongoDB User" and then proceed to the next step.
  7. In Choose a Connection Method, select "Connect your application." Use Node.js as the driver with the latest version available. Then copy the "Connection String Only."
  8. In a text file or other secure place (such as a password manager), paste the copied connection string and modify it to replace <username> and <password> with the credentials you just created in the previous step. Replace the database name (test) with a name of your choosing (e.g., rota).

Code and Configuration Setup

  1. Clone this repository locally to your desktop.
  2. Rename the .env_sample file to .env and update the placeholder info with the appropriate configuration from your Slack app settings and MongoDB Atlas connection.
  3. From your cloned directory, run $ npm install to install dependencies.
  4. Run $ npm start to start the app on the port specified in your .env file.
  5. Download and use ngrok to expose a public URL for your local web server.
  6. Once you have ngrok pointing to your Slack app's local development environment and the server is running, go to your Slack App settings and in the Event Subscriptions section, toggle On "Enable Events."
  7. For the "Request URL," enter https://your-ngrok-url/slack/events.
  8. In "Subscribe to bot events," add app_mention and app_home_opened.

Deployment

Follow the development instructions again to create a new Slack app, but in your production workspace.

The Slack app should be deployed with the following:

  • Node server stays running
  • SSL
  • Public URL (you do not need a pretty URL, since the URL is never displayed; it's only for Slack app configuration)

If you're very comfortable with Linux devops, Let's Encrypt, and have a domain name, I recommend DigitalOcean as a VPS if you've got other applications to deploy as well. This will keep costs down, as some providers (such as Heroku) charge per app.

If you want fast, easy deployments with CI/CD features and don't want to deal with devops, domains, or configuring SSL, I recommend a hobby dyno on Heroku.

Note: A free dyno on Heroku will not work well because the app will sleep after 30 minutes, which causes long response times when it needs to wake back up.

If using DigitalOcean (or a similar VPS), input your production environment variables in a .env file on your server.

If using Heroku, set up an app, push to your Heroku app using Git, then input your production environment variables in your Heroku app Settings (Heroku will not use your .env file).

Important: Whatever deployment option you choose, once you have a public domain for your Slack app with SSL, go into your production Slack app settings and update the Event Subscriptions Request URL to https://your-public-url/slack/events.


MIT License

rota-slackbot's People

Contributors

biancaghiurutan avatar dependabot[bot] avatar kmaida avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

rota-slackbot's Issues

Using the stated Rotation Reminder example in the readme throws error

As per the below, I set a reminder using this text:

/remind @rota #bot-testing “liveops” assign the next user in the rotation using: @rota "liveops" assign next at 5:49pm

Screenshot 2020-11-12 at 18 03 58

I have a liveops rotation config'd:

Screenshot 2020-11-12 at 18 16 27

To which rota-bot complains:

Screenshot 2020-11-12 at 18 07 23

Please could you update your docs to reflect how this should be configured?

Why @mention and not /action

Hello,

Was wondering why rota was implemented as a mention bot @rota and not a slack action /rota

Thought you could explain if there is a usage or technical motivation. 🙂

Thanks,

/CC @mramadan88

[feature] Add description

Add description to the “create” command (need reformatting of list data structure to support). Show description in list and an “info” command.

[enhancement][qa] Make rota more robust to sluggish Slack API

Sometimes when Slack's API is sluggish responding, Rota gets hung up on async calls and doesn't seem to completely process functions before moving on too quickly. Add some functionality to handle race conditions on slow networks or poor connectivity.

[feature] Store rotation

Store rotation members so that people don't need to know who is next in order to rotate the assignment.

This needs to include a few commands along with validation and error handling:

[rotation] staff <@U...> <@U...> <@U...>
[rotation] assign next
[rotation] reset staff

Support for NodeJS16

We are running this app in AWS Lambda with NodeJS12. NodeJS12 will no longer be supported by AWS and we will need to upgrade the runtime to nodejs16 but we are not sure if rota-slackbot would be able to run in this version. Could you please confirm if we can update the code to use nodejs16 and update our runtime to nodejs16?

deployment to heroku

Hello,

thanks a ton for developing this app. i'm looking to use it to try and rotate a few team chores like standups moderation and so. I'd like to deploy the app to heroku

  1. were others successful with deploying to heroku fully?
  2. do we have instructions or even notes somewhere that i could refer to?

Cheers,

/cc @mramadan88

[bug][fixed][qa] workflow is not a bot user

When a workflow mentions the bot, processing is unable to continue because there is no user available (user ID of sender is undefined). Need to build functionality to handle when message comes from something that is not a bot and has no user ID.

[enhancement] Change create to new

Change creation command to @rota new "[rotation]" description

Improves human readability / logic and reduces chance of error or mistaken commands

[qa] Test all commands with MongoDB

  • new (with description)
  • new (without description)
  • new (already exists)
  • description
  • description (empty)
  • description (doesn't exist)
  • delete
  • delete (doesn't exist)
  • about (without staff)
  • about (with staff)
  • about (doesn't exist)
  • staff
  • staff (extra spaces and commas)
  • staff (doesn't exist)
  • reset staff
  • reset staff (doesn't exist)
  • assign user
  • assign user with handoff message
  • assign user (doesn't exist)
  • assign next
  • assign next with handoff message
  • assign next (no staff saved)
  • assign next (current assignee not in list)
  • assign next (doesn't exist)
  • who
  • who (doesn't exist)
  • unassign
  • unassign (doesn't exist)
  • list
  • message
  • message (nobody assigned)
  • message (doesn't exist)
  • help

New rotation fails with TypeError: cleanText.matchAll

I've been following README's guide to set up rota locally with ngrok.
My rota app is installed. I can easily do things like @rota help and the bot responds.
But I cannot create a new rotation with something like:

@rota new "test" description

I get an error:

:cry: I'm sorry, I couldn't do that because an error occurred:
TypeError: cleanText.matchAll(...) is not a function or its return value is not iterable

In node.js output I see the following:

TypeError: cleanText.matchAll(...) is not a function or its return value is not iterable
    at Object.parseCmd (/Users/vitaly/git/rota-slackbot/utils/utils.js:108:31)
    at module.exports (/Users/vitaly/git/rota-slackbot/app-mentions/new.js:8:30)
    at app.event (/Users/vitaly/git/rota-slackbot/app-mentions.js:63:7)
    at process._tickCallback (internal/process/next_tick.js:68:7)

This is how a POST /slack/events request looks like according to ngrok:

{
    "token": "...",
    "team_id": "...",
    "api_app_id": "...",
    "event": {
        "client_msg_id": "...",
        "type": "app_mention",
        "text": "<@U01P006CVDY> new \"test\" desc",
        "user": "...",
        "ts": "1614064660.015100",
        "team": "...",
        "blocks": [
            {
                "type": "rich_text",
                "block_id": "zce",
                "elements": [
                    {
                        "type": "rich_text_section",
                        "elements": [
                            {
                                "type": "user",
                                "user_id": "U01P006CVDY"
                            },
                            {
                                "type": "text",
                                "text": " new \"test\" desc"
                            }
                        ]
                    }
                ]
            }
        ],
        "channel": "...",
        "event_ts": "1614064660.015100"
    },
    "type": "event_callback",
    "event_id": "Ev01P6AQKGLC",
    "event_time": 1614064660,
    "authorizations": [
        {
            "enterprise_id": null,
            "team_id": "...",
            "user_id": "...",
            "is_bot": true,
            "is_enterprise_install": false
        }
    ],
    "is_ext_shared_channel": false,
    "event_context": "1-app_mention-T1KGQ5533-C1KGA6UTY"
}

My local node.js is this one:

$ node -v
v10.23.3

I've tried with both smart quotes and normal quotes. It's all the same.
To me "text": "<@U01P006CVDY> new \"test\" desc" looks just fine, regexp should work. But it doesn't.

What I am doing wrong?

[enhancement] Support timy

Make sure there is support for timy in Rota (replacing Gator)

  • Install app
  • Test scheduled messages
  • If necessary, add coding support for scheduled messages with timy
  • Update documentation accordingly

[bug] Create without description sent as a message

If create command is used without a description, then it's sent as a message. This results in the following behavior:

  • If rotation exists and has assigned user, a message is sent to the on-call user
  • If rotation doesn't exist, a message error is produced saying the rotation doesn't exist so the message couldn't be delivered
  • If rotation exists and has no assigned user, a message error is produced saying nobody is assigned so the message can't be delivered and prompts to assign someone

Desired behavior: Allow empty descriptions

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.