Repository files navigation

Python 3

WebhookEventServer

GitHubGitHub

This is a 'simple' GitHub Webhook listener application.

The program accepts all incoming GitHub Webhooks events. It evaluates the incoming event and triggers the configured 'action' modules (multiple actions can be associated per Webhook event).

The application can match events to 'actions' based on their type and specific payload content (E.g: github user that is associated with the event)

Events that are not 'registered' in the Yaml config file (no matches found), are being ignored. (see the 'configuration' section for details)

diagram

Note: The sample setup in this repository listens for 'Delete Repository' events and creates an 'Issue' in another repository, called 'issue-headRepo'.

Setup Requirements

This application was developed using Python 2.7.10

Create a 'Personal Access Token'(PAT) in Github

Required to access the GitHub API.

Command line Example

curl https://api.github.com/authorizations \
--user "<user>" \
--data '{"scopes":["headRepo","admin:org","gist","notifications","user"],"note":"MyToken"}'

The JSON response contains a section called,

"token": "0f8...d84"

Make sure to store that token! It cannot be retrieved again. (you can always regenerate a token)

GitHub Website Example

For creating tokens see, GitHub - Creating a personal access token...

Make sure to store the token!

Create a 'Secret' String for use with GitHub Webhooks

For security reasons, we only accept incoming requests from our GitHub organization !

Sample Linux command for a secret string

> uuidgen
C8A1A357-5252-452D-B46D-BF9E325A99D6

You can provide any 'string' but we recommend using something similar to the 'uuidgen'.

Create a Webhook in your GitHub Organization

In your GitHub Organization create a Webhook for an event (for testing purposes select all events).

