WebhookDestination.h header

#include <ew/app/WebhookDestination.h>

Namespace ew::app

WebhookDestination struct

struct ew::app::WebhookDestination

One place the user has chosen to send notifications.

The URL is the user's own, pasted from a webhook they created in their own workspace. That is what keeps this feature inside the zero-service rule: with no URL configured the feature is ABSENT, not broken, exactly like the bring-your-own AI provider. Nothing here reaches a service this project runs, and nothing works less well for a user who never sets one up.

Members

QString ew::app::webhook::WebhookDestination::name

What the user calls it ("team channel"), for the settings list.

QString ew::app::webhook::WebhookDestination::url

The incoming-webhook URL, as pasted.

WebhookService ew::app::webhook::WebhookDestination::service =

Which service it belongs to, deciding the payload shape.

bool ew::app::webhook::WebhookDestination::enabled = true

Whether it is currently sending. Off lets somebody keep a URL without using it, which is what people actually do when a channel goes quiet for a release.

Enumerations

enum class WebhookService { Discord, Slack, Teams }

The chat service a webhook posts to.

The service matters because each wants a different JSON shape for the same message – Discord reads content, Slack reads text, Teams wants a card object. Storing which one a URL belongs to is what lets the payload be built correctly instead of guessed from the hostname, which would break the moment somebody put a proxy in front of it.

Functions

QByteArray ew::app::webhook::buildWebhookPayload(WebhookService service, const QString &message)

Builds the JSON body service expects for message.

Each service is given the shape it documents, not a lowest common denominator: Discord and Slack read a single text field under different names, and Teams expects a MessageCard object with a type and context. Sending Discord's body to Teams produces a silent 400 that looks, from the writer's side, exactly like a message nobody replied to.

bool ew::app::webhook::looksLikeWebhookUrl(const QString &url)

Whether url is a plausible incoming-webhook URL for service.

A weak check on purpose. It rejects the mistakes people actually make – an empty box, a pasted channel link, plain http – and does NOT try to validate the host, because a corporate proxy or a self-hosted Mattermost endpoint is a legitimate destination the writer knows about and this code does not. Refusing those would be this project deciding where a user may send their own notifications.

QString ew::app::webhook::toToken(WebhookService service)

Returns the stable serialization token for service.

std::optional< WebhookService > ew::app::webhook::webhookServiceFromToken(QStringView token)

Parses a service from its token; std::nullopt if unrecognized or absent.