# New-sale notifications and email reports

> Get a message in Slack, Discord or email when a sale comes in, with where the buyer came from, and weekly or monthly email reports of a site's traffic and revenue.

PilotFox can tell you about each new sale as it is imported, and send you a summary of a site every week or every month.

## New-sale notifications

When PilotFox imports a payment it has never seen before, the site's chosen channels get a message like:

> New sale: $49.00 · from Hacker News (news.ycombinator.com) · Germany

- **Where the buyer came from** is the visit the payment is credited to (see [how payments are linked to visits](https://pilotfox.app/docs/revenue)): its referrer, named for well-known sites, else its campaign source and channel, else its channel. The country is that visit's. Whatever is unknown is left out, so a payment linked to no visit shows only its amount.
- **What counts as new:** a payment paid in the last 24 hours that PilotFox had not stored yet. Payments imported when a provider is first connected (or its key replaced), payments read again later, refunds and payments refunded in full before they were imported never send a message. Each payment sends at most one. Payments recorded with the [payments API](https://pilotfox.app/docs/revenue) count the same way: the first time a payment id is recorded, never on an update.
- **Bursts:** sales are sent once a minute, so several sales in a minute arrive as one message ("3 new sales: $147.00") listing up to ten of them.
- Payments made with a test key say "test mode".

### Channels

Open Site settings → Notifications (you need the editor role) and choose any of:

- **Email:** tick the organization members who should get an email. Only members who can see the site's revenue are listed, and a member who later loses that access gets nothing.
- **Slack:** create an [incoming webhook](https://docs.slack.dev/messaging/sending-messages-using-incoming-webhooks/) for the channel (a Slack app with Incoming Webhooks turned on, then *Add New Webhook to Workspace*) and paste its URL, which starts with `https://hooks.slack.com/services/`.
- **Discord:** in Discord, Server Settings → Integrations → Webhooks, create a webhook for the channel and paste its URL, which starts with `https://discord.com/api/webhooks/`.

A webhook URL lets whoever has it post to your channel, so PilotFox stores it encrypted and shows only its host and last four characters. A webhook can be switched off without deleting it. *Send test* posts a made-up sale to one channel at once (a test email goes to you). If Slack or Discord refuses a message, the setting shows why, for example when the webhook was deleted; the message is not sent again later.

## Email reports

Anyone who can see a site can have its report emailed to them:

- **Weekly:** on Monday, for the week before (Monday to Sunday).
- **Monthly:** on the 1st, for the month before.

Turn them on in Site settings → Notifications, or for all your sites at once in Account → Email reports. *See an example* shows the report you would get, with the site's real data.

A report shows visitors, pageviews and bounce rate, the top five sources and pages, and, when the site has a payment provider connected or payments in either period (and you can see its revenue), revenue, payments and conversion rate in the site's currency. Each number is compared with the period before. Days follow the site's time zone, and the report goes out from 6 a.m. there on its day.

Every report has an unsubscribe link, and mail apps that offer an unsubscribe button can use it directly (one-click unsubscribe, [RFC 8058](https://www.rfc-editor.org/rfc/rfc8058.html)). Unsubscribing stops that one report; the other period and other sites are not affected.

## Self-hosting

Emails need the server's mail settings: Cloudflare Email Sending (`CLOUDFLARE_ACCOUNT_ID` and `CLOUDFLARE_EMAIL_TOKEN`) or an SMTP server (`SMTP_URL`). For mail apps to offer one-click unsubscribe, RFC 8058 also asks that the sending server signs messages with DKIM, covering the `List-Unsubscribe` and `List-Unsubscribe-Post` headers PilotFox adds; Cloudflare signs them, and accepts them only with an `https://` `PUBLIC_URL`. Slack and Discord messages are sent from the server to `hooks.slack.com` and `discord.com`.

## API

The same settings are in the [REST API](https://pilotfox.app/docs/api), under `/api/v1`:

- `GET /sites/{siteId}/notifications`: the recipients, the members who can be chosen, and the Slack and Discord webhooks (editor role).
- `PUT /sites/{siteId}/notifications/email` with `{ "userIds": [...] }`: sets the recipients.
- `PUT /sites/{siteId}/notifications/slack` (or `discord`) with `url` to connect a webhook, or `enabled` to switch it on or off; `DELETE` removes it.
- `POST /sites/{siteId}/notifications/test` with `{ "channel": "email" }` (or `"slack"`, `"discord"`): sends a test.
- `GET` and `PUT /sites/{siteId}/reports` with `{ "weekly": true, "monthly": false }`: your own reports of the site.
- `GET /sites/{siteId}/reports/preview?period=weekly`: the report you would get, as HTML and text.
- `GET /me/reports`: every site you can see, with your reports.
