webhooks: Use partial with positional arguments.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2024-04-29 14:52:26 -07:00 committed by Tim Abbott
parent 04638ffaee
commit 6fef5c3e46
7 changed files with 102 additions and 116 deletions

View File

@ -312,11 +312,11 @@ def get_issue_commented_body(request: HttpRequest, payload: WildValue, include_t
action = "[commented]({}) on".format(
payload["comment"]["links"]["html"]["href"].tame(check_string)
)
return get_issue_action_body(request, payload, action, include_title)
return get_issue_action_body(action, request, payload, include_title)
def get_issue_action_body(
request: HttpRequest, payload: WildValue, action: str, include_title: bool
action: str, request: HttpRequest, payload: WildValue, include_title: bool
) -> str:
issue = payload["issue"]
assignee = None
@ -338,7 +338,7 @@ def get_issue_action_body(
def get_pull_request_action_body(
request: HttpRequest, payload: WildValue, action: str, include_title: bool
action: str, request: HttpRequest, payload: WildValue, include_title: bool
) -> str:
pull_request = payload["pullrequest"]
target_branch = None
@ -359,7 +359,7 @@ def get_pull_request_action_body(
def get_pull_request_created_or_updated_body(
request: HttpRequest, payload: WildValue, action: str, include_title: bool
action: str, request: HttpRequest, payload: WildValue, include_title: bool
) -> str:
pull_request = payload["pullrequest"]
assignee = None
@ -399,9 +399,9 @@ def get_pull_request_comment_created_action_body(
def get_pull_request_deleted_or_updated_comment_action_body(
action: str,
request: HttpRequest,
payload: WildValue,
action: str,
include_title: bool,
) -> str:
action = "{} a [comment]({})".format(
@ -538,21 +538,21 @@ GET_SINGLE_MESSAGE_BODY_DEPENDING_ON_TYPE_MAPPER: Dict[str, BodyGetter] = {
"fork": get_fork_body,
"commit_comment": get_commit_comment_body,
"change_commit_status": get_commit_status_changed_body,
"issue_updated": partial(get_issue_action_body, action="updated"),
"issue_created": partial(get_issue_action_body, action="created"),
"issue_updated": partial(get_issue_action_body, "updated"),
"issue_created": partial(get_issue_action_body, "created"),
"issue_commented": get_issue_commented_body,
"pull_request_created": partial(get_pull_request_created_or_updated_body, action="created"),
"pull_request_updated": partial(get_pull_request_created_or_updated_body, action="updated"),
"pull_request_approved": partial(get_pull_request_action_body, action="approved"),
"pull_request_unapproved": partial(get_pull_request_action_body, action="unapproved"),
"pull_request_fulfilled": partial(get_pull_request_action_body, action="merged"),
"pull_request_rejected": partial(get_pull_request_action_body, action="rejected"),
"pull_request_created": partial(get_pull_request_created_or_updated_body, "created"),
"pull_request_updated": partial(get_pull_request_created_or_updated_body, "updated"),
"pull_request_approved": partial(get_pull_request_action_body, "approved"),
"pull_request_unapproved": partial(get_pull_request_action_body, "unapproved"),
"pull_request_fulfilled": partial(get_pull_request_action_body, "merged"),
"pull_request_rejected": partial(get_pull_request_action_body, "rejected"),
"pull_request_comment_created": get_pull_request_comment_created_action_body,
"pull_request_comment_updated": partial(
get_pull_request_deleted_or_updated_comment_action_body, action="updated"
get_pull_request_deleted_or_updated_comment_action_body, "updated"
),
"pull_request_comment_deleted": partial(
get_pull_request_deleted_or_updated_comment_action_body, action="deleted"
get_pull_request_deleted_or_updated_comment_action_body, "deleted"
),
"repo:updated": get_repo_updated_body,
}

View File

@ -84,8 +84,8 @@ def ping_handler(
def repo_comment_handler(
payload: WildValue,
action: str,
payload: WildValue,
branches: Optional[str],
include_title: Optional[str],
) -> List[Dict[str, str]]:
@ -336,8 +336,8 @@ def get_pr_reassigned_body(payload: WildValue, include_title: Optional[str]) ->
def pr_handler(
payload: WildValue,
action: str,
payload: WildValue,
branches: Optional[str],
include_title: Optional[str],
) -> List[Dict[str, str]]:
@ -363,8 +363,8 @@ def pr_handler(
def pr_comment_handler(
payload: WildValue,
action: str,
payload: WildValue,
branches: Optional[str],
include_title: Optional[str],
) -> List[Dict[str, str]]:
@ -398,24 +398,24 @@ class EventHandler(Protocol):
EVENT_HANDLER_MAP: Dict[str, EventHandler] = {
"diagnostics:ping": ping_handler,
"repo:comment:added": partial(repo_comment_handler, action="commented"),
"repo:comment:edited": partial(repo_comment_handler, action="edited their comment"),
"repo:comment:deleted": partial(repo_comment_handler, action="deleted their comment"),
"repo:comment:added": partial(repo_comment_handler, "commented"),
"repo:comment:edited": partial(repo_comment_handler, "edited their comment"),
"repo:comment:deleted": partial(repo_comment_handler, "deleted their comment"),
"repo:forked": repo_forked_handler,
"repo:modified": repo_modified_handler,
"repo:refs_changed": repo_push_handler,
"pr:comment:added": partial(pr_comment_handler, action="commented on"),
"pr:comment:edited": partial(pr_comment_handler, action="edited their comment on"),
"pr:comment:deleted": partial(pr_comment_handler, action="deleted their comment on"),
"pr:declined": partial(pr_handler, action="declined"),
"pr:deleted": partial(pr_handler, action="deleted"),
"pr:merged": partial(pr_handler, action="merged"),
"pr:modified": partial(pr_handler, action="modified"),
"pr:opened": partial(pr_handler, action="opened"),
"pr:reviewer:approved": partial(pr_handler, action="approved"),
"pr:reviewer:needs_work": partial(pr_handler, action="needs_work"),
"pr:reviewer:updated": partial(pr_handler, action="reviewers_updated"),
"pr:reviewer:unapproved": partial(pr_handler, action="unapproved"),
"pr:comment:added": partial(pr_comment_handler, "commented on"),
"pr:comment:edited": partial(pr_comment_handler, "edited their comment on"),
"pr:comment:deleted": partial(pr_comment_handler, "deleted their comment on"),
"pr:declined": partial(pr_handler, "declined"),
"pr:deleted": partial(pr_handler, "deleted"),
"pr:merged": partial(pr_handler, "merged"),
"pr:modified": partial(pr_handler, "modified"),
"pr:opened": partial(pr_handler, "opened"),
"pr:reviewer:approved": partial(pr_handler, "approved"),
"pr:reviewer:needs_work": partial(pr_handler, "needs_work"),
"pr:reviewer:updated": partial(pr_handler, "reviewers_updated"),
"pr:reviewer:unapproved": partial(pr_handler, "unapproved"),
}
ALL_EVENT_TYPES = list(EVENT_HANDLER_MAP.keys())

View File

@ -172,7 +172,7 @@ def get_epic_create_body(payload: WildValue, action: WildValue) -> str:
)
def get_comment_added_body(payload: WildValue, action: WildValue, entity: str) -> str:
def get_comment_added_body(entity: str, payload: WildValue, action: WildValue) -> str:
actions = payload["actions"]
kwargs = {"entity": entity}
for action in actions:
@ -188,7 +188,7 @@ def get_comment_added_body(payload: WildValue, action: WildValue, entity: str) -
return COMMENT_ADDED_TEMPLATE.format(**kwargs)
def get_update_description_body(payload: WildValue, action: WildValue, entity: str) -> str:
def get_update_description_body(entity: str, payload: WildValue, action: WildValue) -> str:
desc = action["changes"]["description"]
kwargs = {
@ -249,7 +249,7 @@ def get_story_update_state_body(payload: WildValue, action: WildValue) -> str:
return STATE_CHANGED_TEMPLATE.format(**kwargs)
def get_update_name_body(payload: WildValue, action: WildValue, entity: str) -> str:
def get_update_name_body(entity: str, payload: WildValue, action: WildValue) -> str:
name = action["changes"]["name"]
kwargs = {
"entity": entity,
@ -264,7 +264,7 @@ def get_update_name_body(payload: WildValue, action: WildValue, entity: str) ->
return NAME_CHANGED_TEMPLATE.format(**kwargs)
def get_update_archived_body(payload: WildValue, action: WildValue, entity: str) -> str:
def get_update_archived_body(entity: str, payload: WildValue, action: WildValue) -> str:
archived = action["changes"]["archived"]
if archived["new"]:
operation = "archived"
@ -283,7 +283,7 @@ def get_update_archived_body(payload: WildValue, action: WildValue, entity: str)
return ARCHIVED_TEMPLATE.format(**kwargs)
def get_story_task_body(payload: WildValue, action: WildValue, operation: str) -> str:
def get_story_task_body(operation: str, payload: WildValue, action: WildValue) -> str:
kwargs = {
"task_description": action["description"].tame(check_string),
"operation": operation,
@ -381,7 +381,7 @@ def get_reference_by_id(payload: WildValue, ref_id: Optional[int]) -> Optional[W
def get_secondary_actions_with_param(
payload: WildValue, entity: str, changed_attr: str
entity: str, changed_attr: str, payload: WildValue
) -> Iterator[WildValue]:
# This function is a generator for secondary actions that have the required changed attributes,
# i.e.: "story" that has "pull-request_ids" changed.
@ -390,7 +390,7 @@ def get_secondary_actions_with_param(
yield action
def get_story_create_github_entity_body(payload: WildValue, action: WildValue, entity: str) -> str:
def get_story_create_github_entity_body(entity: str, payload: WildValue, action: WildValue) -> str:
pull_request_action: WildValue = get_action_with_primary_id(payload)
kwargs = {
@ -662,9 +662,7 @@ def get_story_update_batch_body(payload: WildValue, action: WildValue) -> Option
return STORY_UPDATE_BATCH_TEMPLATE.format(**kwargs)
def get_entity_name(
payload: WildValue, action: WildValue, entity: Optional[str] = None
) -> Optional[str]:
def get_entity_name(entity: str, payload: WildValue, action: WildValue) -> Optional[str]:
name = action["name"].tame(check_string) if "name" in action else None
if name is None or action["entity_type"] == "branch":
@ -706,18 +704,16 @@ def send_stream_messages_for_actions(
EVENT_BODY_FUNCTION_MAPPER: Dict[str, Callable[[WildValue, WildValue], Optional[str]]] = {
"story_update_archived": partial(get_update_archived_body, entity="story"),
"epic_update_archived": partial(get_update_archived_body, entity="epic"),
"story_update_archived": partial(get_update_archived_body, "story"),
"epic_update_archived": partial(get_update_archived_body, "epic"),
"story_create": get_story_create_body,
"pull-request_create": partial(get_story_create_github_entity_body, entity="pull-request"),
"pull-request_comment": partial(
get_story_create_github_entity_body, entity="pull-request-comment"
),
"branch_create": partial(get_story_create_github_entity_body, entity="branch"),
"pull-request_create": partial(get_story_create_github_entity_body, "pull-request"),
"pull-request_comment": partial(get_story_create_github_entity_body, "pull-request-comment"),
"branch_create": partial(get_story_create_github_entity_body, "branch"),
"story_delete": get_delete_body,
"epic_delete": get_delete_body,
"story-task_create": partial(get_story_task_body, operation="added to"),
"story-task_delete": partial(get_story_task_body, operation="removed from"),
"story-task_create": partial(get_story_task_body, "added to"),
"story-task_delete": partial(get_story_task_body, "removed from"),
"story-task_update_complete": get_story_task_completed_body,
"story_update_epic": get_story_update_epic_body,
"story_update_estimate": get_story_update_estimate_body,
@ -727,27 +723,27 @@ EVENT_BODY_FUNCTION_MAPPER: Dict[str, Callable[[WildValue, WildValue], Optional[
"story_update_project": get_story_update_project_body,
"story_update_type": get_story_update_type_body,
"epic_create": get_epic_create_body,
"epic-comment_create": partial(get_comment_added_body, entity="epic"),
"story-comment_create": partial(get_comment_added_body, entity="story"),
"epic_update_description": partial(get_update_description_body, entity="epic"),
"story_update_description": partial(get_update_description_body, entity="story"),
"epic-comment_create": partial(get_comment_added_body, "epic"),
"story-comment_create": partial(get_comment_added_body, "story"),
"epic_update_description": partial(get_update_description_body, "epic"),
"story_update_description": partial(get_update_description_body, "story"),
"epic_update_state": get_epic_update_state_body,
"story_update_state": get_story_update_state_body,
"epic_update_name": partial(get_update_name_body, entity="epic"),
"story_update_name": partial(get_update_name_body, entity="story"),
"epic_update_name": partial(get_update_name_body, "epic"),
"story_update_name": partial(get_update_name_body, "story"),
"story_update_batch": get_story_update_batch_body,
}
ALL_EVENT_TYPES = list(EVENT_BODY_FUNCTION_MAPPER.keys())
EVENT_TOPIC_FUNCTION_MAPPER: Dict[str, Callable[[WildValue, WildValue], Optional[str]]] = {
"story": partial(get_entity_name, entity="story"),
"pull-request": partial(get_entity_name, entity="story"),
"branch": partial(get_entity_name, entity="story"),
"story-comment": partial(get_entity_name, entity="story"),
"story-task": partial(get_entity_name, entity="story"),
"epic": partial(get_entity_name, entity="epic"),
"epic-comment": partial(get_entity_name, entity="epic"),
"story": partial(get_entity_name, "story"),
"pull-request": partial(get_entity_name, "story"),
"branch": partial(get_entity_name, "story"),
"story-comment": partial(get_entity_name, "story"),
"story-task": partial(get_entity_name, "story"),
"epic": partial(get_entity_name, "epic"),
"epic-comment": partial(get_entity_name, "epic"),
}
IGNORED_EVENTS = {
@ -755,15 +751,9 @@ IGNORED_EVENTS = {
}
EVENTS_SECONDARY_ACTIONS_FUNCTION_MAPPER: Dict[str, Callable[[WildValue], Iterator[WildValue]]] = {
"pull-request_create": partial(
get_secondary_actions_with_param, entity="story", changed_attr="pull_request_ids"
),
"branch_create": partial(
get_secondary_actions_with_param, entity="story", changed_attr="branch_ids"
),
"pull-request_comment": partial(
get_secondary_actions_with_param, entity="story", changed_attr="pull_request_ids"
),
"pull-request_create": partial(get_secondary_actions_with_param, "story", "pull_request_ids"),
"branch_create": partial(get_secondary_actions_with_param, "story", "branch_ids"),
"pull-request_comment": partial(get_secondary_actions_with_param, "story", "pull_request_ids"),
}

View File

@ -251,7 +251,7 @@ def get_change_deployment_status_body(helper: Helper) -> str:
)
def get_create_or_delete_body(helper: Helper, action: str) -> str:
def get_create_or_delete_body(action: str, helper: Helper) -> str:
payload = helper.payload
ref_type = payload["ref_type"].tame(check_string)
return "{} {} {} {}.".format(
@ -814,9 +814,9 @@ def get_topic_based_on_type(payload: WildValue, event: str) -> str:
EVENT_FUNCTION_MAPPER: Dict[str, Callable[[Helper], str]] = {
"commit_comment": get_commit_comment_body,
"closed_pull_request": get_closed_pull_request_body,
"create": partial(get_create_or_delete_body, action="created"),
"create": partial(get_create_or_delete_body, "created"),
"check_run": get_check_run_body,
"delete": partial(get_create_or_delete_body, action="deleted"),
"delete": partial(get_create_or_delete_body, "deleted"),
"deployment": get_deployment_body,
"deployment_status": get_change_deployment_status_body,
"discussion": get_discussion_body,

View File

@ -109,7 +109,7 @@ def get_issue_created_event_body(payload: WildValue, include_title: bool) -> str
)
def get_issue_event_body(payload: WildValue, action: str, include_title: bool) -> str:
def get_issue_event_body(action: str, payload: WildValue, include_title: bool) -> str:
return get_issue_event_message(
user_name=get_issue_user_name(payload),
action=action,
@ -122,19 +122,19 @@ def get_issue_event_body(payload: WildValue, action: str, include_title: bool) -
def get_merge_request_updated_event_body(payload: WildValue, include_title: bool) -> str:
if payload["object_attributes"].get("oldrev"):
return get_merge_request_event_body(
payload,
"added commit(s) to",
payload,
include_title=include_title,
)
return get_merge_request_open_or_updated_body(
payload,
"updated",
payload,
include_title=include_title,
)
def get_merge_request_event_body(payload: WildValue, action: str, include_title: bool) -> str:
def get_merge_request_event_body(action: str, payload: WildValue, include_title: bool) -> str:
pull_request = payload["object_attributes"]
target_branch = None
base_branch = None
@ -155,7 +155,7 @@ def get_merge_request_event_body(payload: WildValue, action: str, include_title:
def get_merge_request_open_or_updated_body(
payload: WildValue, action: str, include_title: bool
action: str, payload: WildValue, include_title: bool
) -> str:
pull_request = payload["object_attributes"]
return get_pull_request_event_message(
@ -272,7 +272,7 @@ def get_commented_snippet_event_body(payload: WildValue, include_title: bool) ->
)
def get_wiki_page_event_body(payload: WildValue, action: str, include_title: bool) -> str:
def get_wiki_page_event_body(action: str, payload: WildValue, include_title: bool) -> str:
return '{} {} [wiki page "{}"]({}).'.format(
get_issue_user_name(payload),
action,
@ -387,27 +387,27 @@ EVENT_FUNCTION_MAPPER: Dict[str, EventFunction] = {
"Tag Push Hook": get_tag_push_event_body,
"Test Hook": get_test_event_body,
"Issue Hook open": get_issue_created_event_body,
"Issue Hook close": partial(get_issue_event_body, action="closed"),
"Issue Hook reopen": partial(get_issue_event_body, action="reopened"),
"Issue Hook update": partial(get_issue_event_body, action="updated"),
"Issue Hook close": partial(get_issue_event_body, "closed"),
"Issue Hook reopen": partial(get_issue_event_body, "reopened"),
"Issue Hook update": partial(get_issue_event_body, "updated"),
"Confidential Issue Hook open": get_issue_created_event_body,
"Confidential Issue Hook close": partial(get_issue_event_body, action="closed"),
"Confidential Issue Hook reopen": partial(get_issue_event_body, action="reopened"),
"Confidential Issue Hook update": partial(get_issue_event_body, action="updated"),
"Confidential Issue Hook close": partial(get_issue_event_body, "closed"),
"Confidential Issue Hook reopen": partial(get_issue_event_body, "reopened"),
"Confidential Issue Hook update": partial(get_issue_event_body, "updated"),
"Note Hook Commit": get_commented_commit_event_body,
"Note Hook MergeRequest": get_commented_merge_request_event_body,
"Note Hook Issue": get_commented_issue_event_body,
"Confidential Note Hook Issue": get_commented_issue_event_body,
"Note Hook Snippet": get_commented_snippet_event_body,
"Merge Request Hook approved": partial(get_merge_request_event_body, action="approved"),
"Merge Request Hook unapproved": partial(get_merge_request_event_body, action="unapproved"),
"Merge Request Hook open": partial(get_merge_request_open_or_updated_body, action="created"),
"Merge Request Hook approved": partial(get_merge_request_event_body, "approved"),
"Merge Request Hook unapproved": partial(get_merge_request_event_body, "unapproved"),
"Merge Request Hook open": partial(get_merge_request_open_or_updated_body, "created"),
"Merge Request Hook update": get_merge_request_updated_event_body,
"Merge Request Hook merge": partial(get_merge_request_event_body, action="merged"),
"Merge Request Hook close": partial(get_merge_request_event_body, action="closed"),
"Merge Request Hook reopen": partial(get_merge_request_event_body, action="reopened"),
"Wiki Page Hook create": partial(get_wiki_page_event_body, action="created"),
"Wiki Page Hook update": partial(get_wiki_page_event_body, action="updated"),
"Merge Request Hook merge": partial(get_merge_request_event_body, "merged"),
"Merge Request Hook close": partial(get_merge_request_event_body, "closed"),
"Merge Request Hook reopen": partial(get_merge_request_event_body, "reopened"),
"Wiki Page Hook create": partial(get_wiki_page_event_body, "created"),
"Wiki Page Hook update": partial(get_wiki_page_event_body, "updated"),
"Job Hook": get_build_hook_event_body,
"Build Hook": get_build_hook_event_body,
"Pipeline Hook": get_pipeline_event_body,

View File

@ -70,7 +70,7 @@ def ticket_assigned_body(payload: WildValue) -> Optional[str]:
return None
def replied_body(payload: WildValue, actor: str, action: str) -> str:
def replied_body(actor: str, action: str, payload: WildValue) -> str:
actor_url = "http://api.groovehq.com/v1/{}/".format(actor + "s")
actor = payload["links"]["author"]["href"].tame(check_url).split(actor_url)[1]
number = (
@ -93,9 +93,9 @@ def replied_body(payload: WildValue, actor: str, action: str) -> str:
EVENTS_FUNCTION_MAPPER: Dict[str, Callable[[WildValue], Optional[str]]] = {
"ticket_started": ticket_started_body,
"ticket_assigned": ticket_assigned_body,
"agent_replied": partial(replied_body, actor="agent", action="replied to"),
"customer_replied": partial(replied_body, actor="customer", action="replied to"),
"note_added": partial(replied_body, actor="agent", action="left a note on"),
"agent_replied": partial(replied_body, "agent", "replied to"),
"customer_replied": partial(replied_body, "customer", "replied to"),
"note_added": partial(replied_body, "agent", "left a note on"),
}
ALL_EVENT_TYPES = list(EVENTS_FUNCTION_MAPPER.keys())

View File

@ -173,8 +173,8 @@ def get_conversation_admin_assigned_message(payload: WildValue) -> Tuple[str, st
def get_conversation_admin_message(
payload: WildValue,
action: str,
payload: WildValue,
) -> Tuple[str, str]:
assignee = payload["data"]["item"]["assignee"]
user = payload["data"]["item"]["user"]
@ -187,8 +187,8 @@ def get_conversation_admin_message(
def get_conversation_admin_reply_message(
payload: WildValue,
action: str,
payload: WildValue,
) -> Tuple[str, str]:
assignee = payload["data"]["item"]["assignee"]
user = payload["data"]["item"]["user"]
@ -270,8 +270,8 @@ def get_user_email_updated_message(payload: WildValue) -> Tuple[str, str]:
def get_user_tagged_message(
payload: WildValue,
action: str,
payload: WildValue,
) -> Tuple[str, str]:
user = payload["data"]["item"]["user"]
tag = payload["data"]["item"]["tag"]
@ -298,16 +298,12 @@ EVENT_TO_FUNCTION_MAPPER: Dict[str, Callable[[WildValue], Tuple[str, str]]] = {
"contact.tag.created": get_contact_tag_created_message,
"contact.tag.deleted": get_contact_tag_deleted_message,
"conversation.admin.assigned": get_conversation_admin_assigned_message,
"conversation.admin.closed": partial(get_conversation_admin_message, action="closed"),
"conversation.admin.opened": partial(get_conversation_admin_message, action="opened"),
"conversation.admin.snoozed": partial(get_conversation_admin_message, action="snoozed"),
"conversation.admin.unsnoozed": partial(get_conversation_admin_message, action="unsnoozed"),
"conversation.admin.replied": partial(
get_conversation_admin_reply_message, action="replied to"
),
"conversation.admin.noted": partial(
get_conversation_admin_reply_message, action="added a note to"
),
"conversation.admin.closed": partial(get_conversation_admin_message, "closed"),
"conversation.admin.opened": partial(get_conversation_admin_message, "opened"),
"conversation.admin.snoozed": partial(get_conversation_admin_message, "snoozed"),
"conversation.admin.unsnoozed": partial(get_conversation_admin_message, "unsnoozed"),
"conversation.admin.replied": partial(get_conversation_admin_reply_message, "replied to"),
"conversation.admin.noted": partial(get_conversation_admin_reply_message, "added a note to"),
"conversation.admin.single.created": get_conversation_admin_single_created_message,
"conversation.user.created": get_conversation_user_created_message,
"conversation.user.replied": get_conversation_user_replied_message,
@ -315,8 +311,8 @@ EVENT_TO_FUNCTION_MAPPER: Dict[str, Callable[[WildValue], Tuple[str, str]]] = {
"user.created": get_user_created_message,
"user.deleted": get_user_deleted_message,
"user.email.updated": get_user_email_updated_message,
"user.tag.created": partial(get_user_tagged_message, action="added to"),
"user.tag.deleted": partial(get_user_tagged_message, action="removed from"),
"user.tag.created": partial(get_user_tagged_message, "added to"),
"user.tag.deleted": partial(get_user_tagged_message, "removed from"),
"user.unsubscribed": get_user_unsubscribed_message,
# Note that we do not have a payload for visitor.signed_up
# but it should be identical to contact.signed_up