Skip to content

Support for generic webhooks #8522

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 50 commits into from
Nov 9, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
12cd38b
Support for generic webhooks
stsewd Sep 22, 2021
ed703fd
Rename unsub_url -> unsubscribe_url
stsewd Sep 29, 2021
2584afd
Merge branch 'master' into webhooks
stsewd Sep 29, 2021
224622e
Update migrations
stsewd Sep 29, 2021
c531286
Fix merge conflict
stsewd Sep 29, 2021
1a5c5b7
Add more susbtitutions
stsewd Oct 4, 2021
2e03439
Fix
stsewd Oct 4, 2021
9a961e7
Zero downtime
stsewd Oct 4, 2021
297d1a6
Test views
stsewd Oct 4, 2021
73e5efb
fix tests
stsewd Oct 4, 2021
c0689f1
Document generic webhooks
astrojuanlu Oct 21, 2021
c99df5d
Merge branch 'master' into webhooks
stsewd Oct 21, 2021
c6c499b
Whitespace
astrojuanlu Oct 25, 2021
0a031b3
Describe legacy webhooks and migration path
astrojuanlu Oct 25, 2021
9405d4b
Add examples
astrojuanlu Oct 25, 2021
2dd6b39
Fix external version disclaimer
astrojuanlu Oct 25, 2021
3e988a5
Add example to validate webhook signature
astrojuanlu Oct 25, 2021
80446dd
Merge branch 'webhooks' into webhooks-documentation
astrojuanlu Oct 25, 2021
ce31189
Fix markup for Discord webhook example
astrojuanlu Oct 25, 2021
43f9dd4
Clarify that validation is optional
astrojuanlu Oct 25, 2021
e1b426e
Upgrade to use sha256 instead of sha1
stsewd Oct 25, 2021
b6fd66e
Style improvements
astrojuanlu Oct 25, 2021
b443b4f
Fix digest comparison
astrojuanlu Oct 25, 2021
8f55e27
Webhook example improvements
astrojuanlu Oct 25, 2021
39c8ab2
Update external documentation links
astrojuanlu Oct 25, 2021
37484f1
Link to docs
stsewd Oct 25, 2021
fe45d31
Fix screenshot zoom
astrojuanlu Oct 25, 2021
5ff125c
Update test
stsewd Oct 25, 2021
342eea7
Support build.start_date
stsewd Oct 25, 2021
509b09b
Don't show timezone and microseconds
stsewd Oct 25, 2021
e4ea22e
Merge branch 'master' into webhooks
stsewd Nov 2, 2021
2b16a86
Change substitutions format again
stsewd Nov 2, 2021
33f9557
Move payload validation down
astrojuanlu Nov 8, 2021
1077d61
Update template syntax
astrojuanlu Nov 8, 2021
481380d
Merge branch 'webhooks' into webhooks-documentation
astrojuanlu Nov 8, 2021
19eec46
Complete webhook example payload
astrojuanlu Nov 8, 2021
088e629
Add screenshot for custom payload
astrojuanlu Nov 8, 2021
2a0a031
Style improvements
astrojuanlu Nov 8, 2021
a26bd54
Comment
stsewd Nov 8, 2021
a2b6a2a
Merge branch 'master' into webhooks
stsewd Nov 8, 2021
ec9b4fc
Switch to one space for template substitutions
astrojuanlu Nov 8, 2021
b049047
Add examples for URLs
astrojuanlu Nov 8, 2021
94f9fc1
Fix parameter name
astrojuanlu Nov 8, 2021
a928097
Complete remaining variables
astrojuanlu Nov 8, 2021
8f20472
Fix title length
astrojuanlu Nov 8, 2021
04e2953
Fix JSON
astrojuanlu Nov 8, 2021
d1a21f0
Merge pull request #8609 from readthedocs/webhooks-documentation
astrojuanlu Nov 8, 2021
b6dd115
Small updates to docs
stsewd Nov 8, 2021
732ccdd
Merge branch 'master' into webhooks
stsewd Nov 9, 2021
d2611b4
Explicitly test with/out organizations
stsewd Nov 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions readthedocs/projects/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,15 +465,15 @@ def __init__(self, *args, **kwargs):
# Don't show the secret in the creation form.
self.fields.pop('secret')
self.fields['payload'].initial = json.dumps({
'event': '$event',
'name': '$project.name',
'slug': '$project.slug',
'version': '$version.slug',
'commit': '$build.commit',
'build': '$build.id',
'start_date': '$build.start_date',
'build_url': '$build.url',
'docs_url': '$build.docs_url',
'event': '{{ event }}',
'name': '{{ project.name }}',
'slug': '{{ project.slug }}',
'version': '{{ version.slug }}',
'commit': '{{ build.commit }}',
'build': '{{ build.id }}',
'start_date': '{{ build.start_date }}',
'build_url': '{{ build.url }}',
'docs_url': '{{ build.docs_url }}',
}, indent=2)

def clean_project(self):
Expand Down
35 changes: 20 additions & 15 deletions readthedocs/projects/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1546,7 +1546,11 @@ def save(self, *args, **kwargs):
super().save(*args, **kwargs)

def get_payload(self, version, build, event):
"""Get the final payload replacing all placeholders."""
"""
Get the final payload replacing all placeholders.

Placeholders are in the ``{{ foo }}`` or ``{{foo}}`` format.
"""
if not self.payload:
return None

Expand Down Expand Up @@ -1577,25 +1581,26 @@ def get_payload(self, version, build, event):
).isoformat()

substitutions = {
'$event': event,
'$build.id': build.id,
'$build.commit': commit,
'$build.url': build_url,
'$build.docs_url': build_docsurl,
'$build.start_date': start_date,
'$organization.name': organization_name,
'$organization.slug': organization_slug,
'$project.slug': project.slug,
'$project.name': project.name,
'$project.url': project_url,
'$version.slug': version.slug,
'$version.name': version.verbose_name,
'event': event,
'build.id': build.id,
'build.commit': commit,
'build.url': build_url,
'build.docs_url': build_docsurl,
'build.start_date': start_date,
'organization.name': organization_name,
'organization.slug': organization_slug,
'project.slug': project.slug,
'project.name': project.name,
'project.url': project_url,
'version.slug': version.slug,
'version.name': version.verbose_name,
}
payload = self.payload
# Small protection for DDoS.
max_substitutions = 99
for substitution, value in substitutions.items():
payload = payload.replace(substitution, str(value), max_substitutions)
payload = payload.replace(f'{{{{ {substitution} }}}}', str(value), max_substitutions)
payload = payload.replace(f'{{{{{substitution}}}}}', str(value), max_substitutions)
return payload

def sign_payload(self, payload):
Expand Down
30 changes: 15 additions & 15 deletions readthedocs/rtd_tests/tests/test_build_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,21 +155,21 @@ def test_send_webhook_custom_payload(self, mock_request):
project=self.project,
events=[WebHookEvent.objects.get(name=WebHookEvent.BUILD_FAILED)],
payload=json.dumps({
'message': 'Event $event triggered for $version.slug',
'message': 'Event {{ event }} triggered for {{ version.slug }}',
'extra-data': {
'build_id': '$build.id',
'build_commit': '$build.commit',
'build_url': '$build.url',
'build_docsurl': '$build.docs_url',
'build_start_date': '$build.start_date',
'organization_slug': '$organization.slug',
'organization_name': '$organization.name',
'project_slug': '$project.slug',
'project_name': '$project.name',
'project_url': '$project.url',
'version_slug': '$version.slug',
'version_name': '$version.name',
'invalid_substitution': '$invalid.substitution',
'build_id': '{{build.id}}',
'build_commit': '{{build.commit}}',
'build_url': '{{ build.url }}',
'build_docsurl': '{{ build.docs_url }}',
'build_start_date': '{{ build.start_date }}',
'organization_slug': '{{ organization.slug }}',
'organization_name': '{{ organization.name }}',
'project_slug': '{{ project.slug }}',
'project_name': '{{ project.name }}',
'project_url': '{{ project.url }}',
'version_slug': '{{ version.slug }}',
'version_name': '{{ version.name }}',
'invalid_substitution': '{{ invalid.substitution }}',
}
}),
)
Expand Down Expand Up @@ -198,7 +198,7 @@ def test_send_webhook_custom_payload(self, mock_request):
'project_url': f'https://readthedocs.org{self.project.get_absolute_url()}',
'version_name': self.version.verbose_name,
'version_slug': self.version.slug,
'invalid_substitution': '$invalid.substitution',
'invalid_substitution': '{{ invalid.substitution }}',
},
}
)
Expand Down