This file documents the top-level keys the handler populates in the data map used by templates.
Keys are grouped into families. Each family has a Common subsection listing keys shared across the family's events. Event sections only list keys that are specific to that event (i.e., not repeated in the family's Common list). Keys are alphabetized inside each list.
Templates are chosen by matching a set of tags. Each template payload in configs/templates*.jsonc carries a tags list (examples: tags: ["issues", "opened"], tags: ["push", "force"], or tags: ["pull_request", "closed", "merged"]).
-
Event type is ALWAYS a tag: The first tag is always the event type (e.g.,
push,pull_request,issues,workflow_run). This is added automatically and does not need to be specified in handler code. -
Action is automatically a tag: If the webhook payload contains an
actionfield (e.g.,opened,closed,synchronize), it is automatically added as a tag. This means all event actions become selectable tags without extra code. -
Additional context tags: Some events add context-specific tags:
pushevents addforcefor force pushespull_requestwithaction=closedaddsmergedorunmergedbased on merge statusissuesevents addtype:bug,type:feature,type:taskbased on issue labels or type fieldworkflow_run,workflow_job,check_run,check_suiteadd status tags likecompleted,in_progress,queuedand conclusion tags likesuccess,failure,cancelled
-
Default tag: If no specific tags are added beyond event type and action, a
defaulttag is appended as a fallback.
Note: For details on template substitution (placeholders, filters, and supported
{{#if ...}}{{/if}}conditional blocks), seeinternal/template/README.md. It is recommended to read that document before editingconfigs/templates*.jsonc.
Templates are evaluated in priority order using tag matching. A template with more matching tags scores higher:
- Template with tags
["pull_request", "closed", "merged"]matches better than["pull_request", "default"]when the PR is closed and merged - Template with tags
["issues", "opened", "type:bug"]matches better than["issues", "opened"]for bug issues
Handler uses modular common data functions:
prepareRepoData()- Adds repository fields (all events with repository)prepareSenderData()- Adds sender fields (all events with sender)prepareOrgData()- Adds organization fields (org-level events)prepareInstallationCommonData()- Adds installation fields (GitHub App events)prepareCommonData()- Convenience wrapper calling all above functions
Individual handlers can call specific common functions as needed instead of always calling prepareCommonData().
These keys are provided by common data preparation functions:
repo_full_name(string) — repository.full_namerepo_name(string) — repository.namerepo_url(string) — repository.html_urlrepository(object) — the rawrepositoryobject from the payloadrepository_link_md(string) — markdown link to the repository (e.g. "owner/repo")
sender(object) — the rawsenderobject from the payloadsender_avatar(string) — sender.avatar_urlsender_link_md(string) — markdown link to the sender profile (e.g. "user")sender_name(string) — sender.loginsender_url(string) — sender.html_url
organization(object) — the raworganizationobject from the payloadorg_avatar(string) — organization.avatar_urlorg_link_md(string) — markdown link to the organization (e.g. "OrgName")org_name(string) — organization.loginorg_url(string) — organization.html_url
installation(object) — the rawinstallationobject from the payloadinstallation_id(number) — installation.id
All these events call prepareRepoData() and prepareSenderData():
-
repo_full_name,repo_name,repo_url,repository,repository_link_md -
sender,sender_avatar,sender_link_md,sender_name,sender_url -
Tags: push →
[push, default],[push, force]; create/delete/fork/gollum/repository →[default]. -
Condition:
payload.forced == true→ useforce; otherwise use family tag.
branch_link_md(string)branch_name(string)branch_url(string)commit_authors([]string)commit_authors_with_links([]string)commit_authors_with_links_joined(string)commit_authors_joined(string)commit_message(string)commit_messages([]string)commit_messages_joined(string)commits(array)commits_count(int)compare_url(string)forced(bool)pusher(object)pusher_link_md(string)ref(string)
master_branch(string)ref(string)ref_type(string)
ref(string)ref_type(string)
forkee(object)forkee_full_name(string)forkee_url(string)
pages(array)
-
pr_number(int) -
pr_title(string) -
pr_url(string) -
pull_request(object) -
Tags:
[pr, closed, merged],[pr, closed, unmerged],[pr, default]. -
Condition:
action == "closed" && pull_request.merged == true→closed,merged;action == "closed" && pull_request.merged == false→closed,unmerged; elsepr,default.
action(string)pr_base_branch_link_md(string)pr_base_ref(string)pr_body(string)pr_head_branch_link_md(string)pr_head_ref(string)pr_merged(bool)pr_state(string)pr_user_link_md(string)
action(string)review(object)review_body(string)review_state(string)review_url(string)review_user_link_md(string)
comment_body(string)comment_url(string)comment_user_link_md(string)
-
issue(object) -
issue_number(int) -
issue_title(string) -
issue_url(string) -
Tags:
[issue, typed],[issue, type:bug],[issue, type:feature],[issue, type:task],[issue, type:unknown]. -
Condition:
issue.typeif present; otherwise inferred from labels viadetectIssueTypeFromLabels.
action(string)issue_body(string)issue_link_md(string)issue_state(string)issue_type(string)issue_type_name(string)issue_user_link_md(string)
comment(object)comment_body(string)comment_url(string)comment_user_link_md(string)
-
discussion(object) -
discussion_title(string) -
discussion_url(string) -
Tags:
[default]. -
Condition: use family tag
discussion(no extra qualifiers).
action(string)discussion_body(string)discussion_user_link_md(string)
comment(object)comment_body(string)comment_url(string)comment_user_link_md(string)
-
action(string) -
Tags:
release→[default];package→[default]. -
Condition: use family tag (
release/package).
release(object)release_body(string)release_name(string)release_tag(string)release_url(string)
package(object)package_link_md(string)package_name(string)package_publisher_link_md(string)package_tag_name(string)package_type(string)package_version(string)package_version_name(string)
-
action(string) -
deployment(object) -
deployment_status(object) -
status(object) -
Tags:
[default]for deployment, deployment_status, check_run, check_suite, workflow_run, status. -
Condition: use family tag (shipped templates don't add qualifiers).
deployment_id(any)deployment_url(string)
- (see deployment_status object)
- (see check_run object)
action(string)
-
action(string) -
workflow_name(string) -
workflow_run(object) -
workflow_run_number(int) — the run number (normalized to an integer when possible) -
workflow_head_branch(string) — the head branch for the run -
workflow_head_sha(string) — the commit SHA the run ran against -
workflow_run_url(string) — the run html_url -
workflow_run_link_md(string) — markdown link to the run (e.g. "#123") -
workflow_repo_full_name(string) — repository.full_name for the workflow's repository -
workflow_repo_url(string) — repository.html_url for the workflow's repository -
workflow_repository_link_md(string) — markdown link to the repository (e.g. "owner/repo") -
Tags:
[workflow_run, completed, success],[workflow_run, completed, failure],[default]. -
Condition: the handler appends
completedwhenworkflow_run.status == "completed"and appendssuccessorfailurewhenworkflow_run.conclusionmatches those values; non-completed statuses (e.g.in_progress) are emitted as tags as well so templates may opt to match them.
status_state(string)
-
action(string) -
project(object) -
project_card(object) -
project_column(object) -
Tags:
[default]for project, project_card, project_column. -
Condition: use family tag.
project_name(string)project_url(string)
- (see project_card object)
project_column_name(string)
action(string)milestone(object)milestone_description(string)milestone_title(string)
-
action(string) -
member(object) -
membership(object) -
team(object) -
Tags:
[default]for membership, member, team, organization. -
Condition: use family tag; templates may vary on
action.
member_login(string)
organization(object)organization_login(string)
-
page_build(object) -
Tags:
[default]. -
Condition: use family tag
page_build.
-
action(string) -
repository(object) -
Tags:
[default]for public, star, watch. -
Condition: use family tag;
actionoften contains the qualifier.
- (see repository object)
- (use
action)
- (see repository object)
-
action(string) -
security_advisory(object) -
Tags:
[default]. -
Condition: use family tag
security_advisory.
security_advisory_id(string)
- The lists above reflect the keys the handler currently sets in code. Some keys are convenience fields (markdown links, joined strings) derived from the raw payload.
- Types listed are best-effort based on the typical payload shape. Templates should guard against missing keys.
- If you change code to add/remove keys, update this document and add unit tests that assert the presence and shape of the new keys.
-
action(string) -
repository(object) -
Tags:
[default]for branch_protection_configuration, branch_protection_rule. -
Condition: use family tag.
branch_protection_configuration(object)
rule(object)rule_name(string)branch_protection_rule(object)
action(string)definition(object)property_name(string)custom_property(object)
action(string)new_property_values(array)old_property_values(array)custom_property_values(object)
action(string)environment(string)deployment(object)deployment_callback_url(string)deployment_protection_rule(object)
action(string)approver(object)approver_login(string)approver_link_md(string)comment(string)workflow_run(object)deployment_review(object)
action(string)github_app_authorization(object)
action(string)installation(object)installation_id(int)repositories(array)repositories_count(int)installation_event(object)
action(string)repositories_added(array)repositories_added_count(int)repositories_removed(array)repositories_removed_count(int)repository_selection(string)installation_repositories(object)
action(string)account(object)account_login(string)changes(object)old_login(string)target_type(string)installation_target(object)
action(string)blocked_issue(object)blocked_issue_number(int)blocked_issue_title(string)blocking_issue(object)blocking_issue_number(int)blocking_issue_title(string)blocking_issue_repo(object)blocking_issue_repo_name(string)issue_dependencies(object)
action(string)marketplace_purchase(object)account_login(string)plan_name(string)previous_marketplace_purchase(object)effective_date(string)
action(string)merge_group(object)head_sha(string)head_ref(string)base_sha(string)base_ref(string)
action(string)hook(object)hook_id(int)hook_type(string)meta(object)
zen(string)hook(object)hook_id(int)hook_type(string)ping(object)
action(string)blocked_user(object)blocked_user_login(string)blocked_user_link_md(string)org_block(object)
action(string)registry_package(object)package_name(string)package_type(string)package_version(string)
action(string)repository_advisory(object)advisory_id(string)advisory_summary(string)advisory_severity(string)
event_type(string)client_payload(object)repository_dispatch(object)
action(string)alert(object)alert_number(int)location(object)location_type(string)secret_scanning_alert_location(object)
action(string)scan(object)scan_status(string)scan_completed_at(string)secret_scanning_scan(object)
changes(object)security_and_analysis(object)
action(string)sponsorship(object)sponsor_login(string)sponsor_link_md(string)sponsorable_login(string)tier_name(string)tier_monthly_price_cents(int)tier_monthly_price_dollars(float)
action(string)parent_issue(object)parent_issue_number(int)parent_issue_title(string)sub_issue(object)sub_issue_number(int)sub_issue_title(string)sub_issues(object)
team(object)team_name(string)team_slug(string)team_add(object)
action(string)projects_v2(object)project_id(int)project_title(string)project_description(string)
action(string)projects_v2_item(object)item_id(int)item_node_id(string)project_node_id(string)content_node_id(string)content_type(string)changes(object)
action(string)projects_v2_status_update(object)status_update_id(int)status_update_body(string)status(string)
action(string)pull_request(object)pr_number(int)pr_title(string)pr_url(string)thread(object)thread_id(string)thread_comments(array)thread_comments_count(int)pull_request_review_thread(object)
workflow(string)inputs(object)ref(string)workflow_dispatch(object)
action(string)workflow_job(object)job_id(int)job_name(string)job_status(string)job_conclusion(string)job_url(string)run_id(int)
action(string)personal_access_token_request(object)request_id(int)token_owner_login(string)token_name(string)token_expired(bool)
- Add a small, focused
prepare<Event>Datafunction that populates only the keys templates need. - Document new keys in this README (alphabetically) under the appropriate event group.
- Add tests in
internal/handler/handler_test.goverifying important keys for that event.