mirror of
https://github.com/lnbits/lnbits-legend.git
synced 2025-03-10 17:26:15 +01:00
Add webhook_api_key and webhook_custom_data to lnurlp webhook (#1065)
* add webhook_api_key and webhook_custom_data to lnurlp * formatting * add json validation to lnurlp custom_data * motorina0 improvements
This commit is contained in:
parent
604e52c45d
commit
41aa074350
6 changed files with 64 additions and 6 deletions
|
@ -21,13 +21,15 @@ async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink:
|
||||||
served_meta,
|
served_meta,
|
||||||
served_pr,
|
served_pr,
|
||||||
webhook_url,
|
webhook_url,
|
||||||
|
webhook_headers,
|
||||||
|
webhook_body,
|
||||||
success_text,
|
success_text,
|
||||||
success_url,
|
success_url,
|
||||||
comment_chars,
|
comment_chars,
|
||||||
currency,
|
currency,
|
||||||
fiat_base_multiplier
|
fiat_base_multiplier
|
||||||
)
|
)
|
||||||
VALUES (?, ?, ?, ?, 0, 0, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, 0, 0, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
{returning}
|
{returning}
|
||||||
""",
|
""",
|
||||||
(
|
(
|
||||||
|
@ -36,6 +38,8 @@ async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink:
|
||||||
data.min,
|
data.min,
|
||||||
data.max,
|
data.max,
|
||||||
data.webhook_url,
|
data.webhook_url,
|
||||||
|
data.webhook_headers,
|
||||||
|
data.webhook_body,
|
||||||
data.success_text,
|
data.success_text,
|
||||||
data.success_url,
|
data.success_url,
|
||||||
data.comment_chars,
|
data.comment_chars,
|
||||||
|
|
|
@ -60,3 +60,11 @@ async def m004_fiat_base_multiplier(db):
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"ALTER TABLE lnurlp.pay_links ADD COLUMN fiat_base_multiplier INTEGER DEFAULT 1;"
|
"ALTER TABLE lnurlp.pay_links ADD COLUMN fiat_base_multiplier INTEGER DEFAULT 1;"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def m005_webhook_headers_and_body(db):
|
||||||
|
"""
|
||||||
|
Add headers and body to webhooks
|
||||||
|
"""
|
||||||
|
await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN webhook_headers TEXT;")
|
||||||
|
await db.execute("ALTER TABLE lnurlp.pay_links ADD COLUMN webhook_body TEXT;")
|
||||||
|
|
|
@ -18,6 +18,8 @@ class CreatePayLinkData(BaseModel):
|
||||||
currency: str = Query(None)
|
currency: str = Query(None)
|
||||||
comment_chars: int = Query(0, ge=0, lt=800)
|
comment_chars: int = Query(0, ge=0, lt=800)
|
||||||
webhook_url: str = Query(None)
|
webhook_url: str = Query(None)
|
||||||
|
webhook_headers: str = Query(None)
|
||||||
|
webhook_body: str = Query(None)
|
||||||
success_text: str = Query(None)
|
success_text: str = Query(None)
|
||||||
success_url: str = Query(None)
|
success_url: str = Query(None)
|
||||||
fiat_base_multiplier: int = Query(100, ge=1)
|
fiat_base_multiplier: int = Query(100, ge=1)
|
||||||
|
@ -31,6 +33,8 @@ class PayLink(BaseModel):
|
||||||
served_meta: int
|
served_meta: int
|
||||||
served_pr: int
|
served_pr: int
|
||||||
webhook_url: Optional[str]
|
webhook_url: Optional[str]
|
||||||
|
webhook_headers: Optional[str]
|
||||||
|
webhook_body: Optional[str]
|
||||||
success_text: Optional[str]
|
success_text: Optional[str]
|
||||||
success_url: Optional[str]
|
success_url: Optional[str]
|
||||||
currency: Optional[str]
|
currency: Optional[str]
|
||||||
|
|
|
@ -33,17 +33,22 @@ async def on_invoice_paid(payment: Payment) -> None:
|
||||||
if pay_link and pay_link.webhook_url:
|
if pay_link and pay_link.webhook_url:
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
try:
|
try:
|
||||||
r = await client.post(
|
kwargs = {
|
||||||
pay_link.webhook_url,
|
"json": {
|
||||||
json={
|
|
||||||
"payment_hash": payment.payment_hash,
|
"payment_hash": payment.payment_hash,
|
||||||
"payment_request": payment.bolt11,
|
"payment_request": payment.bolt11,
|
||||||
"amount": payment.amount,
|
"amount": payment.amount,
|
||||||
"comment": payment.extra.get("comment"),
|
"comment": payment.extra.get("comment"),
|
||||||
"lnurlp": pay_link.id,
|
"lnurlp": pay_link.id,
|
||||||
},
|
},
|
||||||
timeout=40,
|
"timeout": 40,
|
||||||
)
|
}
|
||||||
|
if pay_link.webhook_body:
|
||||||
|
kwargs["json"]["body"] = json.loads(pay_link.webhook_body)
|
||||||
|
if pay_link.webhook_headers:
|
||||||
|
kwargs["headers"] = json.loads(pay_link.webhook_headers)
|
||||||
|
|
||||||
|
r = await client.post(pay_link.webhook_url, **kwargs)
|
||||||
await mark_webhook_sent(payment, r.status_code)
|
await mark_webhook_sent(payment, r.status_code)
|
||||||
except (httpx.ConnectError, httpx.RequestError):
|
except (httpx.ConnectError, httpx.RequestError):
|
||||||
await mark_webhook_sent(payment, -1)
|
await mark_webhook_sent(payment, -1)
|
||||||
|
|
|
@ -213,6 +213,24 @@
|
||||||
label="Webhook URL (optional)"
|
label="Webhook URL (optional)"
|
||||||
hint="A URL to be called whenever this link receives a payment."
|
hint="A URL to be called whenever this link receives a payment."
|
||||||
></q-input>
|
></q-input>
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
v-if="formDialog.data.webhook_url"
|
||||||
|
v-model="formDialog.data.webhook_headers"
|
||||||
|
type="text"
|
||||||
|
label="Webhook headers (optional)"
|
||||||
|
hint="Custom data as JSON string, send headers along with the webhook."
|
||||||
|
></q-input>
|
||||||
|
<q-input
|
||||||
|
filled
|
||||||
|
dense
|
||||||
|
v-if="formDialog.data.webhook_url"
|
||||||
|
v-model="formDialog.data.webhook_body"
|
||||||
|
type="text"
|
||||||
|
label="Webhook custom data (optional)"
|
||||||
|
hint="Custom data as JSON string, will get posted along with webhook 'body' field."
|
||||||
|
></q-input>
|
||||||
<q-input
|
<q-input
|
||||||
filled
|
filled
|
||||||
dense
|
dense
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import json
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
|
|
||||||
from fastapi import Request
|
from fastapi import Request
|
||||||
|
@ -90,6 +91,24 @@ async def api_link_create_or_update(
|
||||||
detail="Must use full satoshis.", status_code=HTTPStatus.BAD_REQUEST
|
detail="Must use full satoshis.", status_code=HTTPStatus.BAD_REQUEST
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if data.webhook_headers:
|
||||||
|
try:
|
||||||
|
json.loads(data.webhook_headers)
|
||||||
|
except ValueError:
|
||||||
|
raise HTTPException(
|
||||||
|
detail="Invalid JSON in webhook_headers.",
|
||||||
|
status_code=HTTPStatus.BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
|
if data.webhook_body:
|
||||||
|
try:
|
||||||
|
json.loads(data.webhook_body)
|
||||||
|
except ValueError:
|
||||||
|
raise HTTPException(
|
||||||
|
detail="Invalid JSON in webhook_body.",
|
||||||
|
status_code=HTTPStatus.BAD_REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
# database only allows int4 entries for min and max. For fiat currencies,
|
# database only allows int4 entries for min and max. For fiat currencies,
|
||||||
# we multiply by data.fiat_base_multiplier (usually 100) to save the value in cents.
|
# we multiply by data.fiat_base_multiplier (usually 100) to save the value in cents.
|
||||||
if data.currency and data.fiat_base_multiplier:
|
if data.currency and data.fiat_base_multiplier:
|
||||||
|
|
Loading…
Add table
Reference in a new issue