{"id":13540324,"url":"https://github.com/monzo/response","last_synced_at":"2025-05-14T22:08:15.993Z","repository":{"id":34973776,"uuid":"181227803","full_name":"monzo/response","owner":"monzo","description":"Monzo's real-time incident response and reporting tool ⚡️","archived":false,"fork":false,"pushed_at":"2024-03-20T15:45:20.000Z","size":1434,"stargazers_count":1541,"open_issues_count":42,"forks_count":168,"subscribers_count":30,"default_branch":"master","last_synced_at":"2025-05-14T22:08:09.352Z","etag":null,"topics":["incident","incident-management","incident-reports","incident-response","response","slack-bot"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/monzo.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":"2019-04-13T20:55:52.000Z","updated_at":"2025-05-13T10:23:16.000Z","dependencies_parsed_at":"2024-05-28T09:53:08.058Z","dependency_job_id":"c800f83f-a630-420f-ae5c-429359261ee7","html_url":"https://github.com/monzo/response","commit_stats":{"total_commits":339,"total_committers":31,"mean_commits":"10.935483870967742","dds":0.6755162241887905,"last_synced_commit":"0f8d2a8378a02c1f4680a04e4a943d7e32234a22"},"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monzo%2Fresponse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monzo%2Fresponse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monzo%2Fresponse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monzo%2Fresponse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/monzo","download_url":"https://codeload.github.com/monzo/response/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254235700,"owners_count":22036964,"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":["incident","incident-management","incident-reports","incident-response","response","slack-bot"],"created_at":"2024-08-01T09:01:46.687Z","updated_at":"2025-05-14T22:08:10.976Z","avatar_url":"https://github.com/monzo.png","language":"JavaScript","readme":"[![PyPI](https://img.shields.io/pypi/v/django-incident-response.svg)](https://pypi.org/project/django-incident-response/)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/django-incident-response.svg)](https://docs.python.org/3/)\n[![PyPI - Django Version](https://img.shields.io/pypi/djversions/django-incident-response.svg)](https://docs.djangoproject.com/en/2.2/)\n[![Travis (.org)](https://img.shields.io/travis/monzo/response.svg)](https://travis-ci.org/monzo/response)\n[![GitHub](https://img.shields.io/github/license/monzo/response.svg)](https://choosealicense.com/licenses/mit/)\n\n# Response ⚡\n\nDealing with incidents can be stressful. On top of dealing with the issue at hand, responders are often responsible for handling comms, coordinating the efforts of other engineers, and reporting what happened after the fact.  Monzo built Response to help reduce the pressure and cognitive burden on engineers during an incident, and to make it easy to create information rich reports for others to learn from.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"300px\" src=\"./docs/headline_post.png\"\u003e\u003cbr /\u003e\n  \u003cem\u003eThe headline post when an incident is declared\u003c/em\u003e\n\u003c/p\u003e\n\nIf you're interested in how we use this tool at Monzo, there's an overview in [this video](https://twitter.com/evnsio/status/1116026261401247745).\n\n---\n\n# Try it out\n\nResponse is a Django app which you can include in your project.  If you're just looking to give it a try, follow the instuctions for the [demo app](demo/README.md)!\n\n---\n\n# Adding Response to your own project\n\n[Start a new Django project](https://docs.djangoproject.com/en/2.2/intro/tutorial01/), if you don't have one already:\n```\n$ django-admin startproject myincidentresponse\n```\n\nInstall response:\n```\n$ pip install django-incident-response\n```\n\nIn `settings.py`, add these lines to `INSTALLED_APPS`:\n```python\nINSTALLED_APPS = [\n    ...\n    \"after_response\",\n    \"rest_framework\",\n    \"bootstrap4\",\n    \"response.apps.ResponseConfig\",\n]\n```\n\nAdd the following to `settings.py`:\n\n```python\nUSE_TZ = False # if this exists elsewhere in your settings.py, just update the value\n\nSTATIC_ROOT = \"static\"\n\n# Django Rest Framework\nREST_FRAMEWORK = {\n    \"PAGE_SIZE\": 100,\n    \"DEFAULT_PAGINATION_CLASS\": \"rest_framework.pagination.LimitOffsetPagination\",\n    \"DEFAULT_PERMISSION_CLASSES\": [\n        \"rest_framework.permissions.IsAuthenticated\",\n    ],\n}\n#\n\n# Markdown Filter\nMARKDOWN_FILTER_WHITELIST_TAGS = [\n    \"a\", \"p\", \"code\", \"h1\", \"h2\", \"ul\", \"li\", \"strong\", \"em\", \"img\",\n]\n\nMARKDOWN_FILTER_WHITELIST_ATTRIBUTES = [\"src\", \"style\"]\n\nMARKDOWN_FILTER_WHITELIST_STYLES = [\n    \"width\", \"height\", \"border-color\", \"background-color\", \"white-space\",\n    \"vertical-align\", \"text-align\", \"border-style\", \"border-width\", \"float\",\n    \"margin\", \"margin-bottom\", \"margin-left\", \"margin-right\", \"margin-top\",\n]\n\nRESPONSE_LOGIN_REQUIRED = True\n```\n\nIn `urls.py`, add the following to `urlpatterns` (you may also need to import `include`):\n```python\nurlpatterns = [\n    ...\n    path('slack/', include('response.slack.urls')),\n    path('core/', include('response.core.urls')),\n    path('', include('response.ui.urls')),\n]\n```\n\n---\n\n# Completing the setup and config with Slack\n\n## 1. Create a Slack App\n\nFollow [these instructions](./docs/slack_app_create.md) to create a new Slack App.\n\n## 2. Update your `settings.py`\n\n| Environment Variable  | Descriptions |\n|---|---|\n| `SLACK_TOKEN`  | Response needs an OAuth access token to use the Slack API.\u003cbr /\u003e\u003cbr /\u003eCopy the Bot Token that starts `xoxb-...` from the OAuth \u0026 Permissions section of your Slack App and use it to set the `SLACK_TOKEN` variable.|\n| `SITE_URL`  | Response needs to know where it is running in order to create links to the UI in Slack.  Whilst running locally, you might want this set to something like `http://localhost:8000`. |\n| `SLACK_SIGNING_SECRET`  | Response uses the Slack signing secret to restrict access to public endpoints.\u003cbr /\u003e\u003cbr /\u003eCopy the Signing secret from the Basic Information page and use it to set the `SIGNING SECRET` variable. |\n| `INCIDENT_CHANNEL_ID`  | When an incident is declared, a 'headline' post is sent to a central channel.\u003cbr /\u003e\u003cbr /\u003eSee the [demo app settings](./demo/demo/settings/dev.py) for an example of how to get the incident channel ID from the Slack API. |\n| `INCIDENT_BOT_ID`  | We want to invite the Bot to all Incident Channels, so need to know its ID.\u003cbr /\u003e\u003cbr /\u003eSee the [demo app settings](./demo/demo/settings/dev.py) for an example of how to get the bot ID from the Slack API. |\n| `SLACK_CLIENT`  | Response needs a shared global instance of a Slack Client to talk to the Slack API. Typically this does not require any additional configuration. \u003cbr /\u003e\u003cpre\u003efrom response.slack.client import SlackClient\u003cbr /\u003eSLACK_CLIENT = SlackClient(SLACK_TOKEN)\u003c/pre\u003e |\n\n## 3. Running the server\n\nBefore you can complete the Slack app setup, you need to have the app running somewhere that's accesible to to the internet.  That means either deploying your Django project somewhere (see [here](https://lmgtfy.com/?q=deploy+django+app\u0026s=) or running it locally and exposing with something like [ngrok](https://ngrok.com/).\n\nFor simplicity, we'll assume you're developing using ngrok.\n\nFirst make sure your DB is fully migrated and up-to-date:\n```\npython3 manage.py migrate\n```\n\nNext, run the Django development server:\n```\npython3 manage.py runserver 0.0.0.0:8000\n```\n\nFinally, run ngrok:\n```\nngrok http 8000\n```\n\nMake note of the ngrok url as you'll need it in the following section as the `public-url`.\n\n## 4. Complete the Slack App Setup\n\nHead back to the Slack web UI and complete the configuration of your app, as [described here](./docs/slack_app_config.md).\n\n## 5. Test it's working!\n\nIn Slack, start an incident with `/incident Something's happened`.  You should see a post in your incidents channel!\n\n- Visit the incident doc by clicking the Doc link.\n- Create a comms channel by clicking the button.\n- In the comms channel check out the `@incident` commands.  You can find the ones available by entering `@incident help`.\n","funding_links":[],"categories":["\u003ca id=\"e1fc1d87056438f82268742dc2ba08f5\"\u003e\u003c/a\u003e事件响应\u0026\u0026取证\u0026\u0026内存取证\u0026\u0026数字取证","JavaScript","🚨 Incident Management e On-Call"],"sub_categories":["\u003ca id=\"d0f59814394c5823210aa04a8fcd1220\"\u003e\u003c/a\u003e事件响应\u0026\u0026IncidentResponse","Ferramentas Open Source"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonzo%2Fresponse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmonzo%2Fresponse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonzo%2Fresponse/lists"}