In the Webhook setup (organization/settings/hooks) provide the secret string from the previous step. Make sure the Webhook points to the correct location (url) for the Webhook listener (and that it's reachable)

See snap shot of Webhooks setup section and secrets

sample


Install - The Webhook Listener Server

To install the server, clone this repository and copy all files and subfolders from src/ to any location where you want to install the application.

Project folder structure:

.
├── docs
├── README.md
└── src
├── config.yml
├── modules
│ ├── create_issue.py
│ ├── notification.py
│ └── template.py
└── WebhookEventServer.py

NOTE: the 'modules' folder contains the code for Webhook event actions. To see a sample of how to create a Webhook event action, check 'template.py'.

Configure - The Webhook Listener Server

All configuration is done via the 'config.yml' file, found in the 'src/' folder. The application behavior is fully defined by the config.yml file.

The config.yml consists of two main parts,

  1. 'server' section, defining all data to run the server
  2. 'webhooks' section, defining all GitHub events and Webhooks for the application to respond

Sample YAML config

server:
port: 80# the port that the application listen for Webhooksbind: 0.0.0.0 # Application bind IPlog: 'WebhookEventServer.log'# log file/locationsecret: top_secret # 'random' string (for incoming Webhook requests)# GitHub API request infotoken_file: 'token.pat'# security token storage (replaces 'token')token: f7bb2272b...230c1ed9889 # security token (for Github API calls)github_api: 'https://api.github.com'# GitHub Api endpoint (might be different for on premise)owner: jdoeorganization: jchallenge1# list the Webhook events that we want to respond towebhooks:
# events list from - https://developer.github.com/webhooks/
- event: issuesdescription: 'GitHub Issue created...'# the payload_attr acts as a filter optionpayload_attrs:
- action: openedactions:
- notification
- event: repositorydescription: 'create an issue when a repository gets deleted'payload_attrs:
- action: deletedactions:
- create_issue
- event: issuesdescription: 'GitHub Issue closed...'payload_attrs:
- action: closedactions:

Detailed information on the 'webhooks:' section

ParameterDescription
- event:any event listed in https://developer.github.com/webhooks/
payload_attrs:Any top level Yaml tag, with it's value can be provided here.
- action: openedThe Application will use it as a 'filter' to identify a Webhook event more specifically. For possible attributes check the 'Events API payload' section from https://developer.github.com/webhooks/
actions:any number of actions can be provided here as long as it exist in the 'modules' folder
- create_issuepython file in the 'modules' folder
- notificationpython file in the 'modules' folder

Run - The Webhook Listener Server

Application usage help

# python WebhookEventServer.py -h
usage: WebhookEventServer.py [-h] [--loglevel LOG_LEVEL]
optional arguments:
-h, --help show this help message and exit
--loglevel LOG_LEVEL, -l LOG_LEVEL
LOG_LEVEL: <debug|info|warning|error|critical>
(default: INFO)

Run the application

Sample:

# python WebhookEventServer.py
Start listening on 0.0.0.0:80

The server is now listening on port 80 for incoming GitHub Webhook events !
NOTE: Ports below 1024 are 'Privileged Ports' and require 'root' privileges


Some Additional Information

How to Create an 'Issue' via the GitHub API

Command line sample

curl -d "@./data.json" -u jefeish:cc5...cf75 -X POST https
://api.github.com/repos/jchallenge1/issue-headRepo/issues
  • -d payload
  • -u user:token

Sample payload 'data.json'

{
"title": "Found a bug",
"body": "@user I'm having a problem with this.",
"assignees": [
"myuser"
],
"labels": [
"bug"
]
}

Requirements for Webhook action implementations

Sample 'webhook' code template

importrequestsgloballog# Required class nameclasscommand():
# initialize the classdef__init__(self, logger, server_info, payload):
globallog# webhook action requires thisself.server_info=server_infoself.payload=payloadlog=logger# Common entry pointdefexecute(self):
globallog# Implement action

About

No description or website provided.

Topics

Resources

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Python 3

WebhookEventServer

GitHubGitHub

This is a 'simple' GitHub Webhook listener application.

The program accepts all incoming GitHub Webhooks events. It evaluates the incoming event and triggers the configured 'action' modules (multiple actions can be associated per Webhook event).

The application can match events to 'actions' based on their type and specific payload content (E.g: github user that is associated with the event)

Events that are not 'registered' in the Yaml config file (no matches found), are being ignored. (see the 'configuration' section for details)

diagram

Note: The sample setup in this repository listens for 'Delete Repository' events and creates an 'Issue' in another repository, called 'issue-headRepo'.

Setup Requirements

This application was developed using Python 2.7.10

Create a 'Personal Access Token'(PAT) in Github

Required to access the GitHub API.

Command line Example

curl https://api.github.com/authorizations \
--user "<user>" \
--data '{"scopes":["headRepo","admin:org","gist","notifications","user"],"note":"MyToken"}'

The JSON response contains a section called,

"token": "0f8...d84"

Make sure to store that token! It cannot be retrieved again. (you can always regenerate a token)

GitHub Website Example

For creating tokens see, GitHub - Creating a personal access token...

Make sure to store the token!

Create a 'Secret' String for use with GitHub Webhooks

For security reasons, we only accept incoming requests from our GitHub organization !

Sample Linux command for a secret string

> uuidgen
C8A1A357-5252-452D-B46D-BF9E325A99D6

You can provide any 'string' but we recommend using something similar to the 'uuidgen'.

Create a Webhook in your GitHub Organization

In your GitHub Organization create a Webhook for an event (for testing purposes select all events).

In the Webhook setup (organization/settings/hooks) provide the secret string from the previous step. Make sure the Webhook points to the correct location (url) for the Webhook listener (and that it's reachable)

See snap shot of Webhooks setup section and secrets

sample


Install - The Webhook Listener Server

To install the server, clone this repository and copy all files and subfolders from src/ to any location where you want to install the application.

Project folder structure:

.
├── docs
├── README.md
└── src
├── config.yml
├── modules
│ ├── create_issue.py
│ ├── notification.py
│ └── template.py
└── WebhookEventServer.py

NOTE: the 'modules' folder contains the code for Webhook event actions. To see a sample of how to create a Webhook event action, check 'template.py'.

Configure - The Webhook Listener Server

All configuration is done via the 'config.yml' file, found in the 'src/' folder. The application behavior is fully defined by the config.yml file.

The config.yml consists of two main parts,

  1. 'server' section, defining all data to run the server
  2. 'webhooks' section, defining all GitHub events and Webhooks for the application to respond

Sample YAML config

server:
port: 80# the port that the application listen for Webhooksbind: 0.0.0.0 # Application bind IPlog: 'WebhookEventServer.log'# log file/locationsecret: top_secret # 'random' string (for incoming Webhook requests)# GitHub API request infotoken_file: 'token.pat'# security token storage (replaces 'token')token: f7bb2272b...230c1ed9889 # security token (for Github API calls)github_api: 'https://api.github.com'# GitHub Api endpoint (might be different for on premise)owner: jdoeorganization: jchallenge1# list the Webhook events that we want to respond towebhooks:
# events list from - https://developer.github.com/webhooks/
- event: issuesdescription: 'GitHub Issue created...'# the payload_attr acts as a filter optionpayload_attrs:
- action: openedactions:
- notification
- event: repositorydescription: 'create an issue when a repository gets deleted'payload_attrs:
- action: deletedactions:
- create_issue
- event: issuesdescription: 'GitHub Issue closed...'payload_attrs:
- action: closedactions:

Detailed information on the 'webhooks:' section

ParameterDescription
- event:any event listed in https://developer.github.com/webhooks/
payload_attrs:Any top level Yaml tag, with it's value can be provided here.
- action: openedThe Application will use it as a 'filter' to identify a Webhook event more specifically. For possible attributes check the 'Events API payload' section from https://developer.github.com/webhooks/
actions:any number of actions can be provided here as long as it exist in the 'modules' folder
- create_issuepython file in the 'modules' folder
- notificationpython file in the 'modules' folder

Run - The Webhook Listener Server

Application usage help

# python WebhookEventServer.py -h
usage: WebhookEventServer.py [-h] [--loglevel LOG_LEVEL]
optional arguments:
-h, --help show this help message and exit
--loglevel LOG_LEVEL, -l LOG_LEVEL
LOG_LEVEL: <debug|info|warning|error|critical>
(default: INFO)

Run the application

Sample:

# python WebhookEventServer.py
Start listening on 0.0.0.0:80

The server is now listening on port 80 for incoming GitHub Webhook events !
NOTE: Ports below 1024 are 'Privileged Ports' and require 'root' privileges


Some Additional Information

How to Create an 'Issue' via the GitHub API

Command line sample

curl -d "@./data.json" -u jefeish:cc5...cf75 -X POST https
://api.github.com/repos/jchallenge1/issue-headRepo/issues
  • -d payload
  • -u user:token

Sample payload 'data.json'

{
"title": "Found a bug",
"body": "@user I'm having a problem with this.",
"assignees": [
"myuser"
],
"labels": [
"bug"
]
}

Requirements for Webhook action implementations

Sample 'webhook' code template

importrequestsgloballog# Required class nameclasscommand():
# initialize the classdef__init__(self, logger, server_info, payload):
globallog# webhook action requires thisself.server_info=server_infoself.payload=payloadlog=logger# Common entry pointdefexecute(self):
globallog# Implement action

About

No description or website provided.

Topics

Resources

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Python 3

WebhookEventServer

GitHubGitHub

This is a 'simple' GitHub Webhook listener application.

The program accepts all incoming GitHub Webhooks events. It evaluates the incoming event and triggers the configured 'action' modules (multiple actions can be associated per Webhook event).

The application can match events to 'actions' based on their type and specific payload content (E.g: github user that is associated with the event)

Events that are not 'registered' in the Yaml config file (no matches found), are being ignored. (see the 'configuration' section for details)

diagram

Note: The sample setup in this repository listens for 'Delete Repository' events and creates an 'Issue' in another repository, called 'issue-headRepo'.

Setup Requirements

This application was developed using Python 2.7.10

Create a 'Personal Access Token'(PAT) in Github

Required to access the GitHub API.

Command line Example

curl https://api.github.com/authorizations \
--user "<user>" \
--data '{"scopes":["headRepo","admin:org","gist","notifications","user"],"note":"MyToken"}'

The JSON response contains a section called,

"token": "0f8...d84"

Make sure to store that token! It cannot be retrieved again. (you can always regenerate a token)

GitHub Website Example

For creating tokens see, GitHub - Creating a personal access token...

Make sure to store the token!

Create a 'Secret' String for use with GitHub Webhooks

For security reasons, we only accept incoming requests from our GitHub organization !

Sample Linux command for a secret string

> uuidgen
C8A1A357-5252-452D-B46D-BF9E325A99D6

You can provide any 'string' but we recommend using something similar to the 'uuidgen'.

Create a Webhook in your GitHub Organization

In your GitHub Organization create a Webhook for an event (for testing purposes select all events).

In the Webhook setup (organization/settings/hooks) provide the secret string from the previous step. Make sure the Webhook points to the correct location (url) for the Webhook listener (and that it's reachable)

See snap shot of Webhooks setup section and secrets

sample


Install - The Webhook Listener Server

To install the server, clone this repository and copy all files and subfolders from src/ to any location where you want to install the application.

Project folder structure:

.
├── docs
├── README.md
└── src
├── config.yml
├── modules
│ ├── create_issue.py
│ ├── notification.py
│ └── template.py
└── WebhookEventServer.py

NOTE: the 'modules' folder contains the code for Webhook event actions. To see a sample of how to create a Webhook event action, check 'template.py'.

Configure - The Webhook Listener Server

All configuration is done via the 'config.yml' file, found in the 'src/' folder. The application behavior is fully defined by the config.yml file.

The config.yml consists of two main parts,

  1. 'server' section, defining all data to run the server
  2. 'webhooks' section, defining all GitHub events and Webhooks for the application to respond

Sample YAML config

server:
port: 80# the port that the application listen for Webhooksbind: 0.0.0.0 # Application bind IPlog: 'WebhookEventServer.log'# log file/locationsecret: top_secret # 'random' string (for incoming Webhook requests)# GitHub API request infotoken_file: 'token.pat'# security token storage (replaces 'token')token: f7bb2272b...230c1ed9889 # security token (for Github API calls)github_api: 'https://api.github.com'# GitHub Api endpoint (might be different for on premise)owner: jdoeorganization: jchallenge1# list the Webhook events that we want to respond towebhooks:
# events list from - https://developer.github.com/webhooks/
- event: issuesdescription: 'GitHub Issue created...'# the payload_attr acts as a filter optionpayload_attrs:
- action: openedactions:
- notification
- event: repositorydescription: 'create an issue when a repository gets deleted'payload_attrs:
- action: deletedactions:
- create_issue
- event: issuesdescription: 'GitHub Issue closed...'payload_attrs:
- action: closedactions:

Detailed information on the 'webhooks:' section

ParameterDescription
- event:any event listed in https://developer.github.com/webhooks/
payload_attrs:Any top level Yaml tag, with it's value can be provided here.
- action: openedThe Application will use it as a 'filter' to identify a Webhook event more specifically. For possible attributes check the 'Events API payload' section from https://developer.github.com/webhooks/
actions:any number of actions can be provided here as long as it exist in the 'modules' folder
- create_issuepython file in the 'modules' folder
- notificationpython file in the 'modules' folder

Run - The Webhook Listener Server

Application usage help

# python WebhookEventServer.py -h
usage: WebhookEventServer.py [-h] [--loglevel LOG_LEVEL]
optional arguments:
-h, --help show this help message and exit
--loglevel LOG_LEVEL, -l LOG_LEVEL
LOG_LEVEL: <debug|info|warning|error|critical>
(default: INFO)

Run the application

Sample:

# python WebhookEventServer.py
Start listening on 0.0.0.0:80

The server is now listening on port 80 for incoming GitHub Webhook events !
NOTE: Ports below 1024 are 'Privileged Ports' and require 'root' privileges


Some Additional Information

How to Create an 'Issue' via the GitHub API

Command line sample

curl -d "@./data.json" -u jefeish:cc5...cf75 -X POST https
://api.github.com/repos/jchallenge1/issue-headRepo/issues
  • -d payload
  • -u user:token

Sample payload 'data.json'

{
"title": "Found a bug",
"body": "@user I'm having a problem with this.",
"assignees": [
"myuser"
],
"labels": [
"bug"
]
}

Requirements for Webhook action implementations

Sample 'webhook' code template

importrequestsgloballog# Required class nameclasscommand():
# initialize the classdef__init__(self, logger, server_info, payload):
globallog# webhook action requires thisself.server_info=server_infoself.payload=payloadlog=logger# Common entry pointdefexecute(self):
globallog# Implement action

About

No description or website provided.

Topics

Resources

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Python 3

WebhookEventServer

GitHubGitHub

This is a 'simple' GitHub Webhook listener application.

The program accepts all incoming GitHub Webhooks events. It evaluates the incoming event and triggers the configured 'action' modules (multiple actions can be associated per Webhook event).

The application can match events to 'actions' based on their type and specific payload content (E.g: github user that is associated with the event)

Events that are not 'registered' in the Yaml config file (no matches found), are being ignored. (see the 'configuration' section for details)

diagram

Note: The sample setup in this repository listens for 'Delete Repository' events and creates an 'Issue' in another repository, called 'issue-headRepo'.

Setup Requirements

This application was developed using Python 2.7.10

Create a 'Personal Access Token'(PAT) in Github

Required to access the GitHub API.

Command line Example

curl https://api.github.com/authorizations \
--user "<user>" \
--data '{"scopes":["headRepo","admin:org","gist","notifications","user"],"note":"MyToken"}'

The JSON response contains a section called,

"token": "0f8...d84"

Make sure to store that token! It cannot be retrieved again. (you can always regenerate a token)

GitHub Website Example

For creating tokens see, GitHub - Creating a personal access token...

Make sure to store the token!

Create a 'Secret' String for use with GitHub Webhooks

For security reasons, we only accept incoming requests from our GitHub organization !

Sample Linux command for a secret string

> uuidgen
C8A1A357-5252-452D-B46D-BF9E325A99D6

You can provide any 'string' but we recommend using something similar to the 'uuidgen'.

Create a Webhook in your GitHub Organization

In your GitHub Organization create a Webhook for an event (for testing purposes select all events).

In the Webhook setup (organization/settings/hooks) provide the secret string from the previous step. Make sure the Webhook points to the correct location (url) for the Webhook listener (and that it's reachable)

See snap shot of Webhooks setup section and secrets

sample


Install - The Webhook Listener Server

To install the server, clone this repository and copy all files and subfolders from src/ to any location where you want to install the application.

Project folder structure:

.
├── docs
├── README.md
└── src
├── config.yml
├── modules
│ ├── create_issue.py
│ ├── notification.py
│ └── template.py
└── WebhookEventServer.py

NOTE: the 'modules' folder contains the code for Webhook event actions. To see a sample of how to create a Webhook event action, check 'template.py'.

Configure - The Webhook Listener Server

All configuration is done via the 'config.yml' file, found in the 'src/' folder. The application behavior is fully defined by the config.yml file.

The config.yml consists of two main parts,

  1. 'server' section, defining all data to run the server
  2. 'webhooks' section, defining all GitHub events and Webhooks for the application to respond

Sample YAML config

server:
port: 80# the port that the application listen for Webhooksbind: 0.0.0.0 # Application bind IPlog: 'WebhookEventServer.log'# log file/locationsecret: top_secret # 'random' string (for incoming Webhook requests)# GitHub API request infotoken_file: 'token.pat'# security token storage (replaces 'token')token: f7bb2272b...230c1ed9889 # security token (for Github API calls)github_api: 'https://api.github.com'# GitHub Api endpoint (might be different for on premise)owner: jdoeorganization: jchallenge1# list the Webhook events that we want to respond towebhooks:
# events list from - https://developer.github.com/webhooks/
- event: issuesdescription: 'GitHub Issue created...'# the payload_attr acts as a filter optionpayload_attrs:
- action: openedactions:
- notification
- event: repositorydescription: 'create an issue when a repository gets deleted'payload_attrs:
- action: deletedactions:
- create_issue
- event: issuesdescription: 'GitHub Issue closed...'payload_attrs:
- action: closedactions:

Detailed information on the 'webhooks:' section

ParameterDescription
- event:any event listed in https://developer.github.com/webhooks/
payload_attrs:Any top level Yaml tag, with it's value can be provided here.
- action: openedThe Application will use it as a 'filter' to identify a Webhook event more specifically. For possible attributes check the 'Events API payload' section from https://developer.github.com/webhooks/
actions:any number of actions can be provided here as long as it exist in the 'modules' folder
- create_issuepython file in the 'modules' folder
- notificationpython file in the 'modules' folder

Run - The Webhook Listener Server

Application usage help

# python WebhookEventServer.py -h
usage: WebhookEventServer.py [-h] [--loglevel LOG_LEVEL]
optional arguments:
-h, --help show this help message and exit
--loglevel LOG_LEVEL, -l LOG_LEVEL
LOG_LEVEL: <debug|info|warning|error|critical>
(default: INFO)

Run the application

Sample:

# python WebhookEventServer.py
Start listening on 0.0.0.0:80

The server is now listening on port 80 for incoming GitHub Webhook events !
NOTE: Ports below 1024 are 'Privileged Ports' and require 'root' privileges


Some Additional Information

How to Create an 'Issue' via the GitHub API

Command line sample

curl -d "@./data.json" -u jefeish:cc5...cf75 -X POST https
://api.github.com/repos/jchallenge1/issue-headRepo/issues
  • -d payload
  • -u user:token

Sample payload 'data.json'

{
"title": "Found a bug",
"body": "@user I'm having a problem with this.",
"assignees": [
"myuser"
],
"labels": [
"bug"
]
}

Requirements for Webhook action implementations

Sample 'webhook' code template

importrequestsgloballog# Required class nameclasscommand():
# initialize the classdef__init__(self, logger, server_info, payload):
globallog# webhook action requires thisself.server_info=server_infoself.payload=payloadlog=logger# Common entry pointdefexecute(self):
globallog# Implement action

About

No description or website provided.

Topics

Resources

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Python 3

WebhookEventServer

GitHubGitHub

This is a 'simple' GitHub Webhook listener application.

The program accepts all incoming GitHub Webhooks events. It evaluates the incoming event and triggers the configured 'action' modules (multiple actions can be associated per Webhook event).

The application can match events to 'actions' based on their type and specific payload content (E.g: github user that is associated with the event)

Events that are not 'registered' in the Yaml config file (no matches found), are being ignored. (see the 'configuration' section for details)

diagram

Note: The sample setup in this repository listens for 'Delete Repository' events and creates an 'Issue' in another repository, called 'issue-headRepo'.

Setup Requirements

This application was developed using Python 2.7.10

Create a 'Personal Access Token'(PAT) in Github

Required to access the GitHub API.

Command line Example

curl https://api.github.com/authorizations \
--user "<user>" \
--data '{"scopes":["headRepo","admin:org","gist","notifications","user"],"note":"MyToken"}'

The JSON response contains a section called,

"token": "0f8...d84"

Make sure to store that token! It cannot be retrieved again. (you can always regenerate a token)

GitHub Website Example

For creating tokens see, GitHub - Creating a personal access token...

Make sure to store the token!

Create a 'Secret' String for use with GitHub Webhooks

For security reasons, we only accept incoming requests from our GitHub organization !

Sample Linux command for a secret string

> uuidgen
C8A1A357-5252-452D-B46D-BF9E325A99D6

You can provide any 'string' but we recommend using something similar to the 'uuidgen'.

Create a Webhook in your GitHub Organization

In your GitHub Organization create a Webhook for an event (for testing purposes select all events).

In the Webhook setup (organization/settings/hooks) provide the secret string from the previous step. Make sure the Webhook points to the correct location (url) for the Webhook listener (and that it's reachable)

See snap shot of Webhooks setup section and secrets

sample


Install - The Webhook Listener Server

To install the server, clone this repository and copy all files and subfolders from src/ to any location where you want to install the application.

Project folder structure:

.
├── docs
├── README.md
└── src
├── config.yml
├── modules
│ ├── create_issue.py
│ ├── notification.py
│ └── template.py
└── WebhookEventServer.py

NOTE: the 'modules' folder contains the code for Webhook event actions. To see a sample of how to create a Webhook event action, check 'template.py'.

Configure - The Webhook Listener Server

All configuration is done via the 'config.yml' file, found in the 'src/' folder. The application behavior is fully defined by the config.yml file.

The config.yml consists of two main parts,

  1. 'server' section, defining all data to run the server
  2. 'webhooks' section, defining all GitHub events and Webhooks for the application to respond

Sample YAML config

server:
port: 80# the port that the application listen for Webhooksbind: 0.0.0.0 # Application bind IPlog: 'WebhookEventServer.log'# log file/locationsecret: top_secret # 'random' string (for incoming Webhook requests)# GitHub API request infotoken_file: 'token.pat'# security token storage (replaces 'token')token: f7bb2272b...230c1ed9889 # security token (for Github API calls)github_api: 'https://api.github.com'# GitHub Api endpoint (might be different for on premise)owner: jdoeorganization: jchallenge1# list the Webhook events that we want to respond towebhooks:
# events list from - https://developer.github.com/webhooks/
- event: issuesdescription: 'GitHub Issue created...'# the payload_attr acts as a filter optionpayload_attrs:
- action: openedactions:
- notification
- event: repositorydescription: 'create an issue when a repository gets deleted'payload_attrs:
- action: deletedactions:
- create_issue
- event: issuesdescription: 'GitHub Issue closed...'payload_attrs:
- action: closedactions:

Detailed information on the 'webhooks:' section

ParameterDescription
- event:any event listed in https://developer.github.com/webhooks/
payload_attrs:Any top level Yaml tag, with it's value can be provided here.
- action: openedThe Application will use it as a 'filter' to identify a Webhook event more specifically. For possible attributes check the 'Events API payload' section from https://developer.github.com/webhooks/
actions:any number of actions can be provided here as long as it exist in the 'modules' folder
- create_issuepython file in the 'modules' folder
- notificationpython file in the 'modules' folder

Run - The Webhook Listener Server

Application usage help

# python WebhookEventServer.py -h
usage: WebhookEventServer.py [-h] [--loglevel LOG_LEVEL]
optional arguments:
-h, --help show this help message and exit
--loglevel LOG_LEVEL, -l LOG_LEVEL
LOG_LEVEL: <debug|info|warning|error|critical>
(default: INFO)

Run the application

Sample:

# python WebhookEventServer.py
Start listening on 0.0.0.0:80

The server is now listening on port 80 for incoming GitHub Webhook events !
NOTE: Ports below 1024 are 'Privileged Ports' and require 'root' privileges


Some Additional Information

How to Create an 'Issue' via the GitHub API

Command line sample

curl -d "@./data.json" -u jefeish:cc5...cf75 -X POST https
://api.github.com/repos/jchallenge1/issue-headRepo/issues
  • -d payload
  • -u user:token

Sample payload 'data.json'

{
"title": "Found a bug",
"body": "@user I'm having a problem with this.",
"assignees": [
"myuser"
],
"labels": [
"bug"
]
}

Requirements for Webhook action implementations

Sample 'webhook' code template

importrequestsgloballog# Required class nameclasscommand():
# initialize the classdef__init__(self, logger, server_info, payload):
globallog# webhook action requires thisself.server_info=server_infoself.payload=payloadlog=logger# Common entry pointdefexecute(self):
globallog# Implement action

About

No description or website provided.

Topics

Resources

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Python 3

WebhookEventServer

GitHubGitHub

This is a 'simple' GitHub Webhook listener application.

The program accepts all incoming GitHub Webhooks events. It evaluates the incoming event and triggers the configured 'action' modules (multiple actions can be associated per Webhook event).

The application can match events to 'actions' based on their type and specific payload content (E.g: github user that is associated with the event)

Events that are not 'registered' in the Yaml config file (no matches found), are being ignored. (see the 'configuration' section for details)

diagram

Note: The sample setup in this repository listens for 'Delete Repository' events and creates an 'Issue' in another repository, called 'issue-headRepo'.

Setup Requirements

This application was developed using Python 2.7.10

Create a 'Personal Access Token'(PAT) in Github

Required to access the GitHub API.

Command line Example

curl https://api.github.com/authorizations \
--user "<user>" \
--data '{"scopes":["headRepo","admin:org","gist","notifications","user"],"note":"MyToken"}'

The JSON response contains a section called,

"token": "0f8...d84"

Make sure to store that token! It cannot be retrieved again. (you can always regenerate a token)

GitHub Website Example

For creating tokens see, GitHub - Creating a personal access token...

Make sure to store the token!

Create a 'Secret' String for use with GitHub Webhooks

For security reasons, we only accept incoming requests from our GitHub organization !

Sample Linux command for a secret string

> uuidgen
C8A1A357-5252-452D-B46D-BF9E325A99D6

You can provide any 'string' but we recommend using something similar to the 'uuidgen'.

Create a Webhook in your GitHub Organization

In your GitHub Organization create a Webhook for an event (for testing purposes select all events).

In the Webhook setup (organization/settings/hooks) provide the secret string from the previous step. Make sure the Webhook points to the correct location (url) for the Webhook listener (and that it's reachable)

See snap shot of Webhooks setup section and secrets

sample


Install - The Webhook Listener Server

To install the server, clone this repository and copy all files and subfolders from src/ to any location where you want to install the application.

Project folder structure:

.
├── docs
├── README.md
└── src
├── config.yml
├── modules
│ ├── create_issue.py
│ ├── notification.py
│ └── template.py
└── WebhookEventServer.py

NOTE: the 'modules' folder contains the code for Webhook event actions. To see a sample of how to create a Webhook event action, check 'template.py'.

Configure - The Webhook Listener Server

All configuration is done via the 'config.yml' file, found in the 'src/' folder. The application behavior is fully defined by the config.yml file.

The config.yml consists of two main parts,

  1. 'server' section, defining all data to run the server
  2. 'webhooks' section, defining all GitHub events and Webhooks for the application to respond

Sample YAML config

server:
port: 80# the port that the application listen for Webhooksbind: 0.0.0.0 # Application bind IPlog: 'WebhookEventServer.log'# log file/locationsecret: top_secret # 'random' string (for incoming Webhook requests)# GitHub API request infotoken_file: 'token.pat'# security token storage (replaces 'token')token: f7bb2272b...230c1ed9889 # security token (for Github API calls)github_api: 'https://api.github.com'# GitHub Api endpoint (might be different for on premise)owner: jdoeorganization: jchallenge1# list the Webhook events that we want to respond towebhooks:
# events list from - https://developer.github.com/webhooks/
- event: issuesdescription: 'GitHub Issue created...'# the payload_attr acts as a filter optionpayload_attrs:
- action: openedactions:
- notification
- event: repositorydescription: 'create an issue when a repository gets deleted'payload_attrs:
- action: deletedactions:
- create_issue
- event: issuesdescription: 'GitHub Issue closed...'payload_attrs:
- action: closedactions:

Detailed information on the 'webhooks:' section

ParameterDescription
- event:any event listed in https://developer.github.com/webhooks/
payload_attrs:Any top level Yaml tag, with it's value can be provided here.
- action: openedThe Application will use it as a 'filter' to identify a Webhook event more specifically. For possible attributes check the 'Events API payload' section from https://developer.github.com/webhooks/
actions:any number of actions can be provided here as long as it exist in the 'modules' folder
- create_issuepython file in the 'modules' folder
- notificationpython file in the 'modules' folder

Run - The Webhook Listener Server

Application usage help

# python WebhookEventServer.py -h
usage: WebhookEventServer.py [-h] [--loglevel LOG_LEVEL]
optional arguments:
-h, --help show this help message and exit
--loglevel LOG_LEVEL, -l LOG_LEVEL
LOG_LEVEL: <debug|info|warning|error|critical>
(default: INFO)

Run the application

Sample:

# python WebhookEventServer.py
Start listening on 0.0.0.0:80

The server is now listening on port 80 for incoming GitHub Webhook events !
NOTE: Ports below 1024 are 'Privileged Ports' and require 'root' privileges


Some Additional Information

How to Create an 'Issue' via the GitHub API

Command line sample

curl -d "@./data.json" -u jefeish:cc5...cf75 -X POST https
://api.github.com/repos/jchallenge1/issue-headRepo/issues
  • -d payload
  • -u user:token

Sample payload 'data.json'

{
"title": "Found a bug",
"body": "@user I'm having a problem with this.",
"assignees": [
"myuser"
],
"labels": [
"bug"
]
}

Requirements for Webhook action implementations

Sample 'webhook' code template

importrequestsgloballog# Required class nameclasscommand():
# initialize the classdef__init__(self, logger, server_info, payload):
globallog# webhook action requires thisself.server_info=server_infoself.payload=payloadlog=logger# Common entry pointdefexecute(self):
globallog# Implement action

About

No description or website provided.

Topics

Resources

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Python 3

WebhookEventServer

GitHubGitHub

This is a 'simple' GitHub Webhook listener application.

The program accepts all incoming GitHub Webhooks events. It evaluates the incoming event and triggers the configured 'action' modules (multiple actions can be associated per Webhook event).

The application can match events to 'actions' based on their type and specific payload content (E.g: github user that is associated with the event)

Events that are not 'registered' in the Yaml config file (no matches found), are being ignored. (see the 'configuration' section for details)

diagram

Note: The sample setup in this repository listens for 'Delete Repository' events and creates an 'Issue' in another repository, called 'issue-headRepo'.

Setup Requirements

This application was developed using Python 2.7.10

Create a 'Personal Access Token'(PAT) in Github

Required to access the GitHub API.

Command line Example

curl https://api.github.com/authorizations \
--user "<user>" \
--data '{"scopes":["headRepo","admin:org","gist","notifications","user"],"note":"MyToken"}'

The JSON response contains a section called,

"token": "0f8...d84"

Make sure to store that token! It cannot be retrieved again. (you can always regenerate a token)

GitHub Website Example

For creating tokens see, GitHub - Creating a personal access token...

Make sure to store the token!

Create a 'Secret' String for use with GitHub Webhooks

For security reasons, we only accept incoming requests from our GitHub organization !

Sample Linux command for a secret string

> uuidgen
C8A1A357-5252-452D-B46D-BF9E325A99D6

You can provide any 'string' but we recommend using something similar to the 'uuidgen'.

Create a Webhook in your GitHub Organization

In your GitHub Organization create a Webhook for an event (for testing purposes select all events).

In the Webhook setup (organization/settings/hooks) provide the secret string from the previous step. Make sure the Webhook points to the correct location (url) for the Webhook listener (and that it's reachable)

See snap shot of Webhooks setup section and secrets

sample


Install - The Webhook Listener Server

To install the server, clone this repository and copy all files and subfolders from src/ to any location where you want to install the application.

Project folder structure:

.
├── docs
├── README.md
└── src
├── config.yml
├── modules
│ ├── create_issue.py
│ ├── notification.py
│ └── template.py
└── WebhookEventServer.py

NOTE: the 'modules' folder contains the code for Webhook event actions. To see a sample of how to create a Webhook event action, check 'template.py'.

Configure - The Webhook Listener Server

All configuration is done via the 'config.yml' file, found in the 'src/' folder. The application behavior is fully defined by the config.yml file.

The config.yml consists of two main parts,

  1. 'server' section, defining all data to run the server
  2. 'webhooks' section, defining all GitHub events and Webhooks for the application to respond

Sample YAML config

server:
port: 80# the port that the application listen for Webhooksbind: 0.0.0.0 # Application bind IPlog: 'WebhookEventServer.log'# log file/locationsecret: top_secret # 'random' string (for incoming Webhook requests)# GitHub API request infotoken_file: 'token.pat'# security token storage (replaces 'token')token: f7bb2272b...230c1ed9889 # security token (for Github API calls)github_api: 'https://api.github.com'# GitHub Api endpoint (might be different for on premise)owner: jdoeorganization: jchallenge1# list the Webhook events that we want to respond towebhooks:
# events list from - https://developer.github.com/webhooks/
- event: issuesdescription: 'GitHub Issue created...'# the payload_attr acts as a filter optionpayload_attrs:
- action: openedactions:
- notification
- event: repositorydescription: 'create an issue when a repository gets deleted'payload_attrs:
- action: deletedactions:
- create_issue
- event: issuesdescription: 'GitHub Issue closed...'payload_attrs:
- action: closedactions:

Detailed information on the 'webhooks:' section

ParameterDescription
- event:any event listed in https://developer.github.com/webhooks/
payload_attrs:Any top level Yaml tag, with it's value can be provided here.
- action: openedThe Application will use it as a 'filter' to identify a Webhook event more specifically. For possible attributes check the 'Events API payload' section from https://developer.github.com/webhooks/
actions:any number of actions can be provided here as long as it exist in the 'modules' folder
- create_issuepython file in the 'modules' folder
- notificationpython file in the 'modules' folder

Run - The Webhook Listener Server

Application usage help

# python WebhookEventServer.py -h
usage: WebhookEventServer.py [-h] [--loglevel LOG_LEVEL]
optional arguments:
-h, --help show this help message and exit
--loglevel LOG_LEVEL, -l LOG_LEVEL
LOG_LEVEL: <debug|info|warning|error|critical>
(default: INFO)

Run the application

Sample:

# python WebhookEventServer.py
Start listening on 0.0.0.0:80

The server is now listening on port 80 for incoming GitHub Webhook events !
NOTE: Ports below 1024 are 'Privileged Ports' and require 'root' privileges


Some Additional Information

How to Create an 'Issue' via the GitHub API

Command line sample

curl -d "@./data.json" -u jefeish:cc5...cf75 -X POST https
://api.github.com/repos/jchallenge1/issue-headRepo/issues
  • -d payload
  • -u user:token

Sample payload 'data.json'

{
"title": "Found a bug",
"body": "@user I'm having a problem with this.",
"assignees": [
"myuser"
],
"labels": [
"bug"
]
}

Requirements for Webhook action implementations

Sample 'webhook' code template

importrequestsgloballog# Required class nameclasscommand():
# initialize the classdef__init__(self, logger, server_info, payload):
globallog# webhook action requires thisself.server_info=server_infoself.payload=payloadlog=logger# Common entry pointdefexecute(self):
globallog# Implement action

About

No description or website provided.

Topics

Resources

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Python 3

WebhookEventServer

GitHubGitHub

This is a 'simple' GitHub Webhook listener application.

The program accepts all incoming GitHub Webhooks events. It evaluates the incoming event and triggers the configured 'action' modules (multiple actions can be associated per Webhook event).

The application can match events to 'actions' based on their type and specific payload content (E.g: github user that is associated with the event)

Events that are not 'registered' in the Yaml config file (no matches found), are being ignored. (see the 'configuration' section for details)

diagram

Note: The sample setup in this repository listens for 'Delete Repository' events and creates an 'Issue' in another repository, called 'issue-headRepo'.

Setup Requirements

This application was developed using Python 2.7.10

Create a 'Personal Access Token'(PAT) in Github

Required to access the GitHub API.

Command line Example

curl https://api.github.com/authorizations \
--user "<user>" \
--data '{"scopes":["headRepo","admin:org","gist","notifications","user"],"note":"MyToken"}'

The JSON response contains a section called,

"token": "0f8...d84"

Make sure to store that token! It cannot be retrieved again. (you can always regenerate a token)

GitHub Website Example

For creating tokens see, GitHub - Creating a personal access token...

Make sure to store the token!

Create a 'Secret' String for use with GitHub Webhooks

For security reasons, we only accept incoming requests from our GitHub organization !

Sample Linux command for a secret string

> uuidgen
C8A1A357-5252-452D-B46D-BF9E325A99D6

You can provide any 'string' but we recommend using something similar to the 'uuidgen'.

Create a Webhook in your GitHub Organization

In your GitHub Organization create a Webhook for an event (for testing purposes select all events).

In the Webhook setup (organization/settings/hooks) provide the secret string from the previous step. Make sure the Webhook points to the correct location (url) for the Webhook listener (and that it's reachable)

See snap shot of Webhooks setup section and secrets

sample


Install - The Webhook Listener Server

To install the server, clone this repository and copy all files and subfolders from src/ to any location where you want to install the application.

Project folder structure:

.
├── docs
├── README.md
└── src
├── config.yml
├── modules
│ ├── create_issue.py
│ ├── notification.py
│ └── template.py
└── WebhookEventServer.py

NOTE: the 'modules' folder contains the code for Webhook event actions. To see a sample of how to create a Webhook event action, check 'template.py'.

Configure - The Webhook Listener Server

All configuration is done via the 'config.yml' file, found in the 'src/' folder. The application behavior is fully defined by the config.yml file.

The config.yml consists of two main parts,

  1. 'server' section, defining all data to run the server
  2. 'webhooks' section, defining all GitHub events and Webhooks for the application to respond

Sample YAML config

server:
port: 80# the port that the application listen for Webhooksbind: 0.0.0.0 # Application bind IPlog: 'WebhookEventServer.log'# log file/locationsecret: top_secret # 'random' string (for incoming Webhook requests)# GitHub API request infotoken_file: 'token.pat'# security token storage (replaces 'token')token: f7bb2272b...230c1ed9889 # security token (for Github API calls)github_api: 'https://api.github.com'# GitHub Api endpoint (might be different for on premise)owner: jdoeorganization: jchallenge1# list the Webhook events that we want to respond towebhooks:
# events list from - https://developer.github.com/webhooks/
- event: issuesdescription: 'GitHub Issue created...'# the payload_attr acts as a filter optionpayload_attrs:
- action: openedactions:
- notification
- event: repositorydescription: 'create an issue when a repository gets deleted'payload_attrs:
- action: deletedactions:
- create_issue
- event: issuesdescription: 'GitHub Issue closed...'payload_attrs:
- action: closedactions:

Detailed information on the 'webhooks:' section

ParameterDescription
- event:any event listed in https://developer.github.com/webhooks/
payload_attrs:Any top level Yaml tag, with it's value can be provided here.
- action: openedThe Application will use it as a 'filter' to identify a Webhook event more specifically. For possible attributes check the 'Events API payload' section from https://developer.github.com/webhooks/
actions:any number of actions can be provided here as long as it exist in the 'modules' folder
- create_issuepython file in the 'modules' folder
- notificationpython file in the 'modules' folder

Run - The Webhook Listener Server

Application usage help

# python WebhookEventServer.py -h
usage: WebhookEventServer.py [-h] [--loglevel LOG_LEVEL]
optional arguments:
-h, --help show this help message and exit
--loglevel LOG_LEVEL, -l LOG_LEVEL
LOG_LEVEL: <debug|info|warning|error|critical>
(default: INFO)

Run the application

Sample:

# python WebhookEventServer.py
Start listening on 0.0.0.0:80

The server is now listening on port 80 for incoming GitHub Webhook events !
NOTE: Ports below 1024 are 'Privileged Ports' and require 'root' privileges


Some Additional Information

How to Create an 'Issue' via the GitHub API

Command line sample

curl -d "@./data.json" -u jefeish:cc5...cf75 -X POST https
://api.github.com/repos/jchallenge1/issue-headRepo/issues
  • -d payload
  • -u user:token

Sample payload 'data.json'

{
"title": "Found a bug",
"body": "@user I'm having a problem with this.",
"assignees": [
"myuser"
],
"labels": [
"bug"
]
}

Requirements for Webhook action implementations

Sample 'webhook' code template

importrequestsgloballog# Required class nameclasscommand():
# initialize the classdef__init__(self, logger, server_info, payload):
globallog# webhook action requires thisself.server_info=server_infoself.payload=payloadlog=logger# Common entry pointdefexecute(self):
globallog# Implement action

About

No description or website provided.

Topics

Resources

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages