integrations: Create incoming webhook for GitHub Sponsors.

Creates an incoming webhook integration for Github Sponsors. The
main use case is getting notifications when new sponsors sign up.

Fixes #18320.
This commit is contained in:
David Rosa 2023-12-19 15:43:09 -08:00 committed by Tim Abbott
parent ea89a4c6f7
commit d29cd04387
12 changed files with 707 additions and 6 deletions

View File

@ -8,4 +8,5 @@ pnpm-lock.yaml
/web/third
/zerver/tests/fixtures
/zerver/webhooks/*/doc.md
/zerver/webhooks/github/githubsponsors.md
/zerver/webhooks/*/fixtures

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -197,6 +197,7 @@ class WebhookIntegration(Integration):
stream_name: Optional[str] = None,
legacy: bool = False,
config_options: Sequence[Tuple[str, str, OptionValidator]] = [],
dir_name: Optional[str] = None,
) -> None:
if client_name is None:
client_name = self.DEFAULT_CLIENT_NAME.format(name=name.title())
@ -229,9 +230,12 @@ class WebhookIntegration(Integration):
if doc is None:
doc = self.DEFAULT_DOC_PATH.format(name=name, ext="md")
self.doc = doc
if dir_name is None:
dir_name = self.name
self.dir_name = dir_name
@property
def url_object(self) -> URLResolver:
assert self.function is not None
@ -266,7 +270,7 @@ def get_fixture_and_image_paths(
integration: Integration, screenshot_config: BaseScreenshotConfig
) -> Tuple[str, str]:
if isinstance(integration, WebhookIntegration):
fixture_dir = os.path.join("zerver", "webhooks", integration.name, "fixtures")
fixture_dir = os.path.join("zerver", "webhooks", integration.dir_name, "fixtures")
else:
fixture_dir = os.path.join("zerver", "integration_fixtures", integration.name)
fixture_path = os.path.join(fixture_dir, screenshot_config.fixture_name)
@ -401,6 +405,16 @@ WEBHOOK_INTEGRATIONS: List[WebhookIntegration] = [
function="zerver.webhooks.github.view.api_github_webhook",
stream_name="github",
),
WebhookIntegration(
"githubsponsors",
["financial"],
display_name="GitHub Sponsors",
logo="images/integrations/logos/github.svg",
dir_name="github",
function="zerver.webhooks.github.view.api_github_webhook",
doc="github/githubsponsors.md",
stream_name="github",
),
WebhookIntegration("gitlab", ["version-control"], display_name="GitLab"),
WebhookIntegration("gocd", ["continuous-integration"], display_name="GoCD"),
WebhookIntegration("gogs", ["version-control"], stream_name="commits"),
@ -739,6 +753,7 @@ DOC_SCREENSHOT_CONFIG: Dict[str, List[BaseScreenshotConfig]] = {
"gci": [ScreenshotConfig("task_abandoned_by_student.json")],
"gitea": [ScreenshotConfig("pull_request__merged.json")],
"github": [ScreenshotConfig("push__1_commit.json")],
"githubsponsors": [ScreenshotConfig("created.json")],
"gitlab": [ScreenshotConfig("push_hook__push_local_branch_without_commits.json")],
"gocd": [ScreenshotConfig("pipeline.json")],
"gogs": [ScreenshotConfig("pull_request__opened.json")],
@ -836,8 +851,9 @@ DOC_SCREENSHOT_CONFIG: Dict[str, List[BaseScreenshotConfig]] = {
def get_all_event_types_for_integration(integration: Integration) -> Optional[List[str]]:
integration = INTEGRATIONS[integration.name]
if isinstance(integration, WebhookIntegration) and hasattr(
integration.function, "_all_event_types"
):
return integration.function._all_event_types
if isinstance(integration, WebhookIntegration):
if integration.name == "githubsponsors":
return import_string("zerver.webhooks.github.view.SPONSORS_EVENT_TYPES")
if hasattr(integration.function, "_all_event_types"):
return integration.function._all_event_types
return None

View File

@ -0,0 +1,78 @@
{
"action": "cancelled",
"sponsorship": {
"node_id": "MDExOlNwb25zb3JzaGlwMQ==",
"created_at": "2019-12-20T19:24:46+00:00",
"sponsorable": {
"login": "octocat",
"id": 5,
"node_id": "MDQ6VXNlcjU=",
"avatar_url": "https://avatars2.githubusercontent.com/u/5?",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false
},
"sponsor": {
"login": "monalisa",
"id": 2,
"node_id": "MDQ6VXNlcjI=",
"avatar_url": "https://avatars2.githubusercontent.com/u/2?",
"gravatar_id": "",
"url": "https://api.github.com/users/monalisa",
"html_url": "https://github.com/monalisa",
"followers_url": "https://api.github.com/users/monalisa/followers",
"following_url": "https://api.github.com/users/monalisa/following{/other_user}",
"gists_url": "https://api.github.com/users/monalisa/gists{/gist_id}",
"starred_url": "https://api.github.com/users/monalisa/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/monalisa/subscriptions",
"organizations_url": "https://api.github.com/users/monalisa/orgs",
"repos_url": "https://api.github.com/users/monalisa/repos",
"events_url": "https://api.github.com/users/monalisa/events{/privacy}",
"received_events_url": "https://api.github.com/users/monalisa/received_events",
"type": "User",
"site_admin": true
},
"privacy_level": "private",
"tier": {
"node_id": "MDEyOlNwb25zb3JzVGllcjE=",
"created_at": "2019-12-20T19:17:05Z",
"description": "foo",
"monthly_price_in_cents": 500,
"monthly_price_in_dollars": 5,
"name": "$5 a month",
"is_one_time": false,
"is_custom_amount": false
}
},
"sender": {
"login": "monalisa",
"id": 2,
"node_id": "MDQ6VXNlcjI=",
"avatar_url": "https://avatars2.githubusercontent.com/u/2?",
"gravatar_id": "",
"url": "https://api.github.com/users/monalisa",
"html_url": "https://github.com/monalisa",
"followers_url": "https://api.github.com/users/monalisa/followers",
"following_url": "https://api.github.com/users/monalisa/following{/other_user}",
"gists_url": "https://api.github.com/users/monalisa/gists{/gist_id}",
"starred_url": "https://api.github.com/users/monalisa/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/monalisa/subscriptions",
"organizations_url": "https://api.github.com/users/monalisa/orgs",
"repos_url": "https://api.github.com/users/monalisa/repos",
"events_url": "https://api.github.com/users/monalisa/events{/privacy}",
"received_events_url": "https://api.github.com/users/monalisa/received_events",
"type": "User",
"site_admin": true
}
}

View File

@ -0,0 +1,78 @@
{
"action": "created",
"sponsorship": {
"node_id": "MDExOlNwb25zb3JzaGlwMQ==",
"created_at": "2019-12-20T19:24:46+00:00",
"sponsorable": {
"login": "octocat",
"id": 5,
"node_id": "MDQ6VXNlcjU=",
"avatar_url": "https://avatars2.githubusercontent.com/u/5?",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false
},
"sponsor": {
"login": "monalisa",
"id": 2,
"node_id": "MDQ6VXNlcjI=",
"avatar_url": "https://avatars2.githubusercontent.com/u/2?",
"gravatar_id": "",
"url": "https://api.github.com/users/monalisa",
"html_url": "https://github.com/monalisa",
"followers_url": "https://api.github.com/users/monalisa/followers",
"following_url": "https://api.github.com/users/monalisa/following{/other_user}",
"gists_url": "https://api.github.com/users/monalisa/gists{/gist_id}",
"starred_url": "https://api.github.com/users/monalisa/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/monalisa/subscriptions",
"organizations_url": "https://api.github.com/users/monalisa/orgs",
"repos_url": "https://api.github.com/users/monalisa/repos",
"events_url": "https://api.github.com/users/monalisa/events{/privacy}",
"received_events_url": "https://api.github.com/users/monalisa/received_events",
"type": "User",
"site_admin": true
},
"privacy_level": "public",
"tier": {
"node_id": "MDEyOlNwb25zb3JzVGllcjE=",
"created_at": "2019-12-20T19:17:05Z",
"description": "foo",
"monthly_price_in_cents": 500,
"monthly_price_in_dollars": 5,
"name": "$5 a month",
"is_one_time": false,
"is_custom_amount": false
}
},
"sender": {
"login": "monalisa",
"id": 2,
"node_id": "MDQ6VXNlcjI=",
"avatar_url": "https://avatars2.githubusercontent.com/u/2?",
"gravatar_id": "",
"url": "https://api.github.com/users/monalisa",
"html_url": "https://github.com/monalisa",
"followers_url": "https://api.github.com/users/monalisa/followers",
"following_url": "https://api.github.com/users/monalisa/following{/other_user}",
"gists_url": "https://api.github.com/users/monalisa/gists{/gist_id}",
"starred_url": "https://api.github.com/users/monalisa/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/monalisa/subscriptions",
"organizations_url": "https://api.github.com/users/monalisa/orgs",
"repos_url": "https://api.github.com/users/monalisa/repos",
"events_url": "https://api.github.com/users/monalisa/events{/privacy}",
"received_events_url": "https://api.github.com/users/monalisa/received_events",
"type": "User",
"site_admin": true
}
}

View File

@ -0,0 +1,83 @@
{
"action": "edited",
"sponsorship": {
"node_id": "MDExOlNwb25zb3JzaGlwMQ==",
"created_at": "2019-12-20T19:24:46+00:00",
"sponsorable": {
"login": "octocat",
"id": 5,
"node_id": "MDQ6VXNlcjU=",
"avatar_url": "https://avatars2.githubusercontent.com/u/5?",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false
},
"sponsor": {
"login": "monalisa",
"id": 2,
"node_id": "MDQ6VXNlcjI=",
"avatar_url": "https://avatars2.githubusercontent.com/u/2?",
"gravatar_id": "",
"url": "https://api.github.com/users/monalisa",
"html_url": "https://github.com/monalisa",
"followers_url": "https://api.github.com/users/monalisa/followers",
"following_url": "https://api.github.com/users/monalisa/following{/other_user}",
"gists_url": "https://api.github.com/users/monalisa/gists{/gist_id}",
"starred_url": "https://api.github.com/users/monalisa/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/monalisa/subscriptions",
"organizations_url": "https://api.github.com/users/monalisa/orgs",
"repos_url": "https://api.github.com/users/monalisa/repos",
"events_url": "https://api.github.com/users/monalisa/events{/privacy}",
"received_events_url": "https://api.github.com/users/monalisa/received_events",
"type": "User",
"site_admin": true
},
"privacy_level": "private",
"tier": {
"node_id": "MDEyOlNwb25zb3JzVGllcjE=",
"created_at": "2019-12-20T19:17:05Z",
"description": "foo",
"monthly_price_in_cents": 500,
"monthly_price_in_dollars": 5,
"name": "$5 a month",
"is_one_time": false,
"is_custom_amount": false
}
},
"changes": {
"privacy_level": {
"from": "public"
}
},
"sender": {
"login": "monalisa",
"id": 2,
"node_id": "MDQ6VXNlcjI=",
"avatar_url": "https://avatars2.githubusercontent.com/u/2?",
"gravatar_id": "",
"url": "https://api.github.com/users/monalisa",
"html_url": "https://github.com/monalisa",
"followers_url": "https://api.github.com/users/monalisa/followers",
"following_url": "https://api.github.com/users/monalisa/following{/other_user}",
"gists_url": "https://api.github.com/users/monalisa/gists{/gist_id}",
"starred_url": "https://api.github.com/users/monalisa/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/monalisa/subscriptions",
"organizations_url": "https://api.github.com/users/monalisa/orgs",
"repos_url": "https://api.github.com/users/monalisa/repos",
"events_url": "https://api.github.com/users/monalisa/events{/privacy}",
"received_events_url": "https://api.github.com/users/monalisa/received_events",
"type": "User",
"site_admin": true
}
}

View File

@ -0,0 +1,91 @@
{
"action": "pending_cancellation",
"sponsorship": {
"node_id": "MDExOlNwb25zb3JzaGlwMQ==",
"created_at": "2019-12-30T19:24:46+00:00",
"sponsorable": {
"login": "octocat",
"id": 5,
"node_id": "MDQ6VXNlcjU=",
"avatar_url": "https://avatars2.githubusercontent.com/u/5?",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false
},
"sponsor": {
"login": "monalisa",
"id": 2,
"node_id": "MDQ6VXNlcjI=",
"avatar_url": "https://avatars2.githubusercontent.com/u/2?",
"gravatar_id": "",
"url": "https://api.github.com/users/monalisa",
"html_url": "https://github.com/monalisa",
"followers_url": "https://api.github.com/users/monalisa/followers",
"following_url": "https://api.github.com/users/monalisa/following{/other_user}",
"gists_url": "https://api.github.com/users/monalisa/gists{/gist_id}",
"starred_url": "https://api.github.com/users/monalisa/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/monalisa/subscriptions",
"organizations_url": "https://api.github.com/users/monalisa/orgs",
"repos_url": "https://api.github.com/users/monalisa/repos",
"events_url": "https://api.github.com/users/monalisa/events{/privacy}",
"received_events_url": "https://api.github.com/users/monalisa/received_events",
"type": "User",
"site_admin": true
},
"privacy_level": "private",
"tier": {
"node_id": "MDEyOlNwb25zb3JzVGllcjE=",
"created_at": "2019-12-30T19:17:05Z",
"description": "foo",
"monthly_price_in_cents": 500,
"monthly_price_in_dollars": 5,
"name": "$5 a month",
"is_one_time": false,
"is_custom_amount": false
}
},
"changes": {
"tier": {
"from": {
"node_id": "MDEyOlNwb25zb3JzVGllcjI=",
"created_at": "2019-12-30T19:26:26Z",
"description": "bar",
"monthly_price_in_cents": 1000,
"monthly_price_in_dollars": 10,
"name": "$10 a month"
}
}
},
"effective_date": "2020-01-05T00:00:00+00:00",
"sender": {
"login": "monalisa",
"id": 2,
"node_id": "MDQ6VXNlcjI=",
"avatar_url": "https://avatars2.githubusercontent.com/u/2?",
"gravatar_id": "",
"url": "https://api.github.com/users/monalisa",
"html_url": "https://github.com/monalisa",
"followers_url": "https://api.github.com/users/monalisa/followers",
"following_url": "https://api.github.com/users/monalisa/following{/other_user}",
"gists_url": "https://api.github.com/users/monalisa/gists{/gist_id}",
"starred_url": "https://api.github.com/users/monalisa/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/monalisa/subscriptions",
"organizations_url": "https://api.github.com/users/monalisa/orgs",
"repos_url": "https://api.github.com/users/monalisa/repos",
"events_url": "https://api.github.com/users/monalisa/events{/privacy}",
"received_events_url": "https://api.github.com/users/monalisa/received_events",
"type": "User",
"site_admin": true
}
}

View File

@ -0,0 +1,91 @@
{
"action": "pending_tier_change",
"sponsorship": {
"node_id": "MDExOlNwb25zb3JzaGlwMQ==",
"created_at": "2019-12-20T19:24:46+00:00",
"sponsorable": {
"login": "octocat",
"id": 5,
"node_id": "MDQ6VXNlcjU=",
"avatar_url": "https://avatars2.githubusercontent.com/u/5?",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false
},
"sponsor": {
"login": "monalisa",
"id": 2,
"node_id": "MDQ6VXNlcjI=",
"avatar_url": "https://avatars2.githubusercontent.com/u/2?",
"gravatar_id": "",
"url": "https://api.github.com/users/monalisa",
"html_url": "https://github.com/monalisa",
"followers_url": "https://api.github.com/users/monalisa/followers",
"following_url": "https://api.github.com/users/monalisa/following{/other_user}",
"gists_url": "https://api.github.com/users/monalisa/gists{/gist_id}",
"starred_url": "https://api.github.com/users/monalisa/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/monalisa/subscriptions",
"organizations_url": "https://api.github.com/users/monalisa/orgs",
"repos_url": "https://api.github.com/users/monalisa/repos",
"events_url": "https://api.github.com/users/monalisa/events{/privacy}",
"received_events_url": "https://api.github.com/users/monalisa/received_events",
"type": "User",
"site_admin": true
},
"privacy_level": "private",
"tier": {
"node_id": "MDEyOlNwb25zb3JzVGllcjE=",
"created_at": "2019-12-20T19:17:05Z",
"description": "foo",
"monthly_price_in_cents": 500,
"monthly_price_in_dollars": 5,
"name": "$5 a month",
"is_one_time": false,
"is_custom_amount": false
}
},
"changes": {
"tier": {
"from": {
"node_id": "MDEyOlNwb25zb3JzVGllcjI=",
"created_at": "2019-12-20T19:26:26Z",
"description": "bar",
"monthly_price_in_cents": 1000,
"monthly_price_in_dollars": 10,
"name": "$10 a month"
}
}
},
"effective_date": "2019-12-30T00:00:00+00:00",
"sender": {
"login": "monalisa",
"id": 2,
"node_id": "MDQ6VXNlcjI=",
"avatar_url": "https://avatars2.githubusercontent.com/u/2?",
"gravatar_id": "",
"url": "https://api.github.com/users/monalisa",
"html_url": "https://github.com/monalisa",
"followers_url": "https://api.github.com/users/monalisa/followers",
"following_url": "https://api.github.com/users/monalisa/following{/other_user}",
"gists_url": "https://api.github.com/users/monalisa/gists{/gist_id}",
"starred_url": "https://api.github.com/users/monalisa/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/monalisa/subscriptions",
"organizations_url": "https://api.github.com/users/monalisa/orgs",
"repos_url": "https://api.github.com/users/monalisa/repos",
"events_url": "https://api.github.com/users/monalisa/events{/privacy}",
"received_events_url": "https://api.github.com/users/monalisa/received_events",
"type": "User",
"site_admin": true
}
}

View File

@ -0,0 +1,90 @@
{
"action": "tier_changed",
"sponsorship": {
"node_id": "MDExOlNwb25zb3JzaGlwMQ==",
"created_at": "2019-12-30T19:24:46+00:00",
"sponsorable": {
"login": "octocat",
"id": 5,
"node_id": "MDQ6VXNlcjU=",
"avatar_url": "https://avatars2.githubusercontent.com/u/5?",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false
},
"sponsor": {
"login": "monalisa",
"id": 2,
"node_id": "MDQ6VXNlcjI=",
"avatar_url": "https://avatars2.githubusercontent.com/u/2?",
"gravatar_id": "",
"url": "https://api.github.com/users/monalisa",
"html_url": "https://github.com/monalisa",
"followers_url": "https://api.github.com/users/monalisa/followers",
"following_url": "https://api.github.com/users/monalisa/following{/other_user}",
"gists_url": "https://api.github.com/users/monalisa/gists{/gist_id}",
"starred_url": "https://api.github.com/users/monalisa/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/monalisa/subscriptions",
"organizations_url": "https://api.github.com/users/monalisa/orgs",
"repos_url": "https://api.github.com/users/monalisa/repos",
"events_url": "https://api.github.com/users/monalisa/events{/privacy}",
"received_events_url": "https://api.github.com/users/monalisa/received_events",
"type": "User",
"site_admin": true
},
"privacy_level": "private",
"tier": {
"node_id": "MDEyOlNwb25zb3JzVGllcjE=",
"created_at": "2019-12-30T19:17:05Z",
"description": "foo",
"monthly_price_in_cents": 500,
"monthly_price_in_dollars": 5,
"name": "$5 a month",
"is_one_time": false,
"is_custom_amount": false
}
},
"changes": {
"tier": {
"from": {
"node_id": "MDEyOlNwb25zb3JzVGllcjI=",
"created_at": "2019-12-30T19:26:26Z",
"description": "bar",
"monthly_price_in_cents": 1000,
"monthly_price_in_dollars": 10,
"name": "$10 a month"
}
}
},
"sender": {
"login": "monalisa",
"id": 2,
"node_id": "MDQ6VXNlcjI=",
"avatar_url": "https://avatars2.githubusercontent.com/u/2?",
"gravatar_id": "",
"url": "https://api.github.com/users/monalisa",
"html_url": "https://github.com/monalisa",
"followers_url": "https://api.github.com/users/monalisa/followers",
"following_url": "https://api.github.com/users/monalisa/following{/other_user}",
"gists_url": "https://api.github.com/users/monalisa/gists{/gist_id}",
"starred_url": "https://api.github.com/users/monalisa/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/monalisa/subscriptions",
"organizations_url": "https://api.github.com/users/monalisa/orgs",
"repos_url": "https://api.github.com/users/monalisa/repos",
"events_url": "https://api.github.com/users/monalisa/events{/privacy}",
"received_events_url": "https://api.github.com/users/monalisa/received_events",
"type": "User",
"site_admin": true
}
}

View File

@ -0,0 +1,22 @@
Get GitHub Sponsors notifications in Zulip!
1. {!create-stream.md!}
1. {!create-an-incoming-webhook.md!}
1. {!generate-integration-url.md!}
You can refer to GitHub's documentation for [webhook events](https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#sponsorship).
1. Go to your profile on GitHub and click on **Sponsors dashboard**.
Select **Webhooks**. Click on **Add webhook**. GitHub may prompt
you for your password.
1. Set **Payload URL** to the URL constructed above. Set **Content type**
to `application/json` and click **Create webhook**.
{!congrats.md!}
![](/static/images/integrations/githubsponsors/001.png)
See also the [GitHub integration](/integrations/doc/github).

View File

@ -13,6 +13,7 @@ TOPIC_ORGANIZATION = "baxterandthehackers organization"
TOPIC_BRANCH = "public-repo / changes"
TOPIC_WIKI = "public-repo / wiki pages"
TOPIC_DISCUSSION = "testing-gh discussion #20: Lets discuss"
TOPIC_SPONSORS = "sponsors"
class GitHubWebhookTest(WebhookTestCase):
@ -591,3 +592,59 @@ A temporary team so that I can get some webhook fixtures!
def test_discussion_comment_edited_msg(self) -> None:
expected_message = "sbansal1999 edited a [comment](https://github.com/sbansal1999/testing-gh/discussions/20#discussioncomment-6332416) on [discussion #20](https://github.com/sbansal1999/testing-gh/discussions/20):\n\n~~~ quote\nsome random comment edited\n~~~"
self.check_webhook("discussion_comment__edited", TOPIC_DISCUSSION, expected_message)
class GitHubSponsorsHookTests(WebhookTestCase):
STREAM_NAME = "github"
URL_TEMPLATE = "/api/v1/external/githubsponsors?stream={stream}&api_key={api_key}"
WEBHOOK_DIR_NAME = "github"
def test_cancelled_message(self) -> None:
expected_message = "monalisa cancelled their $5 a month subscription."
self.check_webhook(
"cancelled",
TOPIC_SPONSORS,
expected_message,
)
def test_created_message(self) -> None:
expected_message = "monalisa subscribed for $5 a month."
self.check_webhook(
"created",
TOPIC_SPONSORS,
expected_message,
)
def test_pending_cancellation_message(self) -> None:
expected_message = (
"monalisa's $5 a month subscription will be cancelled on January 05, 2020."
)
self.check_webhook(
"pending_cancellation",
TOPIC_SPONSORS,
expected_message,
)
def test_pending_tier_change_message(self) -> None:
expected_message = "monalisa's subscription will change from $10 a month to $5 a month on December 30, 2019."
self.check_webhook(
"pending_tier_change",
TOPIC_SPONSORS,
expected_message,
)
def test_tier_changed_message(self) -> None:
expected_message = "monalisa changed their subscription from $10 a month to $5 a month."
self.check_webhook(
"tier_changed",
TOPIC_SPONSORS,
expected_message,
)
def test_edited_message(self) -> None:
expected_message = "monalisa changed who can see their sponsorship from public to private."
self.check_webhook(
"edited",
TOPIC_SPONSORS,
expected_message,
)

View File

@ -1,4 +1,5 @@
import re
from datetime import datetime, timezone
from typing import Callable, Dict, Optional
from django.http import HttpRequest, HttpResponse
@ -637,6 +638,82 @@ def get_ping_body(helper: Helper) -> str:
return get_setup_webhook_message("GitHub", get_sender_name(payload))
def get_cancelled_body(helper: Helper) -> str:
payload = helper.payload
template = "{user_name} cancelled their {subscription} subscription."
return template.format(
user_name=get_sender_name(payload),
subscription=get_subscription(payload),
).rstrip()
def get_created_body(helper: Helper) -> str:
payload = helper.payload
template = "{user_name} subscribed for {subscription}."
return template.format(
user_name=get_sender_name(payload),
subscription=get_subscription(payload),
).rstrip()
def get_edited_body(helper: Helper) -> str:
payload = helper.payload
template = "{user_name} changed who can see their sponsorship from {prior_privacy_level} to {privacy_level}."
return template.format(
user_name=get_sender_name(payload),
prior_privacy_level=payload["changes"]["privacy_level"]["from"].tame(check_string),
privacy_level=payload["sponsorship"]["privacy_level"].tame(check_string),
).rstrip()
def get_pending_cancellation_body(helper: Helper) -> str:
payload = helper.payload
template = "{user_name}'s {subscription} subscription will be cancelled on {effective_date}."
return template.format(
user_name=get_sender_name(payload),
subscription=get_subscription(payload),
effective_date=get_effective_date(payload),
).rstrip()
def get_pending_tier_change_body(helper: Helper) -> str:
payload = helper.payload
template = "{user_name}'s subscription will change from {prior_subscription} to {subscription} on {effective_date}."
return template.format(
user_name=get_sender_name(payload),
prior_subscription=get_prior_subscription(payload),
subscription=get_subscription(payload),
effective_date=get_effective_date(payload),
).rstrip()
def get_tier_changed_body(helper: Helper) -> str:
payload = helper.payload
template = "{user_name} changed their subscription from {prior_subscription} to {subscription}."
return template.format(
user_name=get_sender_name(payload),
prior_subscription=get_prior_subscription(payload),
subscription=get_subscription(payload),
).rstrip()
def get_subscription(payload: WildValue) -> str:
return payload["sponsorship"]["tier"]["name"].tame(check_string)
def get_effective_date(payload: WildValue) -> str:
effective_date = payload["effective_date"].tame(check_string)[:10]
return (
datetime.strptime(effective_date, "%Y-%m-%d")
.replace(tzinfo=timezone.utc)
.strftime("%B %d, %Y")
)
def get_prior_subscription(payload: WildValue) -> str:
return payload["changes"]["tier"]["from"]["name"].tame(check_string)
def get_repository_name(payload: WildValue) -> str:
return payload["repository"]["name"].tame(check_string)
@ -728,6 +805,8 @@ def get_topic_based_on_type(payload: WildValue, event: str) -> str:
number=payload["discussion"]["number"].tame(check_int),
title=payload["discussion"]["title"].tame(check_string),
)
elif event in SPONSORS_EVENT_TYPES:
return "sponsors"
return get_repository_name(payload)
@ -770,8 +849,23 @@ EVENT_FUNCTION_MAPPER: Dict[str, Callable[[Helper], str]] = {
"team": get_team_body,
"team_add": get_add_team_body,
"watch": get_watch_body,
"cancelled": get_cancelled_body,
"created": get_created_body,
"edited": get_edited_body,
"pending_cancellation": get_pending_cancellation_body,
"pending_tier_change": get_pending_tier_change_body,
"tier_changed": get_tier_changed_body,
}
SPONSORS_EVENT_TYPES = [
"cancelled",
"created",
"edited",
"pending_cancellation",
"pending_tier_change",
"tier_changed",
]
IGNORED_EVENTS = [
"check_suite",
"label",