mirror of
https://github.com/zulip/zulip.git
synced 2025-11-15 03:11:54 +00:00
slack_incoming: Support "fields" in "section"s.
This is a best-effort rendering of the "fields" of Slack incoming hooks, which Slack renders in two columns. We approximate them in a Markdown table, with some minor in-place replacements. Fixes #22228.
This commit is contained in:
committed by
Tim Abbott
parent
4dc57dadd6
commit
1b692984ce
@@ -74,6 +74,9 @@ Danny Torrence left the following *review* for your property:
|
|||||||
[Overlook Hotel](https://google.com) \n :star: \n Doors had too many axe holes, guest in room 237 was far too rowdy, whole place felt stuck in the 1920s.
|
[Overlook Hotel](https://google.com) \n :star: \n Doors had too many axe holes, guest in room 237 was far too rowdy, whole place felt stuck in the 1920s.
|
||||||
|
|
||||||
[Haunted hotel image](https://is5-ssl.mzstatic.com/image/thumb/Purple3/v4/d3/72/5c/d3725c8f-c642-5d69-1904-aa36e4297885/source/256x256bb.jpg)
|
[Haunted hotel image](https://is5-ssl.mzstatic.com/image/thumb/Purple3/v4/d3/72/5c/d3725c8f-c642-5d69-1904-aa36e4297885/source/256x256bb.jpg)
|
||||||
|
|
||||||
|
**Average Rating**
|
||||||
|
1.0
|
||||||
""".strip()
|
""".strip()
|
||||||
|
|
||||||
self.check_webhook(
|
self.check_webhook(
|
||||||
@@ -90,6 +93,9 @@ Danny Torrence left the following review for your property:
|
|||||||
[Overlook Hotel](https://example.com) \n :star: \n Doors had too many axe holes, guest in room 237 was far too rowdy, whole place felt stuck in the 1920s.
|
[Overlook Hotel](https://example.com) \n :star: \n Doors had too many axe holes, guest in room 237 was far too rowdy, whole place felt stuck in the 1920s.
|
||||||
|
|
||||||
[Haunted hotel image](https://is5-ssl.mzstatic.com/image/thumb/Purple3/v4/d3/72/5c/d3725c8f-c642-5d69-1904-aa36e4297885/source/256x256bb.jpg)
|
[Haunted hotel image](https://is5-ssl.mzstatic.com/image/thumb/Purple3/v4/d3/72/5c/d3725c8f-c642-5d69-1904-aa36e4297885/source/256x256bb.jpg)
|
||||||
|
|
||||||
|
**Average Rating**
|
||||||
|
1.0
|
||||||
""".strip()
|
""".strip()
|
||||||
|
|
||||||
self.check_webhook(
|
self.check_webhook(
|
||||||
@@ -175,6 +181,12 @@ This is a section block with an accessory image.
|
|||||||
[cute cat](https://pbs.twimg.com/profile_images/625633822235693056/lNGUneLX_400x400.jpg)
|
[cute cat](https://pbs.twimg.com/profile_images/625633822235693056/lNGUneLX_400x400.jpg)
|
||||||
|
|
||||||
This is a section block with a button.
|
This is a section block with a button.
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|-|-|
|
||||||
|
| one | two |
|
||||||
|
| three | four |
|
||||||
|
| five | |
|
||||||
""".strip()
|
""".strip()
|
||||||
|
|
||||||
self.check_webhook(
|
self.check_webhook(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
# Webhooks for external integrations.
|
# Webhooks for external integrations.
|
||||||
import re
|
import re
|
||||||
|
from itertools import zip_longest
|
||||||
from typing import Literal, Optional, TypedDict, cast
|
from typing import Literal, Optional, TypedDict, cast
|
||||||
|
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
@@ -14,6 +15,7 @@ from zerver.lib.validator import (
|
|||||||
WildValue,
|
WildValue,
|
||||||
check_dict,
|
check_dict,
|
||||||
check_int,
|
check_int,
|
||||||
|
check_list,
|
||||||
check_string,
|
check_string,
|
||||||
check_string_in,
|
check_string_in,
|
||||||
check_url,
|
check_url,
|
||||||
@@ -122,11 +124,26 @@ def render_block(block: WildValue) -> str:
|
|||||||
pieces.append(render_block_element(block["accessory"]))
|
pieces.append(render_block_element(block["accessory"]))
|
||||||
|
|
||||||
if "fields" in block:
|
if "fields" in block:
|
||||||
# TODO -- these should be rendered in two columns,
|
fields = block["fields"].tame(check_list(check_text_block()))
|
||||||
# left-to-right. We could render them sequentially,
|
if len(fields) == 1:
|
||||||
# except some may be Title1 / Title2 / value1 / value2,
|
# Special-case a single field to display a bit more
|
||||||
# which would be nonsensical when rendered sequentially.
|
# nicely, without extraneous borders and limitations
|
||||||
pass
|
# on its contents.
|
||||||
|
pieces.append(fields[0]["text"])
|
||||||
|
else:
|
||||||
|
# It is not possible to have newlines in a table, nor
|
||||||
|
# escape the pipes that make it up; replace them with
|
||||||
|
# whitespace.
|
||||||
|
field_text = [f["text"].replace("\n", " ").replace("|", " ") for f in fields]
|
||||||
|
# Because Slack formats this as two columns, but not
|
||||||
|
# necessarily a table with a bold header, we emit a
|
||||||
|
# blank header row first.
|
||||||
|
table = "| | |\n|-|-|\n"
|
||||||
|
# Then take the fields two-at-a-time to make the table
|
||||||
|
iters = [iter(field_text)] * 2
|
||||||
|
for left, right in zip_longest(*iters, fillvalue=""):
|
||||||
|
table += f"| {left} | {right} |\n"
|
||||||
|
pieces.append(table)
|
||||||
|
|
||||||
return "\n\n".join(piece.strip() for piece in pieces if piece.strip() != "")
|
return "\n\n".join(piece.strip() for piece in pieces if piece.strip() != "")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user