Commit Graph

49 Commits

Author SHA1 Message Date
PieterCK 92437b4ab5 integrations: Refactor slack_incoming webhook.
This commit refactors `render_attachment` and `render_block`
out of slack_incoming.py to promote reusability.

The primary motivation for this refactor is to add support for
converting integration bots messages in Slack exports, which could use
the same functions.

Part of #31311.
2024-11-07 10:47:08 -08:00
Aditya Kumar Kasaudhan d448b75176 slack_incoming: Add ok=false to JSON in case of error.
Previously, errors were returned using Zulip's default format,
which did not match Slack's expected response structure.

This change ensures that errors in the Slack incoming webhook handler
return JSON responses in Slack's expected format: {ok: false, error:
"error string"}.

Fixes: #31878.
2024-10-30 15:33:29 -07:00
Pierre Carru 5cbe3203f5
slack_incoming: add ok=true to json in case of success.
This better simulates the Slack API, which is important, since some
integrations check this response and decide whether the Slack endpoint
is working based on what they receive.
2024-10-04 08:42:27 -07:00
Niloth P f663544353 integration-docs: Update Slack incoming-webhook for new doc format.
Part of zulip#29592.
2024-07-16 14:55:56 -07:00
Anders Kaseorg e08a24e47f ruff: Fix UP006 Use `list` instead of `List` for type annotation.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-07-13 22:28:22 -07:00
Mateusz Mandera 5c9f3cd08c webhooks: Rename create-stream.md to create-channel.md. 2024-05-06 09:07:57 -07:00
Mateusz Mandera d7b2655ad2 webhooks: Rename stream_name to channel_name arg. 2024-05-04 19:01:51 -07:00
Mateusz Mandera fef299510f webhooks: Rename assert_stream_message to assert_channel_message. 2024-05-04 19:01:51 -07:00
Mateusz Mandera dc31347ac4 webhooks: Rename STREAM_NAME to CHANNEL_NAME in tests. 2024-05-04 19:01:51 -07:00
Anders Kaseorg 96fbe060a6 python: Mark regexes as raw strings.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-04-26 12:30:31 -07:00
Anders Kaseorg 712917b2c9 ruff: Fix RUF019 Unnecessary key check before dictionary access.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-02-02 10:30:45 -08:00
Prakhar Pratyush 3afc8ed7ae webhooks: Rename *topic local variables to *topic_name.
This is preparatory work towards adding a Topic model.
We plan to use the local variable name as 'topic' for
the Topic model objects.

Currently, we use *topic as the local variable name for
topic names.

We rename local variables of the form *topic to *topic_name
so that we don't need to think about type collisions in
individual code paths where we might want to talk about both
Topic objects and strings for the topic name.
2024-01-17 08:35:29 -08:00
Tim Abbott 0d525cf644 integrations: Recommend new integration URL tool.
Fixes part of #25976.
2023-11-08 14:19:05 -08:00
Alya Abbott 8fd631bf06 integrations-docs: Update intro content for Slack incoming webhooks. 2023-11-07 12:59:24 -08:00
Lauryn Menard 1618060a3e integrations-docs: Update both Slack integration articles.
Updates the Slack integration page to not describe adding a stream
or topic parameter to the URL query since that's not supported by
the current integration implementation.

Updates the Slack-compatible webhook integration page to have the
extra notes about the integration at the top of the page. Also,
removes the reference to a screenshot of the webhook since there
isn't one.
2023-11-07 12:59:24 -08:00
Anders Kaseorg a50eb2e809 mypy: Enable new error explicit-override.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-10-12 12:28:41 -07:00
Zixuan James Li 9377080f1f webhooks: Migrate most webhooks to use @typed_endpoint.
This converts most webhook integration views to use @typed_endpoint instead
of @has_request_variables, rewriting REQ parameters. For these
webhooks, it simply requires switching the decorator, rewriting the
type annotation of payload/message to WebhookPayload[WildValue], and
removing the REQ default that defines the to_wild_value converter.
2023-09-08 08:20:17 -07:00
Anders Kaseorg 562a79ab76 ruff: Fix PERF401 Use a list comprehension to create a transformed list.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-08-07 17:23:55 -07:00
Anders Kaseorg df001db1a9 black: Reformat with Black 23.
Black 23 enforces some slightly more specific rules about empty line
counts and redundant parenthesis removal, but the result is still
compatible with Black 22.

(This does not actually upgrade our Python environment to Black 23
yet.)

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-02-02 10:40:13 -08:00
Alex Vandiver 1b692984ce 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.
2023-01-04 14:03:47 -08:00
Alex Vandiver 4dc57dadd6 slack_incoming: Make check_text_block return its input.
`check_text_block` transformed its input, making the object it
returned not the same object it was passed; this invalidated it for
use in `check_list`.  It is also, in general, unlike all other
validators.

