mirror of https://github.com/zulip/zulip.git
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:
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.
|
||||
|
||||
[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()
|
||||
|
||||
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.
|
||||
|
||||
[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()
|
||||
|
||||
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)
|
||||
|
||||
This is a section block with a button.
|
||||
|
||||
| | |
|
||||
|-|-|
|
||||
| one | two |
|
||||
| three | four |
|
||||
| five | |
|
||||
""".strip()
|
||||
|
||||
self.check_webhook(
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# Webhooks for external integrations.
|
||||
import re
|
||||
from itertools import zip_longest
|
||||
from typing import Literal, Optional, TypedDict, cast
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
|
@ -14,6 +15,7 @@ from zerver.lib.validator import (
|
|||
WildValue,
|
||||
check_dict,
|
||||
check_int,
|
||||
check_list,
|
||||
check_string,
|
||||
check_string_in,
|
||||
check_url,
|
||||
|
@ -122,11 +124,26 @@ def render_block(block: WildValue) -> str:
|
|||
pieces.append(render_block_element(block["accessory"]))
|
||||
|
||||
if "fields" in block:
|
||||
# TODO -- these should be rendered in two columns,
|
||||
# left-to-right. We could render them sequentially,
|
||||
# except some may be Title1 / Title2 / value1 / value2,
|
||||
# which would be nonsensical when rendered sequentially.
|
||||
pass
|
||||
fields = block["fields"].tame(check_list(check_text_block()))
|
||||
if len(fields) == 1:
|
||||
# Special-case a single field to display a bit more
|
||||
# nicely, without extraneous borders and limitations
|
||||
# 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() != "")
|
||||
|
||||
|
|
Loading…
Reference in New Issue