fix: persist webhook call status

This commit is contained in:
Vlad Stan 2022-11-25 14:12:13 +02:00
parent ead710e591
commit 1a9cd81ee9
6 changed files with 39 additions and 13 deletions

View File

@ -35,18 +35,18 @@ async def call_webhook(charge: Charges):
json=public_charge(charge), json=public_charge(charge),
timeout=40, timeout=40,
) )
except AssertionError: return {"webhook_success": r.is_success, "webhook_message": r.reason_phrase}
charge.webhook = None
except Exception as e: except Exception as e:
logger.warning(f"Failed to call webhook for charge {charge.id}") logger.warning(f"Failed to call webhook for charge {charge.id}")
logger.warning(e) logger.warning(e)
return {"webhook_success": False, "webhook_message": str(e)}
async def fetch_onchain_balance(charge: Charges): async def fetch_onchain_balance(charge: Charges):
endpoint = ( endpoint = (
f"{charge.config['mempool_endpoint']}/testnet" f"{charge.config['mempool_endpoint']}/testnet"
if charge.config["network"] == "Testnet" if charge.config.network == "Testnet"
else charge.config["mempool_endpoint"] else charge.config.mempool_endpoint
) )
async with httpx.AsyncClient() as client: async with httpx.AsyncClient() as client:
r = await client.get(endpoint + "/api/address/" + charge.onchainaddress) r = await client.get(endpoint + "/api/address/" + charge.onchainaddress)

View File

@ -19,6 +19,13 @@ class CreateCharge(BaseModel):
extra: str = "{}" extra: str = "{}"
class ChargeConfig(BaseModel):
mempool_endpoint: Optional[str]
network: Optional[str]
webhook_success: Optional[bool] = False
webhook_message: Optional[str]
class Charges(BaseModel): class Charges(BaseModel):
id: str id: str
description: Optional[str] description: Optional[str]
@ -59,5 +66,9 @@ class Charges(BaseModel):
return False return False
@property @property
def config(self): def config(self) -> ChargeConfig:
return json.loads(self.extra) charge_config = json.loads(self.extra)
return ChargeConfig(**charge_config)
def must_call_webhook(self):
return self.webhook and self.paid and self.config.webhook_success == False

View File

@ -1,4 +1,5 @@
import asyncio import asyncio
import json
from loguru import logger from loguru import logger
@ -7,6 +8,7 @@ from lnbits.extensions.satspay.crud import check_address_balance, get_charge
from lnbits.helpers import get_current_extension_name from lnbits.helpers import get_current_extension_name
from lnbits.tasks import register_invoice_listener from lnbits.tasks import register_invoice_listener
from .crud import update_charge
from .helpers import call_webhook from .helpers import call_webhook
@ -32,5 +34,7 @@ async def on_invoice_paid(payment: Payment) -> None:
await payment.set_pending(False) await payment.set_pending(False)
charge = await check_address_balance(charge_id=charge.id) charge = await check_address_balance(charge_id=charge.id)
if charge.paid and charge.webhook: if charge.must_call_webhook():
await call_webhook(charge) resp = await call_webhook(charge)
extra = {**charge.config.dict(), **resp}
await update_charge(charge_id=charge.id, extra=json.dumps(extra))

View File

@ -203,9 +203,14 @@
:href="props.row.webhook" :href="props.row.webhook"
target="_blank" target="_blank"
style="color: unset; text-decoration: none" style="color: unset; text-decoration: none"
>{{props.row.webhook || props.row.webhook}}</a >{{props.row.webhook}}</a
> >
</div> </div>
<div class="col-4 q-pr-lg">
<q-badge v-if="props.row.webhook_message" color="blue">
{{props.row.webhook_message }}
</q-badge>
</div>
</div> </div>
<div class="row items-center q-mt-md q-mb-lg"> <div class="row items-center q-mt-md q-mb-lg">
<div class="col-2 q-pr-lg">ID:</div> <div class="col-2 q-pr-lg">ID:</div>

View File

@ -34,10 +34,9 @@ async def display(request: Request, charge_id: str):
view_data = { view_data = {
"request": request, "request": request,
"charge_data": public_charge(charge), "charge_data": public_charge(charge),
"mempool_endpoint": charge.config.mempool_endpoint,
"network": charge.config.network
} }
if "mempool_endpoint" in charge.config:
view_data["mempool_endpoint"] = charge.config["mempool_endpoint"]
view_data["network"] = charge.config["network"]
return satspay_renderer().TemplateResponse( return satspay_renderer().TemplateResponse(
"satspay/display.html", "satspay/display.html",

View File

@ -1,3 +1,4 @@
import json
from http import HTTPStatus from http import HTTPStatus
from fastapi.params import Depends from fastapi.params import Depends
@ -19,7 +20,7 @@ from .crud import (
get_charges, get_charges,
update_charge, update_charge,
) )
from .helpers import public_charge from .helpers import call_webhook, public_charge
from .models import CreateCharge from .models import CreateCharge
#############################CHARGES########################## #############################CHARGES##########################
@ -57,6 +58,7 @@ async def api_charges_retrieve(wallet: WalletTypeInfo = Depends(get_key_type)):
**{"time_elapsed": charge.time_elapsed}, **{"time_elapsed": charge.time_elapsed},
**{"time_left": charge.time_left}, **{"time_left": charge.time_left},
**{"paid": charge.paid}, **{"paid": charge.paid},
**{"webhook_message": charge.config.webhook_message},
} }
for charge in await get_charges(wallet.wallet.user) for charge in await get_charges(wallet.wallet.user)
] ]
@ -118,4 +120,9 @@ async def api_charge_balance(charge_id):
status_code=HTTPStatus.NOT_FOUND, detail="Charge does not exist." status_code=HTTPStatus.NOT_FOUND, detail="Charge does not exist."
) )
if charge.must_call_webhook():
resp = await call_webhook(charge)
extra = {**charge.config.dict(), **resp}
await update_charge(charge_id=charge.id, extra=json.dumps(extra))
return {**public_charge(charge)} return {**public_charge(charge)}