mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-21 11:55:31 -05:00
Custom Webhook Templates #410
Open
opened 2025-11-02 03:22:10 -06:00 by GiteaMirror
·
40 comments
No Branch/Tag Specified
main
release/v1.25
release/v1.24
release/v1.23
release/v1.22
release/v1.21
release/v1.20
release/v1.19
release/v1.18
release/v1.17
release/v1.16
release/v1.15
release/v1.14
release/v1.13
release/v1.12
release/v1.11
release/v1.10
release/v1.9
release/v1.8
v1.25.3
v1.25.2
v1.25.1
v1.25.0
v1.24.7
v1.25.0-rc0
v1.26.0-dev
v1.24.6
v1.24.5
v1.24.4
v1.24.3
v1.24.2
v1.24.1
v1.24.0
v1.23.8
v1.24.0-rc0
v1.25.0-dev
v1.23.7
v1.23.6
v1.23.5
v1.23.4
v1.23.3
v1.23.2
v1.23.1
v1.23.0
v1.23.0-rc0
v1.24.0-dev
v1.22.6
v1.22.5
v1.22.4
v1.22.3
v1.22.2
v1.22.1
v1.22.0
v1.23.0-dev
v1.22.0-rc1
v1.21.11
v1.22.0-rc0
v1.21.10
v1.21.9
v1.21.8
v1.21.7
v1.21.6
v1.21.5
v1.21.4
v1.21.3
v1.21.2
v1.20.6
v1.21.1
v1.21.0
v1.21.0-rc2
v1.21.0-rc1
v1.20.5
v1.22.0-dev
v1.21.0-rc0
v1.20.4
v1.20.3
v1.20.2
v1.20.1
v1.20.0
v1.19.4
v1.21.0-dev
v1.20.0-rc2
v1.20.0-rc1
v1.20.0-rc0
v1.19.3
v1.19.2
v1.19.1
v1.19.0
v1.19.0-rc1
v1.20.0-dev
v1.19.0-rc0
v1.18.5
v1.18.4
v1.18.3
v1.18.2
v1.18.1
v1.18.0
v1.17.4
v1.18.0-rc1
v1.19.0-dev
v1.18.0-rc0
v1.17.3
v1.17.2
v1.17.1
v1.17.0
v1.17.0-rc2
v1.16.9
v1.17.0-rc1
v1.18.0-dev
v1.16.8
v1.16.7
v1.16.6
v1.16.5
v1.16.4
v1.16.3
v1.16.2
v1.16.1
v1.16.0
v1.15.11
v1.17.0-dev
v1.16.0-rc1
v1.15.10
v1.15.9
v1.15.8
v1.15.7
v1.15.6
v1.15.5
v1.15.4
v1.15.3
v1.15.2
v1.15.1
v1.14.7
v1.15.0
v1.15.0-rc3
v1.14.6
v1.15.0-rc2
v1.14.5
v1.16.0-dev
v1.15.0-rc1
v1.14.4
v1.14.3
v1.14.2
v1.14.1
v1.14.0
v1.13.7
v1.14.0-rc2
v1.13.6
v1.13.5
v1.14.0-rc1
v1.15.0-dev
v1.13.4
v1.13.3
v1.13.2
v1.13.1
v1.13.0
v1.12.6
v1.13.0-rc2
v1.14.0-dev
v1.13.0-rc1
v1.12.5
v1.12.4
v1.12.3
v1.12.2
v1.12.1
v1.11.8
v1.12.0
v1.11.7
v1.12.0-rc2
v1.11.6
v1.12.0-rc1
v1.13.0-dev
v1.11.5
v1.11.4
v1.11.3
v1.10.6
v1.12.0-dev
v1.11.2
v1.10.5
v1.11.1
v1.10.4
v1.11.0
v1.11.0-rc2
v1.10.3
v1.11.0-rc1
v1.10.2
v1.10.1
v1.10.0
v1.9.6
v1.9.5
v1.10.0-rc2
v1.11.0-dev
v1.10.0-rc1
v1.9.4
v1.9.3
v1.9.2
v1.9.1
v1.9.0
v1.9.0-rc2
v1.10.0-dev
v1.9.0-rc1
v1.8.3
v1.8.2
v1.8.1
v1.8.0
v1.8.0-rc3
v1.7.6
v1.8.0-rc2
v1.7.5
v1.8.0-rc1
v1.9.0-dev
v1.7.4
v1.7.3
v1.7.2
v1.7.1
v1.7.0
v1.7.0-rc3
v1.6.4
v1.7.0-rc2
v1.6.3
v1.7.0-rc1
v1.7.0-dev
v1.6.2
v1.6.1
v1.6.0
v1.6.0-rc2
v1.5.3
v1.6.0-rc1
v1.6.0-dev
v1.5.2
v1.5.1
v1.5.0
v1.5.0-rc2
v1.5.0-rc1
v1.5.0-dev
v1.4.3
v1.4.2
v1.4.1
v1.4.0
v1.4.0-rc3
v1.4.0-rc2
v1.3.3
v1.4.0-rc1
v1.3.2
v1.3.1
v1.3.0
v1.3.0-rc2
v1.3.0-rc1
v1.2.3
v1.2.2
v1.2.1
v1.2.0
v1.2.0-rc3
v1.2.0-rc2
v1.1.4
v1.2.0-rc1
v1.1.3
v1.1.2
v1.1.1
v1.1.0
v1.0.2
v1.0.1
v1.0.0
v0.9.99
Labels
Clear labels
$20
$250
$50
$500
backport/done
💎 Bounty
docs-update-needed
good first issue
hacktoberfest
issue/bounty
issue/confirmed
issue/critical
issue/duplicate
issue/needs-feedback
issue/not-a-bug
issue/regression
issue/stale
issue/workaround
lgtm/need 2
modifies/api
modifies/translation
outdated/backport/v1.18
outdated/theme/markdown
outdated/theme/timetracker
performance/bigrepo
performance/cpu
performance/memory
performance/speed
pr/breaking
proposal/accepted
proposal/rejected
pr/wip
pull-request
reviewed/wontfix
💰 Rewarded
skip-changelog
status/blocked
topic/accessibility
topic/api
topic/authentication
topic/build
topic/code-linting
topic/commit-signing
topic/content-rendering
topic/deployment
topic/distribution
topic/federation
topic/gitea-actions
topic/issues
topic/lfs
topic/mobile
topic/moderation
topic/packages
topic/pr
topic/projects
topic/repo
topic/repo-migration
topic/security
topic/theme
topic/ui
topic/ui-interaction
topic/ux
topic/webhooks
topic/wiki
type/bug
type/deprecation
type/docs
type/enhancement
type/feature
type/miscellaneous
type/proposal
type/question
type/refactoring
type/summary
type/testing
type/upstream
Mirrored from GitHub Pull Request
Milestone
No items
No Milestone
Projects
Clear projects
No project
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: github-starred/gitea#410
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @bkcsoft on GitHub (Feb 28, 2017).
Description
We should allow for custom webhooks. And while we're at it, migrate current webhooks into the new format (This is make it easy for people to remove slack-support (or rename to Mattermost) link to issue ).
I see this being interated in 5 steps (maybe less depending on size of PRs)
{name}_payload.tmpland logo{name}.pngfromoptions/webhooks/andcustom/webhooks/.Name, and custom fields (for config-page). Should be in a file...Could also add support for URL-based icon (to reuse gitea-logo)
The way I see it we'd end up with this:
Screenshots
Will try to make mockup screenshots
@lunny commented on GitHub (May 18, 2018):
How to resolve multiple languages issue?
@bkcsoft commented on GitHub (Jun 17, 2018):
Multiple language issue? You mean for the list? Do they need to be localized? AFAIK "Slack" would be "Slack" in all languages no?
@lunny commented on GitHub (Jun 18, 2018):
OK. They still could customize their locale files.
@bkcsoft commented on GitHub (Jul 4, 2018):
The best part about having webhooks be templates, is that the templates would provide its own translations. So for any built-in templates Gitea provides, we would have separate translation-files for them in Crowd-In 🙂
@pinpox commented on GitHub (Apr 12, 2019):
Any updates on this? I'd offer to help and submit a PR if someone can guide me a bit. Haven't hacked much on gitea yet, but really would like to use this feature
@lunny commented on GitHub (Apr 13, 2019):
You could save all the webhook messages on template files and then read and execute template before send webhooks.
@alexanderadam commented on GitHub (Sep 27, 2019):
This feature would solve a bunch of issues at once (i.e. #2139, #5252, #5267, #5496, #5548, #7488, #7548, #7788, #7973, #8473, #8963, #9000, #9134, #9485, #9504, #9746, #10288, #10418, #10719, #12712, #13063, #13592).
But what's more important: the maintenance probably becomes easier because people could simply add PRs for the templates (or have local custom ones) instead of having a growing hard coded list of webhook services that live in the Go source.
PS: Webhooks that doesn't come with an HTTP interface (i.e. #7549 or #5469) won't be solved by this naturally.
@guillep2k commented on GitHub (Sep 27, 2019):
We could allow the use of external commands for that, like we do for external renderers. That would cover a lot of ground.
@alexanderadam commented on GitHub (Sep 27, 2019):
Absolutely! That makes sense. I guess via template / GUI as well?
Something like
would be nice.
@tacotexmex commented on GitHub (Oct 11, 2019):
Badly needed for my Matrix integration going forward.
@lunny commented on GitHub (Oct 18, 2019):
@guillep2k @alexanderadam But this has been implemented via git hooks? You can edit git hooks on repository settings UI.
@alexanderadam commented on GitHub (Oct 18, 2019):
You are just referring on the external command integration, right?
That's true, I didn't think of that. Thank you!
The major topic of this issue is still open however. 😉
@guillep2k commented on GitHub (Oct 22, 2019):
@lunny I don't know about that. AFAIU git hooks will run under Gitea's user, so they are only available to the site admin or selected users? What I was thinking was something any repo owner can chose from a closed-list, pre-defined by the admin in
custom/otherhookslike we do with labels or gitignore.@fawdlstty commented on GitHub (Nov 6, 2020):
How are the plans for this feature going?
@WattsC-90 commented on GitHub (Nov 19, 2020):
this is a great feature if it can come in soon! want to integrate gitea with existing issue management tool without having to write a custom service in the middle to swap from one to the other! :)
@lunny commented on GitHub (Nov 19, 2020):
Different events should have different templates, so we can define a yml with multiple sections.
@londiniym commented on GitHub (Nov 17, 2021):
How are the plans for this feature going?
@nwmcsween commented on GitHub (Dec 31, 2021):
Add a bounty to get this moving faster, see: https://www.bountysource.com/issues/42577911-custom-webhook-templates
I've added $40USD to this
@oliverpool commented on GitHub (Jul 7, 2022):
@jolheiser le me reply here to https://github.com/go-gitea/gitea/pull/19307#issuecomment-1177731366, since this seems a better place to discuss about it
As far as I understand, it seems already agreed that gitea should offer a way for instance administrators to offer "custom webhook templates".
Looking at the current implementation and the issues for new webhook, it seems that what is actually needed is the possibility to "shape" the canonical JSON along some metadata to adapt to the different services. For instance matrix, Slack and telegram output a smaller JSON with a "text" field summarizing the changes.
So it seems that what is needed is way to transform a JSON document into another JSON document at runtime.
The current implementation is in Go, so it doesn't allow customization at runtime (requires a new compilation).
This issue mentions "templates" and
*_payload.tmplbut does not show any example of such a template. I don't think that Go templates are the best for outputting JSON data (formatting and escaping is not trivial).https://github.com/go-gitea/gitea/issues/1089#issuecomment-730341962 showed a
*_payload.ymltemplate with some string replacement (looking like a go template). So it would mean: executing as a go template and then parsing as YAML (which implies that the go templating must ensure to keep the yaml valid, with proper escaping).In https://github.com/go-gitea/gitea/pull/19307#issuecomment-1177141658 I propose bloblang, which is a document mapper, written in Go. It could read some "mapping" files and run them before delivering the payload.
Pros:
Cons:
Another possibility would be javascript https://github.com/go-gitea/gitea/pull/19307#issuecomment-1126666676 proposed https://github.com/dop251/goja
Pros:
Cons:
What do you think of this overview?
Did you have anything else in mind for the
*_payload.ymlformat?@oliverpool commented on GitHub (Jul 7, 2022):
(if
bloblangseems like a good idea, I would be willing to draft a PR to integrate it)@jolheiser commented on GitHub (Jul 7, 2022):
I agree that describing payloads in YAML is going to be a horrible UX, which is why my current WIP PR didn't go that route.
The current implementation of that PR essentially allows defining a limited UI and passing the payload+form data to another bridge service. More or less a normal Gitea webhook + some limited form data.
As noted in that same PR, some other maintainers want to have it all in the DB, which has stalled the PR because I also think that's bad UX.
Regarding
jsvsbloblang, unless there's a real strong reason to usebloblangI would just as soon use JS. More people are going to be used to it (even if they don't like it), and considering there may be more complex logic depending on the form data (plus adding headers, etc etc) it seems like it may be a better fit.It seems there are conflicting opinions on the very basics of how this should work currently.
My original PR included the ability to run custom scripts rather than requiring another running service, but it was scrapped in favor of bridge services (even though those are currently possible and yet not widely used)
In order to continue this, I think we need to get a clear answer on what is going to be allowed before we begin to discuss implementations.
To answer the above with my own opinions:
I don't have a huge preference on how it's done, but I still don't think running a local command would be a dramatic amount of overhead. At least not any more than embedding an x-lang engine into the runtime.
Having it in the DB, I'm not entirely sure what an install process would look like. "Here, copy/paste this YAML into your page"?
@oliverpool commented on GitHub (Jul 8, 2022):
I would say yes. The goal of a webhook is to communicate with another service, very unlikely running on the same machine. If you can control what runs on the machine, then exposing a service via a local port is not hard to do (however this is only accessible to instance administrators, which represent a minority of the gitea users).
I don't understand what you mean. If I want to post a message to mattermost/matrix/discord every time a PR is opened, I only need to shape the payload (and add some Authorization headers). If the "custom webhook" allows this, I don't need a bridge.
The usecase I actually want to do, is trigger a sourcehut build.
I would restrict "people" to "gitea-dev" and "instance-administrator".
Another possibility would be wasm.
I think that it should be a language restricted enough (I fear, that if JS is allowed, the "people" will expect to be able to perform "fetch" requests directly from the script - which could be interesting, but not really a "webhook" anymore, more like a "hook").
Actually I think we should take a step back and ask who should be allowed to customize what for the webhooks.
Currently:
deliver.gofile)What workflows do we want to allow/ease?
Here is my take:
I would refrain (at least for now) to allow the end-user to create a custom webhook.
so I agree with @jolheiser that the config files/images should live on disk (I do agree with you on something 🤗 :)
@jolheiser commented on GitHub (Jul 8, 2022):
@oliverpool Are you on Discord or Matrix by chance? I think perhaps it may be more effective to line up there and then post a summary here once we've aligned our thoughts.
@oliverpool commented on GitHub (Jul 26, 2022):
Thinking more about this the
transformation serviceshould always output an object, with apayloadkey. Something like:@Flashdown commented on GitHub (Jan 26, 2023):
For those who can't wait for this one to become ready and merged like me (https://github.com/go-gitea/gitea/pull/19307)
that would like to use Gitea Webhooks with Google Chat in the meanwhile, then I'd like to share with you that I've found a good workaround using a NodeJS proxy in a docker container that translates slack webhooks to google chat webhooks. It's working fine for me :)
-> https://github.com/chriseaton/slack-to-google-chat-webhook-proxy
@oliverpool commented on GitHub (Mar 14, 2023):
@jolheiser I recently looked at the webhook state and to allow moving forward, I would recommend splitting this issue in 2 steps:
Currently to generate a webhook request, the following happens:
webhook.PrepareWebhookis called, with the webhook model, the event type and the payloadwebhook.payloadCreatoris calledwebhook.payloadCreator(which callsconvertPayloader) is saved aswebhook_model.HookTaskwebhook_model.HookTaskis added to the queuewebhook.Deliveris called, with the webhook model and theHookTaskI think a couple of things could be refactored:
2.
webhook.payloadCreatorFor all webhooks, it calls
GetXXXPayload, which callsconvertPayloaderwhich calls the right method on the webhook model.Instead of
GetXXXPayload, aNewXXXHookHandlercould be created, which returns an interface.convertPayloaderwould then be called first calls the right method on the previous interface (if the method is missing, it means the event is not supported by the hook, or it could call a default method?).Moreover the
p api.Payloaderandevent webhook_module.HookEventTypearguments ofconvertPayloaderseem redundant: a type switch could probably happen onp(and dismiss theeventargument).3. & 5.
Currently the actual request is created at step 5. I think it could be created at step 3. and simply save in the database the whole request (which is done on step 6. anyway):
So instead of
func (m *MatrixPayload) IssueComment(p *api.IssueCommentPayload) (api.Payloader, error), it would be something likefunc (m *MatrixPayload) IssueComment(uuid string, p *api.IssueCommentPayload) (webhook_model.HookRequest, []byte, error)(uuid is the hook_id, needed for idempotency).End result
webhook.PrepareWebhookis called, with the webhook model, the event type and the payloadhandler, err := webhook.NewXXXHookHandler(meta)is calledhookRequest, body, err := createPayload(handler, p api.Payloader)is called and saved aswebhook_model.HookTaskwebhook_model.HookTaskis added to the queuewebhook.Deliversimply unmarshalls the requestI think generating the whole request upfront would make the logic much easier.
It may make adding new native hooks much easier.
It should help having custom webhooks, since it would formalize the output of the function:
webhook_model.HookRequest, []byte, error(the input would still be an open question...).Maybe this sounds to abstract and I should open a PR to show what I mean. What do you think?
@jolheiser commented on GitHub (Mar 15, 2023):
I would need to refresh myself a bit on the webhook code, but that sounds feasible at a glance.
I've been meaning to get back to this, but my TODO list never seems to decrease. 😔
If you'd like to work on the refactor PR that may be reasonable, I'd be happy to review.
@weironz commented on GitHub (Dec 7, 2023):
Does Gitea Webhook currently not support docking with argo events?
https://github.com/argoproj/argo-events/issues/1431#issuecomment-1844979706
@oliverpool commented on GitHub (Jan 25, 2024):
@jolheiser (and anyone following here on this issue) I drafted a refactoring of the webhook_task database storage (proposed in https://github.com/go-gitea/gitea/issues/1089#issuecomment-1467775828) on codeberg: https://codeberg.org/forgejo/forgejo/pulls/2231
I plan to upstream this to gitea when this draft is complete.
I look forward to any feedback! (here, on matrix or on codeberg)
@lunny commented on GitHub (Jan 25, 2024):
I still think we need a table to save the customized
HookType. Since this table is necessary, some other informations can also be stored into this table. Those are meta information, I don't think storing them intohook_taskis a good idea.@oliverpool commented on GitHub (Jan 25, 2024):
@lunny my PR does not implement any customized HookType.
It is more of a step to simplify the hook interface, so that adding custom types (in later PRs) should be easier.
@lunny commented on GitHub (Jan 25, 2024):
I mean the migrations is unnecessary, we can put them into the
hook_typetable, especially for a big instance like codeberg.@oliverpool commented on GitHub (Jan 25, 2024):
You are right, the impact of the migration must be checked, I will ask codeberg to run it on a copy of the database (it can likely be make faster by using parallelism).
To make it less work, I added a call to the
cleanup_hook_task_tablebefore the migration is run.I think that this migration is worthwhile, because it enables a substantial cleanup of the webhook code. Defining a new webhook inside gitea (as Go files) will touch far fewer files after this PR (for instance the matrix hook currently has some logic inside the
deliver.gofile - #19307 has this as well).The proposed PR is more of an intermediary step:
@oliverpool commented on GitHub (Jan 29, 2024):
@lunny after considering the feedback that I received (inclusive yours, thank you for it!), I am proposing another approach: https://codeberg.org/forgejo/forgejo/pulls/2263 (saving the raw event as-is and doing the type-dependent logic right before sending).
With this new approach, the migration is much lighter (only adding a
versionfield for backward compatibility) and the overall changes are fewer.@oliverpool commented on GitHub (Jan 30, 2024):
@lunny regarding the specific logic added in
services/webhook/payloader.goby #12046 (which got refactored as-is in #12310):b51bd7f1d6/modules/webhook/payloader.go (L37-L42)Do you know if this old (June 2020) comment of yours is still up-to-date? https://github.com/go-gitea/gitea/issues/11940#issuecomment-645713996
Looking at the current code:
return matchIssueCommentEvent(commit, payload.(*api.IssueCommentPayload), evt)for allHookEvent***CommentHookEvent***Commentare of type*api.IssueCommentPayloadSo I guess that this can be simplified to:
What do you think?
@oliverpool commented on GitHub (Feb 6, 2024):
@jolheiser I have a branch ready, for which I plan to open a PR here soon: https://codeberg.org/forgejo/forgejo/pulls/2263
Following the discussion with @lunny and other feedback, instead of saving the request to be delivered in the database, it saves the raw event and creates the webhook-dependent request right before delivering it.
Hence the webhook-specific logic is exists within
Deliver, which should simplify the addition of other/custom webhook types.Feel free to comment on codeberg, or wait for the PR here.
@oliverpool commented on GitHub (Feb 12, 2024):
PR has been opened here: #29145
@jessesanford commented on GitHub (Sep 14, 2024):
Now that https://github.com/go-gitea/gitea/pull/29145 has been merged, is there a logical path forward for this?
@OdinVex commented on GitHub (Sep 14, 2024):
I would have thought custom would've been the first type to be supported because using variable replacement and a template you could support so very many right away...
@merlinz01 commented on GitHub (Jul 30, 2025):
IMO the customization here should be separated into two parts: message HTML customization (for existing integrations), and webhook request JSON customization (for one-off custom integrations). The message part could be done with the builtin
html/templateortext/template, and the request part could be done with either a point-and-click interface or a JSON-like configuration.If we could get just the message customization that would be sufficient for my needs/wishes currently, and I don't think it would be very hard to implement.