From 651ae2a386636e086abe2fc562ff8b39e0940563 Mon Sep 17 00:00:00 2001 From: Ben Arc Date: Mon, 19 Apr 2021 23:45:40 +0100 Subject: [PATCH] Added listener --- lnbits/extensions/copilot/__init__.py | 5 ++ lnbits/extensions/copilot/lnurl.py | 18 +----- lnbits/extensions/copilot/tasks.py | 87 +++++++++++++++++++++++++++ lnbits/extensions/copilot/views.py | 44 -------------- 4 files changed, 93 insertions(+), 61 deletions(-) create mode 100644 lnbits/extensions/copilot/tasks.py diff --git a/lnbits/extensions/copilot/__init__.py b/lnbits/extensions/copilot/__init__.py index 8654cb36..5ecac837 100644 --- a/lnbits/extensions/copilot/__init__.py +++ b/lnbits/extensions/copilot/__init__.py @@ -10,3 +10,8 @@ copilot_ext: Blueprint = Blueprint( from .views_api import * # noqa from .views import * # noqa from .lnurl import * # noqa +from .tasks import register_listeners + +from lnbits.tasks import record_async + +lnurlp_ext.record(record_async(register_listeners)) diff --git a/lnbits/extensions/copilot/lnurl.py b/lnbits/extensions/copilot/lnurl.py index 8af6a2ae..afc74fb9 100644 --- a/lnbits/extensions/copilot/lnurl.py +++ b/lnbits/extensions/copilot/lnurl.py @@ -71,19 +71,12 @@ async def lnurl_callback(cp_id): wallet_id=cp.wallet, amount=int(amount_received / 1000), memo=cp.lnurl_title, - webhook=str(url_for( - "copilot.api_copilot_hooker", - copilot_id=cp_id, - amount=int(amount_received / 1000), - comment=comment, - _external=False, - ))[:-1], description_hash=hashlib.sha256( ( LnurlPayMetadata(json.dumps([["text/plain", str(cp.lnurl_title)]])) ).encode("utf-8") ).digest(), - extra={"tag": "copilot", "comment": comment}, + extra={"tag": "copilot", "copilot": cp.id, "comment": comment}, ) resp = LnurlPayActionResponse( pr=payment_request, @@ -91,13 +84,4 @@ async def lnurl_callback(cp_id): disposable=False, routes=[], ) - print( - str(url_for( - "copilot.api_copilot_hooker", - copilot_id=cp_id, - amount=int(amount_received / 1000), - comment=comment, - _external=False, - ))[:-1] - ) return jsonify(resp.dict()) diff --git a/lnbits/extensions/copilot/tasks.py b/lnbits/extensions/copilot/tasks.py new file mode 100644 index 00000000..8b2b66f9 --- /dev/null +++ b/lnbits/extensions/copilot/tasks.py @@ -0,0 +1,87 @@ +import trio # type: ignore +import json +import httpx + +from lnbits.core import db as core_db +from lnbits.core.models import Payment +from lnbits.tasks import register_invoice_listener + +from .crud import get_pay_link + + +async def register_listeners(): + invoice_paid_chan_send, invoice_paid_chan_recv = trio.open_memory_channel(2) + register_invoice_listener(invoice_paid_chan_send) + await wait_for_paid_invoices(invoice_paid_chan_recv) + + +async def wait_for_paid_invoices(invoice_paid_chan: trio.MemoryReceiveChannel): + async for payment in invoice_paid_chan: + await on_invoice_paid(payment) + + +async def on_invoice_paid(payment: Payment) -> None: + webhook = None + data = None + if "copilot" != payment.extra.get("tag"): + # not an lnurlp invoice + return + + if payment.extra.get("wh_status"): + # this webhook has already been sent + return + + copilot = await get_copilot(payment.extra.get("copilot", -1)) + + if not copilot: + return ( + jsonify({"message": "Copilot link link does not exist."}), + HTTPStatus.NOT_FOUND, + ) + if int(copilot.animation1threshold) and int(amount) > copilot.animation1threshold: + data = copilot.animation1 + webhook = copilot.animation1webhook + if ( + int(copilot.animation2threshold) + and int(amount) > copilot.animation2threshold + ): + data = copilot.animation2 + webhook = copilot.animation1webhook + if ( + int(copilot.animation3threshold) + and int(amount) > copilot.animation3threshold + ): + data = copilot.animation3 + webhook = copilot.animation1webhook + if webhook: + async with httpx.AsyncClient() as client: + try: + r = await client.post( + webhook, + json={ + "payment_hash": payment.payment_hash, + "payment_request": payment.bolt11, + "amount": payment.amount, + "comment": payment.extra.get("comment"), + }, + timeout=40, + ) + await mark_webhook_sent(payment, r.status_code) + except (httpx.ConnectError, httpx.RequestError): + await mark_webhook_sent(payment, -1) + global connected_websockets + connected_websockets[copilot.id] = ( + shortuuid.uuid() + "-" + data + "-" + payment.extra.get("comment") + ) + + +async def mark_webhook_sent(payment: Payment, status: int) -> None: + payment.extra["wh_status"] = status + + await core_db.execute( + """ + UPDATE apipayments SET extra = ? + WHERE hash = ? + """, + (json.dumps(payment.extra), payment.payment_hash), + ) diff --git a/lnbits/extensions/copilot/views.py b/lnbits/extensions/copilot/views.py index bd894956..ee5254ce 100644 --- a/lnbits/extensions/copilot/views.py +++ b/lnbits/extensions/copilot/views.py @@ -64,47 +64,3 @@ async def panel(copilot_id): HTTPStatus.NOT_FOUND, "Copilot link does not exist." ) return await render_template("copilot/panel.html", copilot=copilot) - - -@copilot_ext.route( - "/api/v1/copilot/hook///", methods=["GET"] -) -async def api_copilot_hooker(copilot_id, amount, comment): - - data = "" - webhook = "" - copilot = await get_copilot(copilot_id) - - if not copilot: - return ( - jsonify({"message": "Copilot link link does not exist."}), - HTTPStatus.NOT_FOUND, - ) - if int(copilot.animation1threshold) and int(amount) > copilot.animation1threshold: - data = copilot.animation1 - webhook = copilot.animation1webhook - if ( - int(copilot.animation2threshold) - and int(amount) > copilot.animation2threshold - ): - data = copilot.animation2 - webhook = copilot.animation1webhook - if ( - int(copilot.animation3threshold) - and int(amount) > copilot.animation3threshold - ): - data = copilot.animation3 - webhook = copilot.animation1webhook - if webhook: - async with httpx.AsyncClient() as client: - await client.post( - webhook, - json={ - copilot, - }, - timeout=40, - ) - global connected_websockets - connected_websockets[copilot_id] = shortuuid.uuid() + "-" + data + "-" + comment - print(connected_websockets) - return "", HTTPStatus.OK