Giter VIP home page Giter VIP logo

take-care's Introduction

take-care

take-care is a Slack team and chore ownership manager.

Goal

take-care aims to 1) combat diffusion of responsibility and 2) optimize team behavior regarding necessary distractions. It does so by managing a weekly caretaker rotation for teams.

Caretakers are specific individuals in a team who are responsible for dealing with unattractive but important tasks, such as chores. It's easy for everyone on the team to fall into thinking "This is problematic, surely somebody else will deal with this". However, if this week it's been agreed that John is explicitly responsible for such problems, then John knows that he has to deal with the problem when he sees it and others know that they don't have to worry.

Additionally, other teams and individuals know that instead of using @channel somewhere and notifying the entire team about issues and questions, their first point of contact should be the caretaker. This minimizes distractions for the rest of the team, allowing them to focus on planned work.

take-care manages the caretaker rotation for you. It makes the team's current caretaker easily reachable via @<team-name>-caretaker Slack alias (via User Groups). It also provides a simple way to include the current caretaker's Slack handle in the topic of the team's channel.

Learn more by completing the Getting started tutorial below.

Getting started

This section assumes that you have a Slack API token and you use Docker for running take-care. If you don't have a token yet, complete the Getting a Slack API token section first. And if you don't want to use Docker, then see the Installation section.

First, save your API token to an environment variable. This allows the rest of the commands in this guide to work with simple copy-paste.

export SLACK_API_TOKEN=<token>

If you're planning to also use the Opsgenie integration, then make sure to also set the OPSGENIE_API_TOKEN environment variable. Follow the Getting an Opsgenie API token section below to create the API token if necessary.

Next, the configuration requires referring to users by their email address. Use the list-users command to find the email addresses.

$ docker run --rm -i -e "SLACK_API_TOKEN=$SLACK_API_TOKEN" deiwin/take-care:latest list-users
[email protected]: @alice
[email protected]: @bob
[email protected]: @carol
[email protected]: @dave
[email protected]: @eve
[email protected]: @faye
[email protected]: @gil
[email protected]: @hal

With the list of user email addresses at hand, you're ready to create the configuration for your teams. Save the following to a file called teams.dhall and edit according to your needs. The configuration is written in Dhall, a programmable configuration language with Haskell-like syntax.

let SlackEffect = ./types/core/Effect/Slack.dhall
                ? https://github.com/deiwin/take-care/raw/v0.7.1/types/core/Effect/Slack.dhall
let Effect = ./types/core/Effect.dhall
           ? https://github.com/deiwin/take-care/raw/v0.7.1/types/core/Effect.dhall
let Rotation = ./types/core/Rotation.dhall
             ? https://github.com/deiwin/take-care/raw/v0.7.1/types/core/Rotation.dhall
let teams = ./types/zoo/teams.dhall
          ? https://github.com/deiwin/take-care/raw/v0.7.1/types/zoo/teams.dhall
let concatSep = https://raw.githubusercontent.com/dhall-lang/dhall-lang/v21.1.0/Prelude/Text/concatSep.dhall
 in teams
      [ { members =
          { caretakers = [ [ "[email protected]", "[email protected]" ] ]
          , others = [ "[email protected]" ]
          }
        , name = "design"
        , topic =
            \(caretaker : Text) ->
              let standup = "Stand-up *9:30*"

              let board = "Board :incoming_envelope: https://team.board/url"

              let separator = ":paw_prints:"

              in  "${standup} ${separator} ${board} ${separator} Caretaker ${caretaker}"
        }
      , { members =
          { caretakers =
            [ [ "[email protected]", "[email protected]" ], [ "[email protected]", "[email protected]" ] ]
          , others = [] : List Text
          }
        , name = "dev"
        , topic = \(caretakers : Text) -> "${caretakers} are the caretakers"
        }
      ]
    # [ { rotation = Rotation.OpsgenieScheduleID "123e4567-e89b-12d3-a456-426614174000"
        , effects = [ Effect.Slack
                        ( SlackEffect.SetChannelTopic
                          { name = "tm-platform"
                          , topic = \(caretakers : List Text) -> "Caretaker(s): ${concatSep ", " caretakers}"
                          }
                        )
                    , Effect.Slack
                        ( SlackEffect.SetGroup
                          { handle = "platform-caretaker"
                          , name = "Platform team caretaker(s)"
                          , channels = ["tm-platform"]
                          }
                        )
                    ]
        }
      ]

Verify the configuration with the --dry-run flag for the ensure command.

