{"id":20317653,"url":"https://github.com/dynatrace/custom-webhook-python","last_synced_at":"2025-10-06T07:55:07.406Z","repository":{"id":143388784,"uuid":"135320032","full_name":"Dynatrace/Custom-Webhook-Python","owner":"Dynatrace","description":null,"archived":false,"fork":false,"pushed_at":"2023-05-22T21:34:37.000Z","size":319,"stargazers_count":12,"open_issues_count":1,"forks_count":9,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-10-06T07:55:07.070Z","etag":null,"topics":["dev-program","integration"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Dynatrace.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}},"created_at":"2018-05-29T15:55:57.000Z","updated_at":"2024-03-22T12:48:35.000Z","dependencies_parsed_at":"2023-07-09T22:31:45.539Z","dependency_job_id":null,"html_url":"https://github.com/Dynatrace/Custom-Webhook-Python","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Dynatrace/Custom-Webhook-Python","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynatrace%2FCustom-Webhook-Python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynatrace%2FCustom-Webhook-Python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynatrace%2FCustom-Webhook-Python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynatrace%2FCustom-Webhook-Python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dynatrace","download_url":"https://codeload.github.com/Dynatrace/Custom-Webhook-Python/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dynatrace%2FCustom-Webhook-Python/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278577935,"owners_count":26009701,"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","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["dev-program","integration"],"created_at":"2024-11-14T18:34:41.241Z","updated_at":"2025-10-06T07:55:07.401Z","avatar_url":"https://github.com/Dynatrace.png","language":"Python","readme":"# Custom Webhook for Dynatrace notifications\n\n![](doc/webhook_overview_.png)\n\nThis is a sample python application that works as a custom webhook with Dynatrace. The webhook runs as a [Flask Microservice](http://flask.pocoo.org/) that handles problem notifications (POST requests) coming from Dynatrace (SaaS or Managed). In this sample application there are different use cases shown like calling a legacy executable on the host (use case taken from a Bank), showing and polling the problem feed via the webserver, commenting the results of the integrations in the dynatrace problem or sending an SMS notification. The idea is that you understand this application and use it as a template, understand how the [Dynatrace API](https://www.dynatrace.com/support/help/dynatrace-api/ \"Dynatrace API\")  works, specially the [problem API](https://www.dynatrace.com/support/help/dynatrace-api/problems/what-does-the-problems-api-provide/) so you can build your own integration the way you need it: be it a plain notifications integration, a CMDB synchronization or even a self-healing system.\n\n## Getting started\nThese instructions will get you a copy of the project up and running on a windows or linux machine.\n\n### Prerequisites\n* Python runtime (with pip): [Download](https://www.python.org/downloads/)\n* Dynatrace Tenant: [Get your Saas Trial Tenant](https://www.dynatrace.com/trial/)\n* Twilio Account (optional for sending SMS): [Get your Twilio free trial](https://www.twilio.com/)\n\n### Installing\nFor installing the Webhook in your machine you only need to clone the repository and then download the python dependencies with pip.\n\n#### Download the repository\n\n\tgit clone https://github.com/Dynatrace/Custom-Webhook-Python.git\n\n#### Download and install the requirements with pip\nGo to the main directory (webhook) and install the python project dependencies by running the following command from the terminal:\n\n\tpip install -r requirements.txt\n\n#### Set up your configuration\nbefore running the Flask Web Microservice, we should configure some small things. The webhook configuration is saved in a JSON file named `config.json`. In here you will configure the webhook for your environment, meaning the URL of your Dynatrace Tenant and the API Token used for allow communication with Dynatrace. \n\n##### Description of `config.json`:\n\n\t{\n\t\t\"dynatrace\": {\n\t\t\t\"tenant\": \"https://xxxxxxxx.live.dynatrace.com\",\tURL of Dynatrace SaaS or Managed\n\t\t\t\"api_token\": \"YOUR_API_TOKEN\"\t\t\t\tAPI Token for problem notifications\n\t\t},\n\t\t\"webhook\": {\n\t\t\t\"username\": \"dynatrace\",\t\tUser for custom notification\n\t\t\t\"password\": \"s3cr3t\",\t\t\tPassword for custom notification\n\t\t\t\"interface\": \"0.0.0.0\",\t\t\tInterface where the webhook should listen to. Default all interfaces. \n\t\t\t\"port\": 5000\t\t\t\tPort where the webhook listens for communication.\n\t\t},\n\t\t\"dir_received\": \"problems_received\",\t\tFolder to save the problems when received.\n\t\t\"dir_sent\": \"problems_sent\",\t\t\tFolder to save the problems details after being sent.\n\t\t\"log_dir\": \"log\",\t\t\t\tLog folder \t\n\t\t\"log_file\": \"webhook.log\",\t\t\tLog file\n\t\t\"incident_notification\": {\t\t\t\t\t\t\n\t\t\t\"active\": true,\t\t\t\tLegacy notification flag. Default true (possible values true/false)\n\t\t\t\"exec_win\": \"legacy_script.bat\",\tWindows legacy executable (simulation). It can be also an .exe\n\t\t\t\"exec_unix\": \"legacy_script.sh\"\t\tLinux legacy executable (simulation). It can also be an .so\n\t\t},\n\t\t\"sms_notification\": {\n\t\t\t\"active\": false,\t\t\t\t\tSMS notification (posible values true/false)\n\t\t\t\"twilio_account\":\"AC027e8af87e11d3f080bXXXXXXXXXXX\",\tTwilio Account\n\t\t\t\"twilio_token\":\"2e3070021e718067df2b2dXXXXXXXXXX\",\tTwilio API Token\n\t\t\t\"twilio_number\": \"+18652699XXX\",\t\t\tTwilio Number (sent from)\n\t\t\t\"to_number\": \"+49170XXXXXXX\"\t\t\t\tNumber to notify (sent to)\n\t\t}\n\t}\n\n##### Minimal set up in config.json\n\n- add your Dynatrace tenant URL\n- add the API Token *(Log into your Dynatrace environment and go to Settings \u003e Integration \u003e Dynatrace API. Generate a new access token by typing a unique string into the Key label field, then click the Generate key button)*\n\n\n## Running the webhook\n\n### Starting the webserver\nNow we are all set to run the webhook. You downloaded the repository, installed python and it's dependencies and entered your configuration, now lets test it!\n\nCall the webhook.py application from the console with the parameter \"run\" to start the webserver.\n\n\t$\u003e python webhook.py run\n\n\tDynatrace Custom Webhook Integration\n\t----------------------------------------------\n\t\n\tStarting the Flask Web Microservice\n\t * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)\n\n\nYou'll see a message in the console that the web server is up \u0026 running and listening on port 5000. If you go to your browser and call http://localhost:5000 you'll become a response similar like this:\n\n![Screenshot of the Webhook showing the runtime status](doc/webserver_localhost.png)\n\nYou'll be able to see the runtime status of the application like runtime parameters and how many problems it has received and how many problems have been integrated to other systems (legacy script and/or sms). \n\n\n### Poll the problem feed from the webserver \n\nYou can test the Dynatrace API and fetch the [Problem Feed](https://www.dynatrace.com/support/help/dynatrace-api/problems/how-do-i-fetch-the-complete-list-of-problems/) for a specific time range. The time ranges supported are: hour, 2hours, 6hours, day, week and month. \n\nIn the browser you'll see the time range displayed in buttons. If you click on one it will send an HTTP GET request to the Flask Microservice with a parameter for example to poll all problems of the week: `http://localhost:5000/?relativeTime=week` this request will be handled by the python application and it will then poll the problem API subsequently.\n\n![Screenshot of the Webhook polling problems for the last week](doc/webserver_poll_month.png)\n\n### Bind Dynatrace to the custom webhook\n\nOk, until now we successfully checked that the webhook can connect to Dynatrace and can poll problem information through the API. These are actually extra features, the webhook is listening to incoming connections on the port 5000. \nWe now have to bind the Dynatrace Cluster to the webhook.\n\nYou now go to your tenant in `Dynatrace \u003e Settings \u003e Integration \u003e Problem notifications` and select custom notification.\n\n![custom notification](doc/custom_integration_button.png)\n\nNow you have to fill in the following information:\n\n![webhook bind information](doc/custom_integration_config.png)\n\n**Name**\nThis is kind of obvious, put in the name you want for your custom webhook ;)\n\n**Webhook URL**\nThe webhook URL might be tricky to get if you are running the webhook in your laptop and you want for example that Dynatrace connects to it via the internet. You'll need to first figure out the dynamic IP assigned to your router by your ISP and might also need to configure your home router to open a port and forward the incoming traffic to the listening port in your local machine where you are running the webhook. This is a different topic but I'll let a [blogpost](https://www.howtogeek.com/66214/how-to-forward-ports-on-your-router/) that can help you understand and set up that environment. But hey! before you open a security leak in your home network, or are short in time, you might want to give it a try to spin up a VM in a cloud provider like [Azure ](https://azure.microsoft.com/en-us/free/)or [AWS](https://aws.amazon.com/free/). You can spin up a VM in the sizing you need it within minutes with a DNS name bound to it.\nIf you are running the webhook in a corporate network, then you just need to make sure the port and IP's from the Dynatrace Cluster and the Webhook are open within the internal firewall. \n\n**Additional HTTP Headers** The webhook supports basic authorization, in here you put the username and password that are defined in the `config.json` file, type it in and click add. \n\n**Custom Payload** In here you define the JSON format that is going to be sent to the custom webhook. Since this sample is for educational purpouses, we only need `State, ProblemID and PID` and the webhook will poll the problem details when receiving a message.\n\nHere is the format so you can copy\u0026paste it:\n\n\t{\n\t\"State\":\"{State}\",\n\t\"ProblemID\":\"{ProblemID}\",\n\t\"PID\":\"{PID}\"\n\t}\n\nAfter you have entered the parameters where the webhook is running, click on send notification to send a test message to the webhook. You should see an integration test successful message.  \n![webhook bind information](doc/custom_integration_ok.png)\n\nAlso in the console or log of the webhook you should be able to see that the test message arrived succesfully. The test message is also saved in the `problems_received` folder.\n \n    Notification received from 54.XXX.XXX.XXX\n    Test message successfully received. No integration will be called\n    54.XXX.XXX.XXX - - [29/Mar/2018 15:51:07] \"POST / HTTP/1.1\" 200 -\n\nAs an optional configuration you can assign an alerting profile to the webhook so you only receive notifications for specific severities, criterias, services, hosts, etc.\n\nOk, you are all set! Now your webhook should get in action after a problem its detected.\n\n## Understanding the project\nThis sections describes the features and integrations.\n\n### Features of the webhook in a Nutshell\n- Handle POST requests coming from Dynatrace (with basic authentication user \u0026 password)\n- Logging\n- Configuration via a config.json file\n- Save the incoming and outgoing (problem details) notifications as JSON files\n- Poll a specific problem by ID\n- convert JSON payload in an html table\n- Poll a range of problems in a specific timeframe (via command line or webserver)\n- Integration with legacy systems: call a legacy executable for each impacted entities a problem has with parameters\n- Integration with SMS: send an SMS via Twilio API\n- POST the results of the integration in the problem comments in Dynatrace\n- Exposing a web server with the runtime information of the webhook\n- Poll the problem API in a specific time range (either by command line or via webserver).\n- Show the sent and received problems as an HTML table\n\n### Project structure \u0026 description\n\n\t└─ webhook\n\t\t├─  doc\n\t\t│\t└── ...\t\t\tDocumentation folder with images.\n\t\t├─  log\t\t\t\tFolder for logging (specified in config.json)\n\t\t│\t└── webhook.log\t\tLogging file (specified in config.json)\n\t\t│\n\t\t├─  problems_received   \tFolder for saving the notifications as a JSON payload without preprocessing.\n\t\t│\t└── [0-9]-[STATE].json\n\t\t├─\tproblems_sent\t\tFolder for saving the notifications (problem_details) that were succesfully polled and submitted to the integrations. \n\t\t│      └── [0-9].json\n\t\t├─\ttemplates\t\t\t\n\t\t│\t\t└── index.html\tFlask rendering template for the Webhook webserver.\n\t\t├─\tconfig.json\t\tConfigurations file\n\t\t├─\tlegacy_script.bat\tLegacy sample executable for Windows.\n\t\t├─\tlegacy_script.sh\tLegacy sample executable for Linux.\n\t\t├─\tREADME.md\t\tThis ReadMe file\n\t\t├─\trequirements.txt\tpython project dependencies\n\t\t└─\twebhook.py\t\tThe custom Webhook application\n\n\n\n### Integrations\nThis project has two integrations, calling an executable with parameters where the webhook is running and send an SMS via the Twilio API. The project is created in a way so you can get a glimpse of the integration capabilites with dynatrace and you can build your own integration. \n\n#### Legacy Script / Incident Software\nIn the `config.json` file there is a section called **incident notification**. In here you can activate with a boolean flag the execution of the legacy_script.[bat/sh]. This script will be called with parameters after a notification arrives. The return code of the executable will then be posted in the comment section of the problem in Dynatrace.\n![Posting the results in the comments section](doc/comment_notification.png)\n\n\n#### Send an SMS via Twilio API\nIn the `config.json` file there is a section called **sms notification**. If you set up this integration to true, then it will send an SMS to the given phone in the configuration. You'll need a valid account in twilio for this integration to work. [Here ](https://www.twilio.com/try-twilio) you can set up a free trial Account. \n\n#### Create your own integration\nYou can use this project as a template. For start creating your own integration check the Python code `webhook.py` for a function called `call_integration`. This function is the binding of the Integrations with the received problem (with its problem details). In here you can expand the project and start coding your own integration. \n\n## License\nThis project is licensed under the Apache License - see the [LICENSE](LICENSE) file for details\n\n\n## Who do I talk to? ##\n\nIf this project gave you some new ideas or might help you or your customers, then that's awesome! If you think we can be of any help, don't hesitate to reach out!\n\n* You can always reach out to me [sergio.hinojosa@dynatrace.com](mailto:sergio.hinojosa@dynatrace.com) or my team in [dach.se@dynatrace.com](mailto:dach.se@dynatrace.com)","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdynatrace%2Fcustom-webhook-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdynatrace%2Fcustom-webhook-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdynatrace%2Fcustom-webhook-python/lists"}