def build_actions( group: Group, project: Project, text: str, color: str, actions: Sequence[MessageAction] | None = None, identity: Identity | None = None, ) -> tuple[Sequence[MessageAction], str, str]: """Having actions means a button will be shown on the Slack message e.g. ignore, resolve, assign.""" if actions: text += get_action_text(text, actions, identity) return [], text, "_actioned_issue" ignore_button = MessageAction( name="status", label="Ignore", value="ignored", ) resolve_button = MessageAction( name="resolve_dialog", label="Resolve...", value="resolve_dialog", ) status = group.get_status() if not has_releases(project): resolve_button = MessageAction( name="status", label="Resolve", value="resolved", ) if status == GroupStatus.RESOLVED: resolve_button = MessageAction( name="status", label="Unresolve", value="unresolved", ) if status == GroupStatus.IGNORED: ignore_button = MessageAction( name="status", label="Stop Ignoring", value="unresolved", ) assignee = group.get_assignee() assign_button = MessageAction( name="assign", label="Select Assignee...", type="select", selected_options=format_actor_options([assignee]) if assignee else [], option_groups=get_option_groups(group), ) return [resolve_button, ignore_button, assign_button], text, color
def build_actions( group: Group, project: Project, text: str, color: str, actions: Optional[Sequence[Any]] = None, identity: Optional[Identity] = None, ) -> Tuple[Sequence[Any], str, str]: """ Having actions means a button will be shown on the Slack message e.g. ignore, resolve, assign """ status = group.get_status() members = get_member_assignees(group) teams = get_team_assignees(group) if actions is None: actions = [] assignee = get_assignee(group) resolve_button = { "name": "resolve_dialog", "value": "resolve_dialog", "type": "button", "text": "Resolve...", } ignore_button = { "name": "status", "value": "ignored", "type": "button", "text": "Ignore" } cache_key = "has_releases:2:%s" % project.id has_releases = cache.get(cache_key) if has_releases is None: has_releases = ReleaseProject.objects.filter( project_id=project.id).exists() if has_releases: cache.set(cache_key, True, 3600) else: cache.set(cache_key, False, 60) if not has_releases: resolve_button.update({ "name": "status", "text": "Resolve", "value": "resolved" }) if status == GroupStatus.RESOLVED: resolve_button.update({ "name": "status", "text": "Unresolve", "value": "unresolved" }) if status == GroupStatus.IGNORED: ignore_button.update({"text": "Stop Ignoring", "value": "unresolved"}) option_groups = [] if teams: option_groups.append({"text": "Teams", "options": teams}) if members: option_groups.append({"text": "People", "options": members}) payload_actions = [ resolve_button, ignore_button, { "name": "assign", "text": "Select Assignee...", "type": "select", "selected_options": [assignee], "option_groups": option_groups, }, ] if actions: action_texts = [ _f for _f in [build_action_text(group, identity, a) for a in actions] if _f ] text += "\n" + "\n".join(action_texts) color = "_actioned_issue" payload_actions = [] return payload_actions, text, color
def build_group_attachment( group: Group, event=None, tags: Mapping[str, str] = None, identity: Identity = None, actions=None, rules: List[Rule] = None, link_to_event: bool = False, ): # XXX(dcramer): options are limited to 100 choices, even when nested status = group.get_status() members = get_member_assignees(group) teams = get_team_assignees(group) logo_url = absolute_uri(get_asset_url("sentry", "images/sentry-email-avatar.png")) text = build_attachment_text(group, event) or "" if actions is None: actions = [] assignee = get_assignee(group) resolve_button = { "name": "resolve_dialog", "value": "resolve_dialog", "type": "button", "text": "Resolve...", } ignore_button = {"name": "status", "value": "ignored", "type": "button", "text": "Ignore"} project = Project.objects.get_from_cache(id=group.project_id) cache_key = "has_releases:2:%s" % (project.id) has_releases = cache.get(cache_key) if has_releases is None: has_releases = ReleaseProject.objects.filter(project_id=project.id).exists() if has_releases: cache.set(cache_key, True, 3600) else: cache.set(cache_key, False, 60) if not has_releases: resolve_button.update({"name": "status", "text": "Resolve", "value": "resolved"}) if status == GroupStatus.RESOLVED: resolve_button.update({"name": "status", "text": "Unresolve", "value": "unresolved"}) if status == GroupStatus.IGNORED: ignore_button.update({"text": "Stop Ignoring", "value": "unresolved"}) option_groups = [] if teams: option_groups.append({"text": "Teams", "options": teams}) if members: option_groups.append({"text": "People", "options": members}) payload_actions = [ resolve_button, ignore_button, { "name": "assign", "text": "Select Assignee...", "type": "select", "selected_options": [assignee], "option_groups": option_groups, }, ] # If an event is unspecified, use the tags of the latest event (if one exists). event_for_tags = event if event else group.get_latest_event() fallback_color = LEVEL_TO_COLOR["error"] color = ( LEVEL_TO_COLOR.get(event_for_tags.get_tag("level"), fallback_color) if event_for_tags else fallback_color ) fields = [] if tags: event_tags = event_for_tags.tags if event_for_tags else [] for key, value in event_tags: std_key = tagstore.get_standardized_key(key) if std_key not in tags: continue labeled_value = tagstore.get_tag_value_label(key, value) fields.append( { "title": std_key.encode("utf-8"), "value": labeled_value.encode("utf-8"), "short": True, } ) if actions: action_texts = [_f for _f in [build_action_text(group, identity, a) for a in actions] if _f] text += "\n" + "\n".join(action_texts) color = ACTIONED_ISSUE_COLOR payload_actions = [] ts = group.last_seen if event: event_ts = event.datetime ts = max(ts, event_ts) footer = f"{group.qualified_short_id}" if rules: rule_url = build_rule_url(rules[0], group, project) footer += f" via <{rule_url}|{rules[0].label}>" if len(rules) > 1: footer += f" (+{len(rules) - 1} other)" obj = event if event is not None else group if event and link_to_event: title_link = group.get_absolute_url(params={"referrer": "slack"}, event_id=event.event_id) else: title_link = group.get_absolute_url(params={"referrer": "slack"}) return { "fallback": f"[{project.slug}] {obj.title}", "title": build_attachment_title(obj), "title_link": title_link, "text": text, "fields": fields, "mrkdwn_in": ["text"], "callback_id": json.dumps({"issue": group.id}), "footer_icon": logo_url, "footer": footer, "ts": to_timestamp(ts), "color": color, "actions": payload_actions, }