Make it return a TypedDict cast of its input.
2023-01-04 14:03:47 -08:00
Alex Vandiver eb3674362a slack_incoming: Verify that keys exist before checking their value. 2022-11-29 16:34:16 -08:00
Alex Vandiver f1a8209705 slack_incoming: Fix formatting fixups with overlaps, or at start/end.
The previous regular expression required a `[^\w]` at the start and
end of the match.  This had two unintended effects -- it meant that it
could never match at the start or end of a string, and it meant
that *adjacent* words required *two* non-word characters between them,
as the pattern matches cannot overlap.

Switch to allowing string start/end to anchor the matches, and make
the trailing `[^\w]` be a zero-width look-ahead, to allow the patterns
to overlap.  Also remove the spurious `^` within the inner character
classes, which prevented `*foo^bar*` from matching.  Finally, add
tests to cover the functionality, which was previously untested.
2022-11-29 16:34:16 -08:00
Hari Prashant Bhimaraju fd0b013bcd slack_incoming: Handle optional attachment fields aptly.
This commit checks for null values for keys within "attachment" in
the Slack integration's incoming payloads. These keys were expected
to exist optionally previously, and the existence of null values for
these wasn't anticipated. Due to an issue report for such null
values in the payload, their handling is updated appropriately.

The checks for these values are truthiness checks since the strategy
for these values being null or falsy ("", 0) is the same; we don't
process that key-value pair. This is consistent with how Slack handles
this scenario.

For the case where all the attachment fields have null values, Slack
displays this as an empty block with no content, and therefore our
strategy for this is a no-op.

Tests updated.
2022-08-22 16:40:13 -07:00
Anders Kaseorg b991c8019e slack_incoming: Simplify empty POST test.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-07-05 13:08:35 -07:00
Alex Vandiver bc25f016fc slack_incoming: Support more syntax.
This significantly extends the accepted support for Slack "blocks"[1], as
well as their legacy "attachments"[2] syntax.

Fixes: #21944.

See also #22228, which this does not solve, but assuming we can decide
which compromises to make, becomes a reasonably uncomplicated follow-up.

[1]: https://api.slack.com/reference/block-kit/blocks
[2]: https://api.slack.com/reference/messaging/attachments
2022-06-28 17:04:53 -07:00
Alex Vandiver 239fdc2222 slack_incoming: Stop passing around the previous body.
The only operation is to append -- let that happen in the caller.
2022-06-28 17:04:53 -07:00
Alex Vandiver 0511400d73 slack_incoming: Handle null blocks and attachments.
This is not accepted according to Slack's block-builder, but is
attested in the wild.
2022-06-28 17:04:53 -07:00
Alex Vandiver 74cf9a1e9f slack_incoming: Strengthen types using WildValue. 2022-06-28 17:04:53 -07:00
Anders Kaseorg dc33a0ae67 markdown: Rewrite include plugin without markdown-include.
markdown-include is GPL licensed.

Also, rewrite it as a block processor, so that it works correctly
inside indented blocks.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-06-26 17:36:31 -07:00
Christopher Chong b6f6f6db8d slack_incoming: Process request payload directly in view.py.
slack_incoming webhook previously used has_request_variables to
extract payload from HttpRequest object first, before trying to
access HttpRequest.body again in view.py. This caused an error
when one sends a request without payload - it is forbidden to
read from request data stream twice.

Instead of relying on has_request_variables, this PR extracts
payload depending on content type in view.py directly to avoid
reading request data stream twice.

Fixes #19056.
2022-04-28 14:45:38 -07:00
Anders Kaseorg 5caeb8444b validator: Replace converter=orjson.loads with json_validator.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2022-03-15 13:02:02 -07:00
Lauryn Menard 3be622ffa7 backend: Add request as parameter to json_success.
Adds request as a parameter to json_success as a refactor towards
making `ignored_parameters_unsupported` functionality available
for all API endpoints.