$ docker run --rm -i -e "SLACK_API_TOKEN=$SLACK_API_TOKEN" -e "OPSGENIE_API_TOKEN=$OPSGENIE_API_TOKEN" deiwin/take-care:latest ensure --dry-run < teams.dhall
For [email protected]:
  Slack.SetChannelTopic #tm-design: Stand-up *9:30* :paw_prints: Board :incoming_envelope: https://team.board/url :paw_prints: Caretaker @alice
  Slack.SetGroup: @design-caretaker {name = "Team design caretaker(s)", channels = []}

For [email protected], [email protected], [email protected]:
  Slack.SetGroup: @design-team {name = "Team design", channels = ["tm-design"]}

For [email protected], [email protected]:
  Slack.SetChannelTopic #tm-dev: @eve, @gil are the caretakers
  Slack.SetGroup: @dev-caretaker {name = "Team dev caretaker(s)", channels = []}

For [email protected], [email protected], [email protected], [email protected]:
  Slack.SetGroup: @dev-team {name = "Team dev", channels = ["tm-dev"]}

For [email protected]:
  Slack.SetChannelTopic #tm-platform: Caretaker(s): @carol
  Slack.SetGroup: @platform-caretaker {name = "Platform team caretaker(s)", channels = ["tm-platform"]}

And finally, run the ensure command.

$ docker run --rm -i -e "SLACK_API_TOKEN=$SLACK_API_TOKEN" -e "OPSGENIE_API_TOKEN=$OPSGENIE_API_TOKEN" deiwin/take-care:latest ensure < teams.dhall
[info] [..] Parsing configuration ..
..
[info] [..] Completed applying all configurations
Program completed successfully! Exiting.

The ensure command ensures that

  • channels #tm-design, #tm-dev, and #tm-platform
    • exist,
    • include the configured team members, and
    • have their topic set per configuration;
  • user groups @design-team and @dev-team
    • exist and
    • consist of the configured team members; and
  • user groups @design-caretaker, @dev-caretaker, and @platform-caretaker
    • exist and
    • consist of the current caretakers (one per caretaker list per team).

Confiuration options

  • SLACK_API_TOKEN: Access token for Slack APIs. Currently required for all use-cases. See Getting a Slack API token below for instructions on how to get the token.
  • OPSGENIE_API_TOKEN: Access token for Opsgenie APIs. Only required when using the OpsgenieScheduleID rotation. See Getting an Opsgenie API token below for instructions.
  • PERSISTENT_FOLDER_PATH: An optional env variable. Setting this env variable enables deduplication.
    • If enabled, each configuration is applied only once. Every time the script runs it checks whether it has already applied a particular configuration and avoids re-applying it if has already been applied in the past with the same parameters (e.g. same result from resolving the rotation).
    • This is useful if you run the bot at a frequent schedule (e.g. every 5 minutes). Deduplication avoids unnecessary API calls and avoids reverting any manual changes people have made since the last execution (e.g. manually changing Slack User Groups or Channel Topics).
    • Setting the variable to an empty string will mean that the current folder will be used.
    • Leaving this environment variable unset disables this functionality.

Getting a Slack API token

  • Follow the Creating apps Slack guide to create a Slack app. You can call it Take Care, for example. The app will only live in your workspace.
  • Go to the OAuth & Permissions section of your app's management page, to add permissions for the following scopes:
    • channels:read
    • channels:write for creating channels and setting channel topics
    • usergroups:read
    • usergroups:write for managing user groups
    • users:read for finding individual users' Slack handles
    • users:read.email for finding user info based on their email
  • Save the permission changes.
  • In the same OAuth & Permissions section, scroll to the top and click on the Install App to Workspace button and authorize the installation.
  • You will then see a OAuth Access Token and a Bot User OAuth Access Token. The scopes above are configured separately for both. You can use either token, but the bot token will only work if you've enabled usergroup modifications for non-admins in your workspace. It is disabled by default, but can be enabled from Administration -> Settings & Permissions -> Permissions -> User Groups, or from https://.slack.com/admin/settings#user_group_restrictions

Getting an Opsgenie API token

Installation

The Getting started tutorial uses a deiwin/take-care:latest Docker image for running take-care. Docker is used so you don't have to worry about platform compatibility, but if you don't want to use Docker, then there's a few alternative's as well.

Downloading macOS binary

If you're using mac, you can find the latest release from GitHub and download its binary. At the moment only binaries for macOS will be published.

Building from source

Of course, you can also build the program from source:

git clone [email protected]:deiwin/take-care.git
cd take-care
stack install

take-care's People

Contributors

deiwin avatar rrebane avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

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.