{"id":18719234,"url":"https://github.com/fbjorn/azure-devops-slack","last_synced_at":"2026-05-08T01:40:33.549Z","repository":{"id":113475601,"uuid":"604109926","full_name":"fbjorn/azure-devops-slack","owner":"fbjorn","description":"Forward pull request notifications from Azure DevOps to Slack","archived":false,"fork":false,"pushed_at":"2023-09-20T11:09:34.000Z","size":90,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-28T11:13:51.796Z","etag":null,"topics":["azure","azure-devops","pull-requests","slack","slack-bot"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fbjorn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-20T11:01:41.000Z","updated_at":"2023-09-15T11:20:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"07bde63f-5d9b-4ec0-ade2-58f6e56e116c","html_url":"https://github.com/fbjorn/azure-devops-slack","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fbjorn%2Fazure-devops-slack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fbjorn%2Fazure-devops-slack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fbjorn%2Fazure-devops-slack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fbjorn%2Fazure-devops-slack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fbjorn","download_url":"https://codeload.github.com/fbjorn/azure-devops-slack/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239581759,"owners_count":19662960,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure","azure-devops","pull-requests","slack","slack-bot"],"created_at":"2024-11-07T13:24:43.953Z","updated_at":"2025-11-10T17:30:23.846Z","avatar_url":"https://github.com/fbjorn.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Slack 🤝 Azure DevOps code reviews\n\n![Docker Image Version (latest semver)](https://img.shields.io/docker/v/fbjorn/devops-slack-pr-webhook?label=DockerHub\u0026logo=docker\u0026color=green\u0026logoColor=white)\n\nDo you\n\n- 🚀 collaboratively work on code in Azure DevOps,\n- 🧑‍💻 use Slack for work related communication,\n- 🥵 hate spammy notifications in your mailbox?\n\nWell, then you might like an idea to receive notifications from pull requests into\nSlack.\n\nIt requires a bit of setup, but then all (configured) team members will be able to get\ninformed in direct messages:\n\n1. **When a pull request is created, and they are assigned as reviewers**\n   \u003cimg width=\"663\" alt=\"image\" src=\"https://github.com/fbjorn/azure-devops-slack/assets/9670990/70736266-76aa-40f9-a48e-47a7ef7afeaa\"\u003e\n\n2. **When their pull request is approved**\n   \u003cimg width=\"653\" alt=\"image\" src=\"https://github.com/fbjorn/azure-devops-slack/assets/9670990/4003405c-6ac7-455f-bda4-41e408affd73\"\u003e\n\n3. **When someone leaves a comment on their PRs**\n   \u003cimg width=\"654\" alt=\"image\" src=\"https://github.com/fbjorn/azure-devops-slack/assets/9670990/f4d7f288-bc5e-4460-b866-14e11820d71f\"\u003e\n\n4. When someone replies to their comment _[IN PROGRESS]_\n\n# Setup\n\nFirst of all, I think that all this information is sensitive since you're working in\nprivate repositories. Thus, your data should not be transferred to 3rd parties. That's\nwhy I didn't create a shared Slack application. It's up to you to host your own\nnotification webhook, because each DevOps event gets transferred through it.\n\n## 1. Collect information about users\n\nSlack doesn't know anything about your Azure users and vice versa. So you will have to\ncreate a mapping for them manually. Moreover, not everyone in your team might want to\nopt in for such notifications, so it's still a wise idea to compose this list by hands.\n\nIf you have an Azure CLI installed (and `jq` as a bonus), you can use this snippet:\n\n```shell\naz devops user list | jq \".items[].user | [.displayName, .mailAddress]\"\n```\n\nOtherwise, go to `Organization settings` -\u003e `Users` (or ask your admin to gather this\ninformation) and save a list of emails and usernames.\n\nFollow this article to\n[find user IDs in Slack](https://www.workast.com/help/article/how-to-find-a-slack-user-id/).\n\nAfter that, create a `users.yaml` in the repository root with the following structure:\n\n```yaml\nusers:\n  - name_filter: Jane Doe\n    emails: [\"jane.doe@example.com\"]\n    slack_id: ABCDFOOBAR\n```\n\nName filter is used to match a user if it's not matched by the email (there are some\ncases when users change their emails but not the display name). It can be just a surname\nor a name as well if it's kinda unique.\n\n## 2. Create a Slack application\n\n1. Go to Slack application management and [create a new app](https://api.slack.com/apps)\n2. Choose \"From an app manifest\", select your workspace and copy the content from\n   [slack-app.manifest.json](./slack-app.manifest.json). Pick another name based on your\n   preferences. The important there is the permission to `chat:write`, otherwise the app\n   won't be able to post messages to DMs.\n3. Go to \"OAuth \u0026 Permissions\" and save the value of `Bot User OAuth Token`\n\n## 3. Deploy the webhook\n\nThere are few options for how you can deploy it. Feel free to suggest more. If you\ndecide to deploy it as a Google Cloud function, then you have to create a `.env` file\nwith the settings. If you want to deploy it as a Docker container, then it's up to you\nhow to pass the configuration inside. Anyway, the service is configured via the\nenvironment variables.\n\n```dotenv\n# [REQUIRED]\n# Slack application token from the previous step\nSLACK_BOT_TOKEN=xoxb-123-foobar\n\n# [REQUIRED for Docker, OPTIONAL for cloud functions]\n# A list of users that will receive the messages from the bot.\n# If you deploy as a Cloud Function, then no need to add it - the list will be\n# taken automatically from `users.yaml`. If you deploy as a docker container,\n# run `poetry run invoke convert-users`, this is the value you shoud set.\nUSERS='[ \u003carray of users in a JSON format\u003e ]'\n\n# [OPTIONAL]\n# An HTTP header that you might want to configure later when setting up\n# an event subscription in Azure DevOps. The value is up to you\nAPI_KEY=foo-bar\n\n# [OPTIONAL]\n# Set this if you want to log the DevOps events and additional debug information\nDEBUG=1\n```\n\n### Google Cloud Functions\n\nRun the following command to deploy it from your computer or CI. Requires\n[gcloud](https://cloud.google.com/sdk/docs/install) to be installed.\n\n```bash\npoetry run invoke deploy-cloud-function --help\n```\n\n### Anywhere as a Docker image\n\nDeploy this image to a platform you like and don't forget to set environment variables.\n\n```shell\nfbjorn/devops-slack-pr-webhook:latest\n```\n\nThe image is uploaded to\n[DockerHub](https://hub.docker.com/repository/docker/fbjorn/devops-slack-pr-webhook)\nautomatically from GitHub Actions.\n\n## 4. Set up triggers in Azure DevOps\n\nFinally, go to Project Settings in Azure DevOps:\n`https://dev.azure.com/\u003cORG\u003e/\u003cPROJ\u003e/_settings/`.\n\nOpen \"Service hooks\" section and click a plus icon for adding:\n\n- `Web hooks / Pull request commented on` (v2.0)\n- `Web hooks / Pull request created` (v1.0)\n- `Web hooks / Pull request updated` (v1.0)\n\nFor each of them, enter the URL of the service that you deployed on a previous step.\n\nOptionally, add an HTTP header `X-API-KEY:\u003ckey\u003e` if you configured it in the settings.\n\nSave an enjoy being up-to-date 🎉\n\n# Installation and local development\n\n```shell\n# install project dependencies\npoetry install\n\n# set up pre-commit hooks (required if you want to make PRs)\npre-commit install\n\n# get information about useful commands\npoetry run invoke --help\n\n# run unit tests\npoetry run pytest\n\n# update unit test snapshots\npoetry run pytest --snapshot-update\n\n# export Poetry dependencies to Cloud Functions -acceptable format\npoetry export \u003e requirements.txt\n```\n\n## Recording Azure DevOps events for unit tests\n\n```shell\n# 1. Run ngrok or other tool that exposes a local port to the internet\nngrok http 8080\n\n# 2. Edit corresponding service hook in Azure DevOps and set the new URL there\n\n# 3. Run the following command and perform an action you'd like to record\n#    (for example merging a pull request)\npoetry run invoke record-test-sample foo\n```\n\nThis will create a `foo.json` under [tests/samples](./tests/samples) and you can use\nthis file for testing the parser logic.\n\nMost likely, you don't want to expose IDs of your projects or users recording event\nsamples for tests. Neither do I. For that purpose, there's a script that simplifies\nthis. Create an `obfuscate.yaml` in the repo root with the following content:\n\n```yaml\n- from: Foo\n  into: Bar\n```\n\nAnd then run:\n\n```shell\npoetry run invoke obfuscate-tests\n```\n\nIt will replace all `Foo` occurrences in samples with `Bar`.\n\n# Contribution\n\nEvery PR and suggestion is welcomed. My team is using this project on daily basis, but\nyour Azure setup might be different resulting in potential bugs. Don't hesitate to\nreport issues, or record your event sample and add it to test cases.\n\nI believe this project is a great example of a service to deploy as a stateless cloud\nfunction, but I only tested it with Google. If you have successfully deployed it to\nanother cloud provider, please let me know, so we can update the instructions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffbjorn%2Fazure-devops-slack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffbjorn%2Fazure-devops-slack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffbjorn%2Fazure-devops-slack/lists"}