events/README.md
Padreug 2f8a602bbd
Some checks failed
lint.yml / feat: attach a self-describing ticket card to the email (1.6.1-aio.10) (pull_request) Failing after 0s
feat: attach a self-describing ticket card to the email (1.6.1-aio.10)
The v1.6.1-aio.9 mail still scored 8.4/10 on mail-tester: the remaining
deduction was HTML_IMAGE_ONLY (1.8) — an HTML part whose only content of
note is a remote <img>. Remote images are also blocked by default in most
clients until the reader opts in, and a bare QR saved from that mail says
nothing about what it opens.

- New `qr.py` module (QR + logo helpers moved out of views_api) with
  `render_ticket_card`: site title, event name, when/where, the branded
  QR, name on ticket, ticket id and the door instruction, laid out with
  the bundled DejaVu Sans; `format_event_when` gives "Fri 19 Feb 2027,
  16:00 - 20:00"; filenames are `ticket-<event-slug>-<id8>.png`.
- `GET /events/api/v1/ticket-card/{ticket_id}` serves the same PNG
  (anonymous, like the QR endpoint); the email's "Ticket image" link
  now points there.
- The ticket email becomes multipart/mixed: text + HTML alternatives
  (URLs as links, no <img>) plus the card as a PNG attachment, which
  clients show inline at the end of the message and which works offline
  at the door.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EYwoAkZZmXMMmaBp4WGUBo
2026-09-08 16:40:25 +02:00

78 lines
4 KiB
Markdown

<a href="https://lnbits.com" target="_blank" rel="noopener noreferrer">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://i.imgur.com/QE6SIrs.png">
<img src="https://i.imgur.com/fyKPgVT.png" alt="LNbits" style="width:280px">
</picture>
</a>
[![License: MIT](https://img.shields.io/badge/License-MIT-success?logo=open-source-initiative&logoColor=white)](./LICENSE)
[![Built for LNbits](https://img.shields.io/badge/Built%20for-LNbits-4D4DFF?logo=lightning&logoColor=white)](https://github.com/lnbits/lnbits)
# Events - <small>[LNbits](https://github.com/lnbits/lnbits) extension</small>
<small>For more about LNBits extension check [this tutorial](https://github.com/lnbits/lnbits/wiki/LNbits-Extensions)</small>
## Sell tickets for events and use the built-in scanner for registering attendees
Events allows you to create tickets for an event. Each ticket is in the form of a unique QR code. After registering and paying, the user gets a QR code to present at registration/entrance.
Events includes a shareable ticket scanner, which can be used to register attendees.
## Usage
1. Create an event\
![create event](https://i.imgur.com/dadK1dp.jpg)
2. Fill out the event information:
- event name
- wallet (normally there's only one)
- event information
- closing date for event registration
- begin and end date of the event
![event info](https://imgur.com/KAv68Yr.jpg)
3. Share the event registration link\
![event ticket](https://imgur.com/AQWUOBY.jpg)
- ticket example\
![ticket example](https://i.imgur.com/trAVSLd.jpg)
- QR code ticket, presented after invoice paid, to present at registration\
![event ticket](https://i.imgur.com/M0ROM82.jpg)
4. Use the built-in ticket scanner to validate registered, and paid, attendees\
![ticket scanner](https://i.imgur.com/zrm9202.jpg)
## Guest checkout, card payments and email delivery (aio fork)
- **Identity.** `POST /events/api/v1/tickets/{event_id}` accepts either an
LNbits `user_id` or a guest `name` + `email`; a `user_id` ticket may also
carry an `email` so logged-in buyers get their ticket mailed.
- **Payment methods.** `extra.payment_methods` (`lightning`, `fiat`) lists the
rails an event accepts; an empty list keeps the legacy rule (Lightning always,
fiat when `allow_fiat`). The effective list is published on the NIP-52 event
as `tickets_payment_methods` and enforced at purchase.
- **Return to the calling app.** A client may send `frontend_url` (its app
root, e.g. `https://app.example/events`). Its origin must be one of
`LNBITS_CORS_ALLOWED_ORIGINS`, the LNbits base URL or
`LNBITS_CUSTOM_FRONTEND_URL`, otherwise the request is refused. Under that
root the extension builds the Stripe `success_url`
(`/events/{event_id}?checkout=success&tickets=<id,id>`), `cancel_url`
(`/events/{event_id}?checkout=cancelled`) and the emailed ticket link
(`/events/ticket/{ticket_id}`). Absent, the LNbits host is used as before.
- **Stripe session.** The buyer's email is passed as `customer_email`
(prefilled and locked on the hosted page); the line item is named after the
event; `event_id`, `quantity` and `ticket_ids` ride along as metadata.
- **Email.** Multipart text + HTML (links, no images) with the **ticket card**
attached — a self-describing PNG (site, event, when, where, QR with the
instance logo, name on ticket, ticket id) also served at
`GET /events/api/v1/ticket-card/{ticket_id}`; the bare QR stays at
`GET /events/api/v1/qr/{ticket_id}`. Headers carry Date, Message-ID and a
From display name (site title). `POST /events/api/v1/tickets/{ticket_id}/resend-email`
returns a `TicketResendResult` with per-channel outcome.
## Powered by LNbits
[LNbits](https://lnbits.com) is a free and open-source lightning accounts system.
[![Visit LNbits Shop](https://img.shields.io/badge/Visit-LNbits%20Shop-7C3AED?logo=shopping-cart&logoColor=white&labelColor=5B21B6)](https://shop.lnbits.com/)
[![Try myLNbits SaaS](https://img.shields.io/badge/Try-myLNbits%20SaaS-2563EB?logo=lightning&logoColor=white&labelColor=1E40AF)](https://my.lnbits.com/login)