diff --git a/crud.py b/crud.py index 2e6013b..8a5f474 100644 --- a/crud.py +++ b/crud.py @@ -5,8 +5,10 @@ from lnbits.helpers import urlsafe_short_hash from . import db from .models import ( + DirectMessage, Merchant, Order, + PartialDirectMessage, PartialMerchant, PartialProduct, PartialStall, @@ -405,3 +407,42 @@ async def update_order_shipped_status( (order_id,), ) return Order.from_row(row) if row else None + + +######################################## MESSAGES ########################################L + + +async def create_direct_message( + merchant_id: str, dm: PartialDirectMessage +) -> DirectMessage: + dm_id = urlsafe_short_hash() + await db.execute( + f""" + INSERT INTO nostrmarket.direct_messages (merchant_id, id, event_id, message, public_key, incomming) + VALUES (?, ?, ?, ?, ?, ?) + """, + (merchant_id, dm_id, dm.event_id, dm.message, dm.public_key, dm.incomming), + ) + + msg = await get_direct_message(merchant_id, dm_id) + assert msg, "Newly created dm couldn't be retrieved" + return msg + + +async def get_direct_message(merchant_id: str, dm_id: str) -> Optional[DirectMessage]: + row = await db.fetchone( + "SELECT * FROM nostrmarket.direct_messages WHERE merchant_id = ? AND id = ?", + ( + merchant_id, + dm_id, + ), + ) + return DirectMessage.from_row(row) if row else None + + +async def get_direct_messages(merchant_id: str, public_key: str) -> List[DirectMessage]: + rows = await db.fetchall( + "SELECT * FROM nostrmarket.zones WHERE merchant_id = ? AND public_ley = ?", + (merchant_id, public_key), + ) + return [DirectMessage.from_row(row) for row in rows] diff --git a/migrations.py b/migrations.py index d6c3ffe..08105fa 100644 --- a/migrations.py +++ b/migrations.py @@ -93,31 +93,20 @@ async def m001_initial(db): """ ) - """ - Initial market table. - """ - await db.execute( - """ - CREATE TABLE nostrmarket.markets ( - id TEXT PRIMARY KEY, - user_id TEXT NOT NULL, - name TEXT - ); - """ - ) - """ Initial chat messages table. """ await db.execute( f""" - CREATE TABLE nostrmarket.messages ( + CREATE TABLE nostrmarket.direct_messages ( + merchant_id TEXT NOT NULL, id TEXT PRIMARY KEY, - msg TEXT NOT NULL, - pubkey TEXT NOT NULL, - conversation_id TEXT NOT NULL, - timestamp TIMESTAMP NOT NULL DEFAULT {db.timestamp_now} - ); + event_id TEXT, + message TEXT NOT NULL, + public_key TEXT NOT NULL, + incomming BOOLEAN NOT NULL DEFAULT false, + time TIMESTAMP NOT NULL DEFAULT {db.timestamp_now} + ); """ ) diff --git a/models.py b/models.py index f228ed5..47220a9 100644 --- a/models.py +++ b/models.py @@ -359,3 +359,23 @@ class PaymentRequest(BaseModel): id: str message: Optional[str] payment_options: List[PaymentOption] + + +######################################## MESSAGE ######################################## + + +class PartialDirectMessage(BaseModel): + event_id: Optional[str] + message: str + public_key: str + incomming: bool = False + time: Optional[int] + + +class DirectMessage(BaseModel): + id: str + + @classmethod + def from_row(cls, row: Row) -> "DirectMessage": + dm = cls(**dict(row)) + return dm diff --git a/tasks.py b/tasks.py index c97c2b2..278e72a 100644 --- a/tasks.py +++ b/tasks.py @@ -13,13 +13,14 @@ from lnbits.helpers import Optional, url_for from lnbits.tasks import register_invoice_listener from .crud import ( + create_direct_message, get_merchant_by_pubkey, get_public_keys_for_merchants, get_wallet_for_product, update_order_paid_status, ) from .helpers import order_from_json -from .models import OrderStatusUpdate, PartialOrder +from .models import OrderStatusUpdate, PartialDirectMessage, PartialOrder from .nostr.event import NostrEvent from .nostr.nostr_client import connect_to_nostrclient_ws, publish_nostr_event @@ -125,14 +126,16 @@ async def handle_nip04_message(public_key: str, event: NostrEvent): assert merchant, f"Merchant not found for public key '{public_key}'" clear_text_msg = merchant.decrypt_message(event.content, event.pubkey) - dm_content = await handle_dirrect_message(event.pubkey, event.id, clear_text_msg) + dm_content = await handle_dirrect_message( + merchant.id, event.pubkey, event.id, clear_text_msg + ) if dm_content: dm_event = merchant.build_dm_event(dm_content, event.pubkey) await publish_nostr_event(dm_event) async def handle_dirrect_message( - from_pubkey: str, event_id: str, msg: str + merchant_id: str, from_pubkey: str, event_id: str, msg: str ) -> Optional[str]: order, text_msg = order_from_json(msg) try: @@ -142,6 +145,13 @@ async def handle_dirrect_message( return await handle_new_order(PartialOrder(**order)) else: print("### text_msg", text_msg) + dm = PartialDirectMessage( + event_id=event_id, + message=text_msg, + public_key=from_pubkey, + incomming=True, + ) + await create_direct_message(merchant_id, dm) return None except Exception as ex: logger.warning(ex) diff --git a/views_api.py b/views_api.py index 6d561d8..8dc1810 100644 --- a/views_api.py +++ b/views_api.py @@ -594,6 +594,7 @@ async def api_stop(wallet: WalletTypeInfo = Depends(check_admin)): return {"success": True} + ######################################## HELPERS ########################################