{"id":37096850,"url":"https://github.com/versuscontrol/versus-incident","last_synced_at":"2026-01-14T11:55:03.090Z","repository":{"id":277509228,"uuid":"927203006","full_name":"VersusControl/versus-incident","owner":"VersusControl","description":"An incident management tool supporting multi-channel alerting, customizable messages, and on-call integrations. Compatible with any tool supporting webhook alerts.","archived":false,"fork":false,"pushed_at":"2025-12-15T10:26:12.000Z","size":3887,"stargazers_count":376,"open_issues_count":5,"forks_count":51,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-12-18T10:30:12.871Z","etag":null,"topics":["aws","devops","devops-tools","golang","helm","lark","monitoring-tool","on-call","pagerduty","slack","sre","telegram"],"latest_commit_sha":null,"homepage":"https://versus-incident.devopsvn.tech","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/VersusControl.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-02-04T15:20:06.000Z","updated_at":"2025-12-15T10:25:25.000Z","dependencies_parsed_at":"2025-03-03T10:29:55.578Z","dependency_job_id":"cb2791e0-caf8-4238-aa71-5174d5d7a271","html_url":"https://github.com/VersusControl/versus-incident","commit_stats":null,"previous_names":["versuscontrol/versus-incident"],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/VersusControl/versus-incident","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VersusControl%2Fversus-incident","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VersusControl%2Fversus-incident/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VersusControl%2Fversus-incident/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VersusControl%2Fversus-incident/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/VersusControl","download_url":"https://codeload.github.com/VersusControl/versus-incident/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VersusControl%2Fversus-incident/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28419272,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["aws","devops","devops-tools","golang","helm","lark","monitoring-tool","on-call","pagerduty","slack","sre","telegram"],"created_at":"2026-01-14T11:55:02.408Z","updated_at":"2026-01-14T11:55:03.084Z","avatar_url":"https://github.com/VersusControl.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\" style=\"border-bottom: none\"\u003e\n  \u003cimg alt=\"Versus\" src=\"src/docs/images/versus.svg\"\u003e\n\u003c/h1\u003e\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/yourusername/versus)](https://goreportcard.com/report/github.com/yourusername/versus)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nAn incident management tool that supports alerting across multiple channels with easy custom messaging and on-call integrations. Compatible with any tool supporting webhook alerts, it's designed for modern DevOps teams to quickly respond to production incidents.\n\n🚀 Mastering your Site Reliability Engineering Skills: [On-Call in Action](https://leanpub.com/on-call-in-action).\n\n## Table of Contents\n- [Features](#features)\n- [Getting Started](#get-started-in-60-seconds)\n- [Development Custom Templates](#development-custom-templates)\n  - [Docker](#docker)\n  - [Understanding Custom Templates](#understanding-custom-templates-with-monitoring-webhooks)\n  - [Kubernetes](#kubernetes)\n  - [Helm Chart](#helm-chart)\n- [SNS Usage](#sns-usage)\n- [On-Call](#on-call)\n- [Configuration](#complete-configuration)\n- [Environment Variables](#environment-variables)\n- [Dynamic Configuration with Query Parameters](#dynamic-configuration-with-query-parameters)\n- [Template Syntax](https://versuscontrol.github.io/versus-incident/userguide/template-syntax.html)\n- [Migration Guides](#migration-guides)\n  - [Migrating to v1.2.0](#migrating-to-v120)\n  - [Migrating to v1.3.0](#migrating-to-v130)\n- [Roadmap](#roadmap)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Features\n\n- 🚨 **Multi-channel Alerts**: Send incident notifications to Slack, Microsoft Teams, Telegram, Viber, Email, and Lark (more channels coming!)\n- 📝 **Custom Templates**: Define your own alert messages using Go templates\n- 🔧 **Easy Configuration**: YAML-based configuration with environment variables support\n- 📡 **REST API**: Simple HTTP interface to receive alerts\n- 📡 **On-Call**: On-Call integrations with AWS Incident Manager and PagerDuty\n\n![Versus](src/docs/images/versus-architecture.svg)\n\n## Get Started in 60 Seconds\n\n### Easy Installation with Docker\n\n```bash\ndocker run -p 3000:3000 \\\n  -e SLACK_ENABLE=true \\\n  -e SLACK_TOKEN=your_token \\\n  -e SLACK_CHANNEL_ID=your_channel \\\n  ghcr.io/versuscontrol/versus-incident\n```\n\nVersus listens on port 3000 by default and exposes the `/api/incidents` endpoint, which you can configure as a webhook URL in your monitoring tools. This endpoint accepts JSON payloads from various monitoring systems and forwards the alerts to your configured notification channels.\n\n### Universal Alert Template Support\n\nOur default template (Slack, Telegram) automatically handles alerts from multiple sources, including:\n- Alertmanager (Prometheus)\n- Grafana Alerts\n- Sentry\n- CloudWatch SNS\n- FluentBit\n\n#### Example JSON Payload Sent by Alertmanager\n\n```bash\ncurl -X POST \"http://localhost:3000/api/incidents\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"receiver\": \"webhook-incident\",\n    \"status\": \"firing\",\n    \"alerts\": [ \n      {                \n        \"status\": \"firing\",                         \n        \"labels\": {                                   \n          \"alertname\": \"PostgresqlDown\",\n          \"instance\": \"postgresql-prod-01\",\n          \"severity\": \"critical\"\n        },                        \n        \"annotations\": {                                                \n          \"summary\": \"Postgresql down (instance postgresql-prod-01)\",\n          \"description\": \"Postgresql instance is down.\"\n        },                                     \n        \"startsAt\": \"2023-10-01T12:34:56.789Z\",                         \n        \"endsAt\": \"2023-10-01T12:44:56.789Z\",                \n        \"generatorURL\": \"\"\n      }                                  \n    ],                                 \n    \"groupLabels\": {                                                                  \n      \"alertname\": \"PostgresqlDown\"     \n    },                                                                    \n    \"commonLabels\": {                                                           \n      \"alertname\": \"PostgresqlDown\",                                                       \n      \"severity\": \"critical\",\n      \"instance\": \"postgresql-prod-01\"\n    },  \n    \"commonAnnotations\": {                                                                                  \n      \"summary\": \"Postgresql down (instance postgresql-prod-01)\",\n      \"description\": \"Postgresql instance is down.\"\n    },            \n    \"externalURL\": \"\"            \n  }'\n```\n\n#### Example JSON Payload Sent by Sentry\n\n```bash\ncurl -X POST \"http://localhost:3000/api/incidents\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"action\": \"created\",\n    \"data\": {\n      \"issue\": {\n        \"id\": \"123456\",\n        \"title\": \"Example Issue\",\n        \"culprit\": \"example_function in example_module\",\n        \"shortId\": \"PROJECT-1\",\n        \"project\": {\n          \"id\": \"1\",\n          \"name\": \"Example Project\",\n          \"slug\": \"example-project\"\n        },\n        \"metadata\": {\n          \"type\": \"ExampleError\",\n          \"value\": \"This is an example error\"\n        },\n        \"status\": \"unresolved\",\n        \"level\": \"error\",\n        \"firstSeen\": \"2023-10-01T12:00:00Z\",\n        \"lastSeen\": \"2023-10-01T12:05:00Z\",\n        \"count\": 5,\n        \"userCount\": 3\n      }\n    },\n    \"installation\": {\n      \"uuid\": \"installation-uuid\"\n    },\n    \"actor\": {\n      \"type\": \"user\",\n      \"id\": \"789\",\n      \"name\": \"John Doe\"\n    }\n  }'\n```\n\n**Result:**\n\n![Versus Result](src/docs/images/versus-result-01.png)\n\n## Development Custom Templates\n\n### Docker\n\nCreate a configuration file:\n\n```\nmkdir -p ./config \u0026\u0026 touch config.yaml\n```\n\n`config.yaml`:\n```yaml\nname: versus\nhost: 0.0.0.0\nport: 3000\n\nalert:\n  slack:\n    enable: true\n    token: ${SLACK_TOKEN}\n    channel_id: ${SLACK_CHANNEL_ID}\n    template_path: \"/app/config/slack_message.tmpl\" # For containerized env\n\n  telegram:\n    enable: false\n\n  msteams:\n    enable: false\n```\n\n**Slack Template**\n\nCreate your Slack message template, for example `config/slack_message.tmpl`:\n\n```\n🔥 *Critical Error in {{.ServiceName}}*\n\n❌ Error Details:\n```{{.Logs}}```\n\nOwner \u003c@{{.UserID}}\u003e please investigate\n```\n\n**Run with volume mount:**\n\n```bash\ndocker run -d \\\n  -p 3000:3000 \\\n  -v $(pwd)/config:/app/config \\\n  -e SLACK_ENABLE=true \\\n  -e SLACK_TOKEN=your_slack_token \\\n  -e SLACK_CHANNEL_ID=your_channel_id \\\n  --name versus \\\n  ghcr.io/versuscontrol/versus-incident\n```\n\nTo test, simply send an incident to Versus:\n\n```bash\ncurl -X POST http://localhost:3000/api/incidents \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"Logs\": \"[ERROR] This is an error log from User Service that we can obtain using Fluent Bit.\",\n    \"ServiceName\": \"order-service\",\n    \"UserID\": \"SLACK_USER_ID\"\n  }'\n```\n\nResponse:\n\n```json\n{\n    \"status\":\"Incident created\"\n}\n```\n\n**Result:**\n\n![Versus Result](src/docs/images/versus-result-02.png)\n\n### Understanding Custom Templates with Monitoring Webhooks\n\nWhen integrating Versus with any monitoring tool that supports webhooks, you need to understand the JSON payload structure that the tool sends to create an effective template. Here's a step-by-step guide:\n\n1. **Enable Debug Mode**: First, enable debug_body in your config to see the exact payload structure:\n\n```yaml\nalert:\n  debug_body: true  # This will print the incoming payload to the console\n```\n\n2. **Capture Sample Payload**: Send a test alert to Versus, then review the JSON structure within the logs of your Versus instance.\n\n3. **Create Custom Template**: Use the JSON structure to build a template that extracts the relevant information.\n\n#### FluentBit Integration Example\n\nHere's a sample FluentBit configuration to send logs to Versus:\n\n```ini\n[OUTPUT]\n    Name            http\n    Match           kube.production.user-service.*\n    Host            versus-host\n    Port            3000\n    URI             /api/incidents\n    Format          json\n    Header          Content-Type application/json\n    Retry_Limit     3\n```\n\n**Sample FluentBit JSON Payload:**\n\n```json\n{\n  \"date\": 1746354647.987654321,\n  \"log\": \"ERROR: Exception occurred while handling request ID: req-55ef8801\\nTraceback (most recent call last):\\n  File \\\"/app/server.py\\\", line 215, in handle_request\\n    user_id = session['user_id']\\nKeyError: 'user_id'\\n\",\n  \"stream\": \"stderr\",\n  \"time\": \"2025-05-04T17:30:47.987654321Z\",\n  \"kubernetes\": {\n    \"pod_name\": \"user-service-6cc8d5f7b5-wxyz9\",\n    \"namespace_name\": \"production\",\n    \"pod_id\": \"f0e9d8c7-b6a5-f4e3-d2c1-b0a9f8e7d6c5\",\n    \"labels\": {\n      \"app\": \"user-service\",\n      \"tier\": \"backend\",\n      \"environment\": \"production\"\n    },\n    \"annotations\": {\n      \"kubernetes.io/psp\": \"eks.restricted\",\n      \"monitoring.alpha.example.com/scrape\": \"true\"\n    },\n    \"host\": \"ip-10-1-2-4.ap-southeast-1.compute.internal\",\n    \"container_name\": \"auth-logic-container\",\n    \"docker_id\": \"f5e4d3c2b1a0f5e4d3c2b1a0f5e4d3c2b1a0f5e4d3c2b1a0f5e4d3c2b1a0f5e4\",\n    \"container_hash\": \"my-docker-hub/user-service@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890\",\n    \"container_image\": \"my-docker-hub/user-service:v2.1.0\"\n  }\n}\n```\n\n**FluentBit Slack Template (`config/slack_message.tmpl`):**\n\n```\n🚨 *Error in {{.kubernetes.labels.app}}* 🚨\n*Environment:* {{.kubernetes.labels.environment}}\n*Pod:* {{.kubernetes.pod_name}}\n*Container:* {{.kubernetes.container_name}}\n\n*Error Details:*\n```{{.log}}```\n\n*Time:* {{.time}}\n*Host:* {{.kubernetes.host}}\n\n\u003c@SLACK_ONCALL_USER_ID\u003e Please investigate!\n```\n\n#### More examples\n\n1. [How to Customize Alert Messages from Alertmanager to Slack and Telegram](https://medium.com/@hmquan08011996/how-to-customize-alert-messages-from-alertmanager-to-slack-and-telegram-786525713689)\n2. [Configuring Fluent Bit to Send Error Logs to Versus Incident](https://medium.com/@hmquan08011996/configuring-fluent-bit-to-send-error-logs-to-slack-and-telegram-89d11968bc30)\n3. [Configuring AWS CloudWatch to Send Alerts to Slack and Telegram](https://medium.com/@hmquan08011996/configuring-aws-cloudwatch-to-send-alerts-to-slack-and-telegram-ae0b8c077fc6)\n4. [How to Configure Sentry to Send Alerts to MS Teams](https://medium.com/@hmquan08011996/how-to-configure-sentry-to-send-alerts-to-ms-teams-08e0969f8578)\n5. [How to Configure Kibana to Send Alerts to Slack and Telegram](https://medium.com/@hmquan08011996/how-to-configure-kibana-to-send-alerts-to-slack-and-telegram-40e882e29bb4)\n6. [How to Configure Grafana to Send Alerts to Slack and Telegram](https://medium.com/@hmquan08011996/how-to-configure-grafana-to-send-alerts-to-slack-and-telegram-b11a784369b8)\n7. [How to Configure OpenSearch to Send Alerts to Slack and Telegram](https://medium.com/@hmquan08011996/how-to-configure-opensearch-to-send-alerts-to-slack-and-telegram-43d177d36791)\n\n#### Other Templates\n\n**Telegram Template**\n\nFor Telegram, you can use HTML formatting. Create your Telegram message template, for example `config/telegram_message.tmpl`:\n```\n🚨 \u003cb\u003eCritical Error Detected!\u003c/b\u003e 🚨\n📌 \u003cb\u003eService:\u003c/b\u003e {{.ServiceName}}\n⚠️ \u003cb\u003eError Details:\u003c/b\u003e\n{{.Logs}}\n```\n\nThis template will be parsed with HTML tags when sending the alert to Telegram.\n\n**Email Template**\n\nCreate your email message template, for example `config/email_message.tmpl`:\n\n```\nSubject: Critical Error Alert - {{.ServiceName}}\n\nCritical Error Detected in {{.ServiceName}}\n----------------------------------------\n\nError Details:\n{{.Logs}}\n\nPlease investigate this issue immediately.\n\nBest regards,\nVersus Incident Management System\n```\n\nThis template supports both plain text and HTML formatting for email notifications.\n\n**Microsoft Teams Template**\n\nCreate your Teams message template, for example `config/msteams_message.tmpl`. The Microsoft Teams integration now supports rich Markdown formatting that gets converted to Adaptive Cards:\n\n```markdown\n# Critical Error in {{.ServiceName}}\n \n### Error Details:\n\n```{{.Logs}}```\n\n## Additional Information\n\n- Source: {{.Source}}\n- Severity: {{.Severity}}\n- Incident ID: {{.IncidentID}}\n\nPlease [investigate immediately](https://your-dashboard-url.com/incidents/{{.IncidentID}})\n\n*Alert sent by Versus Incident Management*\n```\n\nThis template uses Markdown features that will be rendered as an Adaptive Card in Microsoft Teams:\n- Headings with different levels (`#`, `##`, `###`)\n- Code blocks with triple backticks\n- Unordered lists with `-` or `*`\n- Ordered lists with `1.`, `2.`, etc.\n- Links with `[text](url)` syntax\n- Bold text with `**double asterisks**`\n\n**Important Note (April 2025)**: Versus Incident now automatically extracts a summary from your template's first heading (or first line if no heading exists) to ensure proper display in Microsoft Teams notifications. It also creates a plain text fallback version for clients that don't support Adaptive Cards.\n\n**Lark Template**\n\nCreate your Lark message template, for example `config/lark_message.tmpl`:\n\n```markdown\nCritical Error in {{.ServiceName}}\n\n**Error Details:**\n\n```{{.Logs}}```\n\n{{ if .AckURL }}\n\n[Click here to acknowledge]({{.AckURL}})\n{{ end }}\n```\n\nThis template uses Markdown formatting for optimal display in Lark channels.\n\n### Kubernetes\n\n1. Create a secret for Slack:\n```bash\n# Create secret\nkubectl create secret generic versus-secrets \\\n  --from-literal=slack_token=$SLACK_TOKEN \\\n  --from-literal=slack_channel_id=$SLACK_CHANNEL_ID\n```\n\n2. Create ConfigMap for config and template file, for example `versus-config.yaml`:\n```yaml\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: versus-config\ndata:\n  config.yaml: |\n    name: versus\n    host: 0.0.0.0\n    port: 3000\n\n    alert:\n      slack:\n        enable: true\n        token: ${SLACK_TOKEN}\n        channel_id: ${SLACK_CHANNEL_ID}\n        template_path: \"/app/config/slack_message.tmpl\"\n\n      telegram:\n        enable: false\n\n  slack_message.tmpl: |\n    *Critical Error in {{.ServiceName}}*\n    ----------\n    Error Details:\n    ```\n    {{.Logs}}\n    ```\n    ----------\n    Owner \u003c@{{.UserID}}\u003e please investigate\n\n```\n\n```bash\nkubectl apply -f versus-config.yaml\n```\n\n3. Create `versus-deployment.yaml`:\n```yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: versus-incident\nspec:\n  replicas: 2\n  selector:\n    matchLabels:\n      app: versus-incident\n  template:\n    metadata:\n      labels:\n        app: versus-incident\n    spec:\n      containers:\n      - name: versus-incident\n        image: ghcr.io/versuscontrol/versus-incident\n        ports:\n        - containerPort: 3000\n        livenessProbe:\n          httpGet:\n            path: /healthz\n            port: 3000\n        env:\n          - name: SLACK_CHANNEL_ID\n            valueFrom:\n              secretKeyRef:\n                name: versus-secrets\n                key: slack_channel_id\n          - name: SLACK_TOKEN\n            valueFrom:\n              secretKeyRef:\n                name: versus-secrets\n                key: slack_token\n        volumeMounts:\n        - name: versus-config\n          mountPath: /app/config/config.yaml\n          subPath: config.yaml\n        - name: versus-config\n          mountPath: /app/config/slack_message.tmpl\n          subPath: slack_message.tmpl\n      volumes:\n      - name: versus-config\n        configMap:\n          name: versus-config\n\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: versus-service\nspec:\n  selector:\n    app: versus-incident\n  ports:\n    - protocol: TCP\n      port: 3000\n      targetPort: 3000\n```\n\n4. Apply:\n```bash\nkubectl apply -f versus-deployment.yaml\n```\n\n### Helm Chart\n\nYou can install the Versus Incident Helm chart using OCI registry:\n\n```bash\nhelm install versus-incident oci://ghcr.io/versuscontrol/charts/versus-incident\n```\n\n### Install with Custom Values\n\n```bash\n# Install with custom configuration from a values file\nhelm install \\\n  versus-incident \\\n  oci://ghcr.io/versuscontrol/charts/versus-incident \\\n  -f values.yaml\n```\n\n### Upgrading an Existing Installation\n\n```bash\n# Upgrade an existing installation with the latest version\nhelm upgrade \\\n  versus-incident \\\n  oci://ghcr.io/versuscontrol/charts/versus-incident\n\n# Upgrade with custom values\nhelm upgrade \\\n  versus-incident \\\n  oci://ghcr.io/versuscontrol/charts/versus-incident \\\n  -f values.yaml\n```\n\nFor detailed information, please refer to the document [here](https://github.com/VersusControl/versus-incident/blob/main/helm/versus-incident).\n\n## SNS Usage\n```bash\ndocker run -d \\\n  -p 3000:3000 \\\n  -e SLACK_ENABLE=true \\\n  -e SLACK_TOKEN=your_slack_token \\\n  -e SLACK_CHANNEL_ID=your_channel_id \\\n  -e SNS_ENABLE=true \\\n  -e SNS_TOPIC_ARN=$SNS_TOPIC_ARN \\\n  -e SNS_HTTPS_ENDPOINT_SUBSCRIPTION=https://your-domain.com \\\n  -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY \\\n  -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_KEY \\\n  --name versus \\\n  ghcr.io/versuscontrol/versus-incident\n```\n\nSend test message using AWS CLI:\n```\naws sns publish \\\n  --topic-arn $SNS_TOPIC_ARN \\\n  --message '{\"ServiceName\":\"test-service\",\"Logs\":\"[ERROR] Test error\",\"UserID\":\"U12345\"}' \\\n  --region $AWS_REGION\n```\n\n**A key real-world application of Amazon SNS** involves integrating it with CloudWatch Alarms. This allows CloudWatch to publish messages to an SNS topic when an alarm state changes (e.g., from OK to ALARM), which can then trigger notifications to Slack, Telegram, or Email via Versus Incident with a custom template.\n\n## On-Call\n\nVersus supports On-Call integrations with AWS Incident Manager and PagerDuty. Updated configuration example with on-call features:\n\n```yaml\nname: versus\nhost: 0.0.0.0\nport: 3000\npublic_host: https://your-ack-host.example # Required for on-call ack\n\n# ... existing alert configurations ...\n\noncall:\n  ### Enable overriding using query parameters\n  # /api/incidents?oncall_enable=false =\u003e Set to `true` or `false` to enable or disable on-call for a specific alert\n  # /api/incidents?oncall_wait_minutes=0 =\u003e Set the number of minutes to wait for acknowledgment before triggering on-call. Set to `0` to trigger immediately\n  initialized_only: true  # Initialize on-call feature but don't enable by default; use query param oncall_enable=true to enable for specific requests\n  enable: false # Use this to enable or disable on-call for all alerts\n  wait_minutes: 3 # If you set it to 0, it means there's no need to check for an acknowledgment, and the on-call will trigger immediately\n  provider: aws_incident_manager # Valid values: \"aws_incident_manager\" or \"pagerduty\"\n\n  aws_incident_manager: # Used when provider is \"aws_incident_manager\"\n    response_plan_arn: ${AWS_INCIDENT_MANAGER_RESPONSE_PLAN_ARN}\n    other_response_plan_arns: # Optional: Enable overriding the default response plan ARN using query parameters, eg /api/incidents?awsim_other_response_plan=prod\n      prod: ${AWS_INCIDENT_MANAGER_OTHER_RESPONSE_PLAN_ARN_PROD}\n      dev: ${AWS_INCIDENT_MANAGER_OTHER_RESPONSE_PLAN_ARN_DEV}\n      staging: ${AWS_INCIDENT_MANAGER_OTHER_RESPONSE_PLAN_ARN_STAGING}\n\n  pagerduty: # Used when provider is \"pagerduty\"\n    routing_key: ${PAGERDUTY_ROUTING_KEY} # Integration/Routing key for Events API v2 (REQUIRED)\n    other_routing_keys: # Optional: Enable overriding the default routing key using query parameters, eg /api/incidents?pagerduty_other_routing_key=infra\n      infra: ${PAGERDUTY_OTHER_ROUTING_KEY_INFRA}\n      app: ${PAGERDUTY_OTHER_ROUTING_KEY_APP}\n      db: ${PAGERDUTY_OTHER_ROUTING_KEY_DB}\n\nredis: # Required for on-call functionality\n  insecure_skip_verify: true # dev only\n  host: ${REDIS_HOST}\n  port: ${REDIS_PORT}\n  password: ${REDIS_PASSWORD}\n  db: 0\n```\n\n**Explanation:**\n\nThe `oncall` section includes:\n1. `enable`: A boolean to toggle on-call functionality for all incidents (default: `false`).\n2. `initialized_only`: Initialize on-call feature but keep it disabled by default. When set to `true`, on-call is triggered only for requests that explicitly include `?oncall_enable=true` in the URL. This is useful for having on-call ready but not enabled for all alerts.\n3. `wait_minutes`: Time in minutes to wait for an acknowledgment before escalating (default: `3`). Setting it to `0` triggers the on-call immediately.\n4. `provider`: Specifies which on-call provider to use (\"aws_incident_manager\" or \"pagerduty\").\n5. `aws_incident_manager`: Configuration for AWS Incident Manager when it's the selected provider, including `response_plan_arn` and `other_response_plan_arns`.\n6. `pagerduty`: Configuration for PagerDuty when it's the selected provider, including routing keys.\n\nThe redis section is required when `oncall.enable` or `oncall.initialized_only` is true. It configures the Redis instance used for state management or queuing, with settings like host, port, password, and db.\n\nFor detailed information on integration, please refer to the document here: [On-Call setup with Versus](https://versuscontrol.github.io/versus-incident/oncall/on-call-introduction.html).\n\n## Complete Configuration\n\nA sample configuration file is located at `config/config.yaml`:\n\n```yaml\nname: versus\nhost: 0.0.0.0\nport: 3000\npublic_host: https://your-ack-host.example # Required for on-call ack\n\n# Proxy configuration (global settings)\n# Use this when your network blocks access to messaging services like Telegram, Viber, or Lark\nproxy:\n  url: ${PROXY_URL}           # HTTP/HTTPS/SOCKS5 proxy URL (e.g., http://proxy.example.com:8080)\n  username: ${PROXY_USERNAME} # Optional proxy username for authenticated proxies\n  password: ${PROXY_PASSWORD} # Optional proxy password for authenticated proxies\n\nalert:\n  debug_body: true  # Default value, will be overridden by DEBUG_BODY env var\n\n  slack:\n    enable: false  # Default value, will be overridden by SLACK_ENABLE env var\n    token: ${SLACK_TOKEN}            # From environment\n    channel_id: ${SLACK_CHANNEL_ID}  # From environment\n    template_path: \"config/slack_message.tmpl\"\n    message_properties:\n      button_text: \"Acknowledge Alert\" # Custom text for the acknowledgment button\n      button_style: \"primary\" # Button style: \"primary\" (default blue), \"danger\" (red), or empty for default gray\n      disable_button: false # Set to true to disable the button, if you want to handle acknowledgment differently\n\n  telegram:\n    enable: false  # Default value, will be overridden by TELEGRAM_ENABLE env var\n    bot_token: ${TELEGRAM_BOT_TOKEN} # From environment\n    chat_id: ${TELEGRAM_CHAT_ID} # From environment\n    template_path: \"config/telegram_message.tmpl\"\n    use_proxy: false # Set to true to use global proxy settings for Telegram API calls\n\n  viber:\n    enable: false  # Default value, will be overridden by VIBER_ENABLE env var\n    bot_token: ${VIBER_BOT_TOKEN} # From environment (token for bot or channel)\n    api_type: ${VIBER_API_TYPE} # From environment - \"channel\" (default) or \"bot\"\n    # Channel API (recommended for incident management)\n    channel_id: ${VIBER_CHANNEL_ID} # From environment (required for channel API)\n    # Bot API (for individual user notifications)  \n    user_id: ${VIBER_USER_ID} # From environment (required for bot API)\n    template_path: \"config/viber_message.tmpl\"\n    use_proxy: false # Set to true to use global proxy settings for Viber API calls\n\n  email:\n    enable: false # Default value, will be overridden by EMAIL_ENABLE env var\n    smtp_host: ${SMTP_HOST} # From environment\n    smtp_port: ${SMTP_PORT} # From environment\n    username: ${SMTP_USERNAME} # From environment\n    password: ${SMTP_PASSWORD} # From environment\n    to: ${EMAIL_TO} # From environment, can contain multiple comma-separated email addresses\n    subject: ${EMAIL_SUBJECT} # From environment\n    template_path: \"config/email_message.tmpl\"\n\n  msteams:\n    enable: false # Default value, will be overridden by MSTEAMS_ENABLE env var\n    power_automate_url: ${MSTEAMS_POWER_AUTOMATE_URL} # Automatically works with both Power Automate workflow URLs and legacy Office 365 webhooks\n    template_path: \"config/msteams_message.tmpl\"\n    other_power_urls: # Optional: Define additional Power Automate URLs for multiple MS Teams channels\n      qc: ${MSTEAMS_OTHER_POWER_URL_QC} # Power Automate URL for QC team\n      ops: ${MSTEAMS_OTHER_POWER_URL_OPS} # Power Automate URL for Ops team\n      dev: ${MSTEAMS_OTHER_POWER_URL_DEV} # Power Automate URL for Dev team\n\n  lark:\n    enable: false # Default value, will be overridden by LARK_ENABLE env var\n    webhook_url: ${LARK_WEBHOOK_URL} # Lark webhook URL (required)\n    template_path: \"config/lark_message.tmpl\"\n    use_proxy: false # Set to true to use global proxy settings for Lark API calls\n    other_webhook_urls: # Optional: Enable overriding the default webhook URL using query parameters, eg /api/incidents?lark_other_webhook_url=dev\n      dev: ${LARK_OTHER_WEBHOOK_URL_DEV}\n      prod: ${LARK_OTHER_WEBHOOK_URL_PROD}\n\n  queue:\n  enable: true\n  debug_body: true\n\n  # AWS SNS\n  sns:\n    enable: false\n    https_endpoint_subscription_path: /sns # URI to receive SNS messages, e.g. ${host}:${port}/sns or ${https_endpoint_subscription}/sns\n    # Options If you want to automatically create an sns subscription\n    https_endpoint_subscription: ${SNS_HTTPS_ENDPOINT_SUBSCRIPTION} # If the user configures an HTTPS endpoint, then an SNS subscription will be automatically created, e.g. https://your-domain.com\n    topic_arn: ${SNS_TOPIC_ARN}\n    \n  # AWS SQS\n  sqs:\n    enable: false\n    queue_url: ${SQS_QUEUE_URL}\n    \n  # GCP Pub Sub\n  pubsub:\n    enable: false\n    \n  # Azure Event Bus\n  azbus:\n    enable: false\n\noncall:\n  ### Enable overriding using query parameters\n  # /api/incidents?oncall_enable=false =\u003e Set to `true` or `false` to enable or disable on-call for a specific alert\n  # /api/incidents?oncall_wait_minutes=0 =\u003e Set the number of minutes to wait for acknowledgment before triggering on-call. Set to `0` to trigger immediately\n  initialized_only: false  # Initialize on-call feature but don't enable by default; use query param oncall_enable=true to enable for specific requests\n  enable: false # Use this to enable or disable on-call for all alerts\n  wait_minutes: 3 # If you set it to 0, it means there's no need to check for an acknowledgment, and the on-call will trigger immediately\n  provider: aws_incident_manager # Valid values: \"aws_incident_manager\" or \"pagerduty\"\n\n  aws_incident_manager: # Used when provider is \"aws_incident_manager\"\n    response_plan_arn: ${AWS_INCIDENT_MANAGER_RESPONSE_PLAN_ARN}\n    other_response_plan_arns: # Optional: Enable overriding the default response plan ARN using query parameters, eg /api/incidents?awsim_other_response_plan=prod\n      prod: ${AWS_INCIDENT_MANAGER_OTHER_RESPONSE_PLAN_ARN_PROD}\n      dev: ${AWS_INCIDENT_MANAGER_OTHER_RESPONSE_PLAN_ARN_DEV}\n      staging: ${AWS_INCIDENT_MANAGER_OTHER_RESPONSE_PLAN_ARN_STAGING}\n\n  pagerduty: # Used when provider is \"pagerduty\"\n    routing_key: ${PAGERDUTY_ROUTING_KEY} # Integration/Routing key for Events API v2 (REQUIRED)\n    other_routing_keys: # Optional: Enable overriding the default routing key using query parameters, eg /api/incidents?pagerduty_other_routing_key=infra\n      infra: ${PAGERDUTY_OTHER_ROUTING_KEY_INFRA}\n      app: ${PAGERDUTY_OTHER_ROUTING_KEY_APP}\n      db: ${PAGERDUTY_OTHER_ROUTING_KEY_DB}\n\nredis: # Required for on-call functionality\n  insecure_skip_verify: true # dev only\n  host: ${REDIS_HOST}\n  port: ${REDIS_PORT}\n  password: ${REDIS_PASSWORD}\n  db: 0\n```\n\n## Environment Variables\n\nThe application relies on several environment variables to configure alerting services. Below is an explanation of each variable:\n\n### Common\n| Variable          | Description |\n|------------------|-------------|\n| `DEBUG_BODY`   | Set to `true` to enable print body send to Versus Incident. |\n\n### Proxy Configuration\n| Variable          | Description |\n|------------------|-------------|\n| `PROXY_URL`      | HTTP/HTTPS/SOCKS5 proxy URL (e.g., `http://proxy.example.com:8080`). Used by channels that have `use_proxy: true` enabled. |\n| `PROXY_USERNAME` | Optional username for authenticated proxy servers. |\n| `PROXY_PASSWORD` | Optional password for authenticated proxy servers. |\n\n**Note**: The proxy configuration is global and can be used by any channel (Telegram, Viber, Lark) by setting their respective `use_proxy` field to `true` in the configuration.\n\n### Slack Configuration\n| Variable          | Description |\n|------------------|-------------|\n| `SLACK_ENABLE`   | Set to `true` to enable Slack notifications. |\n| `SLACK_TOKEN`    | The authentication token for your Slack bot. |\n| `SLACK_CHANNEL_ID` | The ID of the Slack channel where alerts will be sent. **Can be overridden per request using the `slack_channel_id` query parameter.** |\n\nSlack also supports interactive acknowledgment buttons that can be configured using the following properties in the `config.yaml` file:\n\n```yaml\nalert:\n  slack:\n    # ...other slack configuration...\n    message_properties:\n      button_text: \"Acknowledge Alert\" # Custom text for the acknowledgment button\n      button_style: \"primary\" # Button style: \"primary\" (default blue), \"danger\" (red), or empty for default gray\n      disable_button: false # Set to true to disable the button, if you want to handle acknowledgment differently\n```\n\nThese properties allow you to:\n- Customize the text of the acknowledgment button (`button_text`)\n- Change the style of the button (`button_style`) - options are \"primary\" (blue), \"danger\" (red), or leave empty for default gray\n- Disable the interactive button entirely (`disable_button`) if you want to handle acknowledgment through other means\n\n### Telegram Configuration\n| Variable              | Description |\n|----------------------|-------------|\n| `TELEGRAM_ENABLE`    | Set to `true` to enable Telegram notifications. |\n| `TELEGRAM_BOT_TOKEN` | The authentication token for your Telegram bot. |\n| `TELEGRAM_CHAT_ID`   | The chat ID where alerts will be sent. **Can be overridden per request using the `telegram_chat_id` query parameter.** |\n| `TELEGRAM_USE_PROXY` | Set to `true` to use the global proxy configuration for Telegram API calls. Useful when Telegram is blocked. |\n\n### Viber Configuration\n\nViber supports two types of API integrations:\n- **Channel API** (default): Send messages to Viber channels for team notifications\n- **Bot API**: Send messages to individual users for personal notifications\n\n**When to use Channel API:**\n- ✅ Broadcasting to team channels\n- ✅ Public incident notifications\n- ✅ Automated system alerts\n- ✅ Better for most incident management scenarios\n- ✅ No individual user setup required\n\n**When to use Bot API:**\n- ✅ Personal notifications to specific users\n- ✅ Direct messaging for individual alerts\n- ⚠️ Limited to individual users only\n- ⚠️ Requires users to interact with bot first\n- ⚠️ User IDs can be hard to obtain\n\n| Variable            | Description |\n|--------------------|-------------|\n| `VIBER_ENABLE`     | Set to `true` to enable Viber notifications. |\n| `VIBER_BOT_TOKEN`  | The authentication token for your Viber bot or channel. |\n| `VIBER_API_TYPE`   | API type: `\"channel\"` (default) for team notifications or `\"bot\"` for individual messaging. |\n| `VIBER_CHANNEL_ID` | The channel ID where alerts will be posted (required for channel API). **Can be overridden per request using the `viber_channel_id` query parameter.** |\n| `VIBER_USER_ID`    | The user ID where alerts will be sent (required for bot API). **Can be overridden per request using the `viber_user_id` query parameter.** |\n| `VIBER_USE_PROXY`  | Set to `true` to use the global proxy configuration for Viber API calls. Useful when Viber is blocked. |\n\n### Email Configuration\n| Variable          | Description |\n|------------------|-------------|\n| `EMAIL_ENABLE`   | Set to `true` to enable email notifications. |\n| `SMTP_HOST`      | The SMTP server hostname (e.g., smtp.gmail.com). |\n| `SMTP_PORT`      | The SMTP server port (e.g., 587 for TLS). |\n| `SMTP_USERNAME`  | The username/email for SMTP authentication. |\n| `SMTP_PASSWORD`  | The password or app-specific password for SMTP authentication. |\n| `EMAIL_TO`       | The recipient email address(es) for incident notifications. Can be multiple addresses separated by commas. **Can be overridden per request using the `email_to` query parameter.** |\n| `EMAIL_SUBJECT`  | The subject line for email notifications. **Can be overridden per request using the `email_subject` query parameter.** |\n\n### Microsoft Teams Configuration\n| Variable          | Description |\n|------------------|-------------|\n| `MSTEAMS_ENABLE`   | Set to `true` to enable Microsoft Teams notifications. |\n| `MSTEAMS_POWER_AUTOMATE_URL` | Automatically works with both Power Automate workflow URLs and legacy Office 365 webhooks. |\n| `MSTEAMS_OTHER_POWER_URL_QC`  | (Optional) Power Automate URL for the QC team channel. **Can be selected per request using the `msteams_other_power_url=qc` query parameter.** |\n| `MSTEAMS_OTHER_POWER_URL_OPS` | (Optional) Power Automate URL for the Ops team channel. **Can be selected per request using the `msteams_other_power_url=ops` query parameter.** |\n| `MSTEAMS_OTHER_POWER_URL_DEV` | (Optional) Power Automate URL for the Dev team channel. **Can be selected per request using the `msteams_other_power_url=dev` query parameter.** |\n\n### Lark Configuration\n| Variable          | Description |\n|------------------|-------------|\n| `LARK_ENABLE`   | Set to `true` to enable Lark notifications. |\n| `LARK_WEBHOOK_URL` | The webhook URL for Lark notifications. |\n| `LARK_USE_PROXY` | Set to `true` to use the global proxy configuration for Lark API calls. Useful when Lark is blocked. |\n| `LARK_OTHER_WEBHOOK_URL_DEV` | (Optional) Webhook URL for the development environment. **Can be selected per request using the `lark_other_webhook_url=dev` query parameter.** |\n| `LARK_OTHER_WEBHOOK_URL_PROD` | (Optional) Webhook URL for the production environment. **Can be selected per request using the `lark_other_webhook_url=prod` query parameter.** |\n\n### Queue Services Configuration\n| Variable                     | Description |\n|-----------------------------|-------------|\n| `SNS_ENABLE`             | Set to `true` to enable receive Alert Messages from SNS. |\n| `SNS_HTTPS_ENDPOINT_SUBSCRIPTION`             | This specifies the HTTPS endpoint to which SNS sends messages. When an HTTPS endpoint is configured, an SNS subscription is automatically created. If no endpoint is configured, you must create the SNS subscription manually using the CLI or AWS Console. E.g. `https://your-domain.com`. |\n| `SNS_TOPIC_ARN`             | AWS ARN of the SNS topic to subscribe to. |\n| `SQS_ENABLE`             | Set to `true` to enable receive Alert Messages from AWS SQS. |\n| `SQS_QUEUE_URL`             | URL of the AWS SQS queue to receive messages from. |\n\n### On-Call Configuration\n| Variable                          | Description |\n|----------------------------------|-------------|\n| `ONCALL_ENABLE`             | Set to `true` to enable on-call functionality. **Can be overridden per request using the `oncall_enable` query parameter.** |\n| `ONCALL_INITIALIZED_ONLY`   | Set to `true` to initialize on-call feature but keep it disabled by default. When enabled, on-call is triggered only for requests that explicitly include `?oncall_enable=true` in the URL. |\n| `ONCALL_WAIT_MINUTES`       | Time in minutes to wait for acknowledgment before escalating (default: 3). **Can be overridden per request using the `oncall_wait_minutes` query parameter.** |\n| `ONCALL_PROVIDER`           | Specify the on-call provider to use (\"aws_incident_manager\" or \"pagerduty\"). |\n| `AWS_INCIDENT_MANAGER_RESPONSE_PLAN_ARN` | The ARN of the AWS Incident Manager response plan to use for on-call escalations. Required if on-call provider is \"aws_incident_manager\". |\n| `AWS_INCIDENT_MANAGER_OTHER_RESPONSE_PLAN_ARN_PROD` | (Optional) AWS Incident Manager response plan ARN for production environment. **Can be selected per request using the `awsim_other_response_plan=prod` query parameter.** |\n| `AWS_INCIDENT_MANAGER_OTHER_RESPONSE_PLAN_ARN_DEV` | (Optional) AWS Incident Manager response plan ARN for development environment. **Can be selected per request using the `awsim_other_response_plan=dev` query parameter.** |\n| `AWS_INCIDENT_MANAGER_OTHER_RESPONSE_PLAN_ARN_STAGING` | (Optional) AWS Incident Manager response plan ARN for staging environment. **Can be selected per request using the `awsim_other_response_plan=staging` query parameter.** |\n| `PAGERDUTY_ROUTING_KEY`     | Integration/Routing key for PagerDuty Events API v2. Required if on-call provider is \"pagerduty\". |\n| `PAGERDUTY_OTHER_ROUTING_KEY_INFRA` | (Optional) PagerDuty routing key for infrastructure team. **Can be selected per request using the `pagerduty_other_routing_key=infra` query parameter.** |\n| `PAGERDUTY_OTHER_ROUTING_KEY_APP`   | (Optional) PagerDuty routing key for application team. **Can be selected per request using the `pagerduty_other_routing_key=app` query parameter.** |\n| `PAGERDUTY_OTHER_ROUTING_KEY_DB`    | (Optional) PagerDuty routing key for database team. **Can be selected per request using the `pagerduty_other_routing_key=db` query parameter.** |\n\nWhen you have `initialized_only: true` in your configuration (rather than `enable: true`), on-call is only triggered for incidents that explicitly request it. This is useful when:\n\n1. You want the on-call feature ready but not active for all alerts\n2. You need to selectively enable on-call only for high-priority services or incidents\n3. You want to let your monitoring system decide which alerts should trigger on-call\n\n### Redis Configuration\n| Variable          | Description |\n|------------------|-------------|\n| `REDIS_HOST`     | The hostname or IP address of the Redis server. Required if on-call is enabled. |\n| `REDIS_PORT`     | The port number of the Redis server. Required if on-call is enabled. |\n| `REDIS_PASSWORD` | The password for authenticating with the Redis server. Required if on-call is enabled and Redis requires authentication. |\n\nEnsure these environment variables are properly set before running the application.\n\n## Dynamic Configuration with Query Parameters\nWe provide a way to overwrite configuration values using query parameters, allowing you to send alerts to different channels and customize notification behavior on a per-request basis.\n\n| Query Parameter          | Description |\n|------------------|-------------|\n| `slack_channel_id`   | The ID of the Slack channel where alerts will be sent. Use: `/api/incidents?slack_channel_id=\u003cyour_value\u003e`. |\n| `telegram_chat_id`   | The chat ID where Telegram alerts will be sent. Use: `/api/incidents?telegram_chat_id=\u003cyour_chat_id\u003e`. |\n| `viber_user_id`   | The user ID where Viber alerts will be sent (for bot API). Use: `/api/incidents?viber_user_id=\u003cyour_user_id\u003e`. |\n| `viber_channel_id`   | The channel ID where Viber alerts will be posted (for channel API). Use: `/api/incidents?viber_channel_id=\u003cyour_channel_id\u003e`. |\n| `email_to`   | Overrides the default recipient email address for email notifications. Use: `/api/incidents?email_to=\u003crecipient_email\u003e`. |\n| `email_subject`   | Overrides the default subject line for email notifications. Use: `/api/incidents?email_subject=\u003ccustom_subject\u003e`. |\n| `msteams_other_power_url`   | Overrides the default Microsoft Teams Power Automate flow by specifying an alternative key (e.g., qc, ops, dev). Use: `/api/incidents?msteams_other_power_url=qc`. |\n| `lark_other_webhook_url`   | Overrides the default Lark webhook URL by specifying an alternative key (e.g., dev, prod). Use: `/api/incidents?lark_other_webhook_url=dev`. |\n| `oncall_enable`          | Set to `true` or `false` to enable or disable on-call for a specific alert. Use: `/api/incidents?oncall_enable=false`. |\n| `oncall_wait_minutes`    | Set the number of minutes to wait for acknowledgment before triggering on-call. Set to `0` to trigger immediately. Use: `/api/incidents?oncall_wait_minutes=0`. |\n| `awsim_other_response_plan` | Overrides the default AWS Incident Manager response plan by specifying an alternative key (e.g., prod, dev, staging). Use: `/api/incidents?awsim_other_response_plan=prod`. |\n| `pagerduty_other_routing_key` | Overrides the default PagerDuty routing key by specifying an alternative key (e.g., infra, app, db). Use: `/api/incidents?pagerduty_other_routing_key=infra`. |\n\n### Examples for Each Query Parameter\n\n#### Slack Channel Override\n\nTo send an alert to a specific Slack channel (e.g., a dedicated channel for database issues):\n\n```bash\ncurl -X POST \"http://localhost:3000/api/incidents?slack_channel_id=C01DB2ISSUES\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"Logs\": \"[ERROR] Database connection pool exhausted.\",\n    \"ServiceName\": \"database-service\",\n    \"UserID\": \"U12345\"\n  }'\n```\n\n#### Telegram Chat Override\n\nTo send an alert to a different Telegram chat (e.g., for network monitoring):\n\n```bash\ncurl -X POST \"http://localhost:3000/api/incidents?telegram_chat_id=-1001234567890\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"Logs\": \"[ERROR] Network latency exceeding thresholds.\",\n    \"ServiceName\": \"network-monitor\",\n    \"UserID\": \"U12345\"\n  }'\n```\n\n#### Viber Channel Override (Default API)\n\nTo send an alert to a different Viber channel (e.g., for team notifications):\n\n```bash\ncurl -X POST \"http://localhost:3000/api/incidents?viber_channel_id=your_channel_id\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"Logs\": \"[ERROR] Production database connection failure.\",\n    \"ServiceName\": \"database\",\n    \"UserID\": \"U12345\"\n  }'\n```\n\n#### Viber User Override (Bot API)\n\nTo send an alert to a different Viber user (e.g., for personal notifications):\n\n```bash\ncurl -X POST \"http://localhost:3000/api/incidents?viber_user_id=4UHcAFe/T6w4SJjQ3M8VKA==\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"Logs\": \"[ERROR] Mobile app service degradation detected.\",\n    \"ServiceName\": \"mobile-api\",\n    \"UserID\": \"U12345\"\n  }'\n```\n\n#### Email Recipient Override\n\nTo send an email alert to a specific recipient with a custom subject:\n\n```bash\ncurl -X POST \"http://localhost:3000/api/incidents?email_to=network-team@yourdomain.com\u0026email_subject=Urgent%20Network%20Issue\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"Logs\": \"[ERROR] Load balancer failing health checks.\",\n    \"ServiceName\": \"load-balancer\",\n    \"UserID\": \"U12345\"\n  }'\n```\n\n#### Microsoft Teams Channel Override\n\nYou can configure multiple Microsoft Teams channels using the `other_power_urls` setting:\n\n```yaml\nalert:\n  msteams:\n    enable: true\n    power_automate_url: ${MSTEAMS_POWER_AUTOMATE_URL}\n    template_path: \"config/msteams_message.tmpl\"\n    other_power_urls:\n      qc: ${MSTEAMS_OTHER_POWER_URL_QC}\n      ops: ${MSTEAMS_OTHER_POWER_URL_OPS}\n      dev: ${MSTEAMS_OTHER_POWER_URL_DEV}\n```\n\nThen, to send an alert to the QC team's Microsoft Teams channel:\n\n```bash\ncurl -X POST \"http://localhost:3000/api/incidents?msteams_other_power_url=qc\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"Logs\": \"[ERROR] Quality check failed for latest deployment.\",\n    \"ServiceName\": \"quality-service\",\n    \"UserID\": \"U12345\"\n  }'\n```\n\n#### Lark Webhook Override\n\nYou can configure multiple Lark webhook URLs using the `other_webhook_urls` setting:\n\n```yaml\nalert:\n  lark:\n    enable: true\n    webhook_url: ${LARK_WEBHOOK_URL}\n    template_path: \"config/lark_message.tmpl\"\n    other_webhook_urls:\n      dev: ${LARK_OTHER_WEBHOOK_URL_DEV}\n      prod: ${LARK_OTHER_WEBHOOK_URL_PROD}\n```\n\nThen, to send an alert to the development environment's Lark webhook:\n\n```bash\ncurl -X POST \"http://localhost:3000/api/incidents?lark_other_webhook_url=dev\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"Logs\": \"[ERROR] Development server failure.\",\n    \"ServiceName\": \"dev-server\",\n    \"UserID\": \"U12345\"\n  }'\n```\n\n#### On-Call Controls\n\nTo disable on-call escalation for a non-critical alert:\n\n```bash\ncurl -X POST \"http://localhost:3000/api/incidents?oncall_enable=false\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"Logs\": \"[WARNING] This is a minor issue that doesn't require on-call response.\",\n    \"ServiceName\": \"monitoring-service\",\n    \"UserID\": \"U12345\"\n  }'\n```\n\nTo trigger on-call immediately without the normal wait period for a critical issue:\n\n```bash\ncurl -X POST \"http://localhost:3000/api/incidents?oncall_wait_minutes=0\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"Logs\": \"[CRITICAL] Payment processing system down.\",\n    \"ServiceName\": \"payment-service\",\n    \"UserID\": \"U12345\"\n  }'\n```\n\n#### AWS Incident Manager Response Plan Override\n\nYou can configure multiple AWS Incident Manager response plans using the `other_response_plan_arns` setting:\n\n```yaml\noncall:\n  enable: true\n  wait_minutes: 3\n  provider: aws_incident_manager\n  \n  aws_incident_manager:\n    response_plan_arn: ${AWS_INCIDENT_MANAGER_RESPONSE_PLAN_ARN}  # Default response plan\n    other_response_plan_arns:\n      prod: ${AWS_INCIDENT_MANAGER_OTHER_RESPONSE_PLAN_ARN_PROD}  # Production environment\n      dev: ${AWS_INCIDENT_MANAGER_OTHER_RESPONSE_PLAN_ARN_DEV}    # Development environment\n      staging: ${AWS_INCIDENT_MANAGER_OTHER_RESPONSE_PLAN_ARN_STAGING}  # Staging environment\n```\n\nThen, to use a specific AWS Incident Manager response plan for a production environment issue:\n\n```bash\ncurl -X POST \"http://localhost:3000/api/incidents?awsim_other_response_plan=prod\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"Logs\": \"[CRITICAL] Production database cluster failure.\",\n    \"ServiceName\": \"prod-database\",\n    \"UserID\": \"U12345\"\n  }'\n```\n\n#### PagerDuty Routing Key Override\n\nYou can configure multiple PagerDuty routing keys using the `other_routing_keys` setting:\n\n```yaml\noncall:\n  enable: true\n  wait_minutes: 3\n  provider: pagerduty\n  \n  pagerduty:\n    routing_key: ${PAGERDUTY_ROUTING_KEY}  # Default routing key\n    other_routing_keys:\n      infra: ${PAGERDUTY_OTHER_ROUTING_KEY_INFRA}  # Infrastructure team\n      app: ${PAGERDUTY_OTHER_ROUTING_KEY_APP}      # Application team \n      db: ${PAGERDUTY_OTHER_ROUTING_KEY_DB}        # Database team\n```\n\nThen, to use a specific PagerDuty routing key for the infrastructure team:\n\n```bash\ncurl -X POST \"http://localhost:3000/api/incidents?pagerduty_other_routing_key=infra\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"Logs\": \"[ERROR] Server load balancer failure in us-west-2.\",\n    \"ServiceName\": \"infrastructure\",\n    \"UserID\": \"U12345\"\n  }'\n```\n\n### Combining Multiple Parameters\n\nYou can combine multiple query parameters to customize exactly how an incident is handled:\n\n```bash\ncurl -X POST \"http://localhost:3000/api/incidents?slack_channel_id=C01PROD\u0026telegram_chat_id=-987654321\u0026oncall_enable=true\u0026oncall_wait_minutes=1\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"Logs\": \"[CRITICAL] Multiple service failures detected in production environment.\",\n    \"ServiceName\": \"core-infrastructure\",\n    \"UserID\": \"U12345\",\n    \"Severity\": \"CRITICAL\"\n  }'\n```\n\nThis will:\n1. Send the alert to a specific Slack channel (`C01PROD`)\n2. Send the alert to a specific Telegram chat (`-987654321`)\n3. Enable on-call escalation with a shortened 1-minute wait time\n\n## Migration Guides\n\n### Migrating to v1.2.0\n\nVersion 1.2.0 introduces enhanced Microsoft Teams integration using Power Automate.\n\nFor complete migration instructions, please see our [detailed migration guide](https://versuscontrol.github.io/versus-incident/migration/migration-v1.2.0.html).\n\n### Migrating to v1.3.0\n\nVersion 1.3.0 introduces a new integration with PagerDuty.\n\nFor complete migration instructions, please see our [detailed migration guide](https://versuscontrol.github.io/versus-incident/migration/migration-v1.3.0.html).\n\n## Roadmap\n\n- [x] Add Telegram support\n- [x] Add Email support\n- [x] Add SNS subscription\n- [x] Add MS Team support\n- [x] Add Viber support\n- [x] Add Lark support\n- [x] Add support for queue listeners (AWS SQS, GCP Cloud Pub/Sub, Azure Service Bus)\n- [x] Support multiple templates\n- [ ] API Server for Incident Management\n- [ ] Web UI\n- [x] On-call integrations (AWS Incident Manager, PagerDuty)\n- [ ] Prometheus metrics\n\nComplete Project Diagram\n\n![Versus Control](src/docs/images/road-map.svg)\n\n## Contributing\n\nWe welcome contributions! Please follow these steps:\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## License\n\nDistributed under the MIT License. See `LICENSE` for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fversuscontrol%2Fversus-incident","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fversuscontrol%2Fversus-incident","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fversuscontrol%2Fversus-incident/lists"}