Also, removes any data parameters that are an empty dict or
a dict with the generic success response values.
2022-02-04 15:16:56 -08:00
Alex Vandiver 43f3f9221d slack_incoming: Handle explicit None text payload in webhook. 2021-07-15 09:37:39 -07:00
PIG208 5ecbfecd77 webhook: Rename FIXTURE_DIR_NAME to WEBHOOK_DIR_NAME.
Since FIXTURE_DIR_NAME is the name of the folder that contains the view
and tests modules of the webhook and another folder called "fixtures" that
store the fixtures, it is more appropriate to call it WEBHOOK_DIR_NAME,
especially when we want to refer to the view module using this variable.
2021-06-29 17:01:54 -07:00
akshatdalton 8d158852fd webhooks/slack_incoming: Update regex to correctly convert emphasis.
This was a bug where we were converting _text_ to **text**.
For emphasis we use the *text* format.
2021-06-24 09:43:32 -07:00
Anders Kaseorg e7ed907cf6 python: Convert deprecated Django ugettext alias to gettext.
django.utils.translation.ugettext is a deprecated alias of
django.utils.translation.gettext as of Django 3.0, and will be removed
in Django 4.0.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-04-15 18:01:34 -07:00
Anders Kaseorg 6e4c3e41dc python: Normalize quotes with Black.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-02-12 13:11:19 -08:00
Anders Kaseorg 11741543da python: Reformat with Black, except quotes.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-02-12 13:11:19 -08:00
Alex Vandiver cf6ebb9c8d webhooks: Rename api_key_only_webhook_view to webhook_view.
There are no other types of webhook views; this is more concise.
2020-09-10 17:47:21 -07:00
Steve Howell 388053db6b webhook tests: Rename main helper to check_webhook.
Almost all webhook tests use this helper, except a few
webhooks that write to private streams.

Being concise is important here, and the name
`self.send_and_test_stream_message` always confused
me, since it sounds you're sending a stream message,
and it leaves out the webhook piece.

We should consider renaming `send_and_test_private_message`
to something like `check_webhook_private`, but I couldn't
decide on a great name, and it's very rarely used.  So
for now I just made sure the docstrings of the two
sibling functions reference each other.
2020-08-24 12:34:46 -07:00
Anders Kaseorg d0f4af5f8c python: Catch JSONDecodeError instead of ValueError when decoding JSON.
These weren’t wrong since orjson.JSONDecodeError subclasses
json.JSONDecodeError which subclasses ValueError, but the more
specific ones express the intention more clearly.

(ujson raised ValueError directly, as did json in Python 2.)

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-08-12 11:59:59 -07:00
Anders Kaseorg 61d0417e75 python: Replace ujson with orjson.
Fixes #6507.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-08-11 10:55:12 -07:00
Anders Kaseorg 365fe0b3d5 python: Sort imports with isort.
Fixes #2665.

Regenerated by tabbott with `lint --fix` after a rebase and change in
parameters.

Note from tabbott: In a few cases, this converts technical debt in the
form of unsorted imports into different technical debt in the form of
our largest files having very long, ugly import sequences at the
start.  I expect this change will increase pressure for us to split
those files, which isn't a bad thing.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-06-11 16:45:32 -07:00
Anders Kaseorg 69730a78cc python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:

import re
import sys

last_filename = None
last_row = None
lines = []

for msg in sys.stdin:
    m = re.match(
        r"\x1b\[35mflake8    \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
    )
    if m:
        filename, row_str, col_str, err = m.groups()
        row, col = int(row_str), int(col_str)

        if filename == last_filename:
            assert last_row != row
        else:
            if last_filename is not None:
                with open(last_filename, "w") as f:
                    f.writelines(lines)

            with open(filename) as f:
                lines = f.readlines()
            last_filename = filename
        last_row = row

        line = lines[row - 1]
        if err in ["C812", "C815"]:
            lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
        elif err in ["C819"]:
            assert line[col - 2] == ","
            lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")

if last_filename is not None:
    with open(last_filename, "w") as f:
        f.writelines(lines)

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-06-11 16:04:12 -07:00
Anders Kaseorg 8dd83228e7 python: Convert "".format to Python 3.6 f-strings.
Generated by pyupgrade --py36-plus --keep-percent-format, but with the
NamedTuple changes reverted (see commit
ba7906a3c6, #15132).

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-06-08 15:31:20 -07:00
Anders Kaseorg 8c15081069 python: Further pyupgrade changes.
Generated by pyupgrade --py3-plus --keep-percent-format.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2020-06-08 15:23:10 -07:00
Tim Abbott a0c2121958 docs: Advertise Slack-compatible webhook a bit.
This should make it discoverable enough that users will try it out and
send us feedback.
2020-05-11 00:07:28 -07:00
Chris Heald c80e913c7a webhooks: Add a webhook capable of parsing Slack payloads.
This adds a webhook that can be used to interpret standard Slack
payloads. Since there are a ton of existing Slack integrations out
there, having a webhook which can accept standard Slack payloads can
significantly ease transition pains. Obviously this can't do everything
that Slack payloads can (particularly WRT their widgets/interactions),
but we can ingest text and parse out multi-block payloads into a message
relatively reasonably.
2020-05-11 00:07:28 -07:00