mirror of
https://github.com/RoboSats/robosats.git
synced 2025-08-05 20:00:25 +00:00
Subscribe notifications
This commit is contained in:
@ -53,10 +53,10 @@ class Nostr:
|
|||||||
Tag.parse(
|
Tag.parse(
|
||||||
[
|
[
|
||||||
"order_id",
|
"order_id",
|
||||||
f"{config("COORDINATOR_ALIAS", cast=str)}#{order.id}",
|
f"{config("COORDINATOR_ALIAS", cast=str).lower()}#{order.id}",
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
Tag.parse(["status", Order.Status(order.status).label]),
|
Tag.parse(["status", order.status]),
|
||||||
]
|
]
|
||||||
|
|
||||||
await client.send_private_msg(PublicKey.parse(robot.nostr_pubkey), text, tags)
|
await client.send_private_msg(PublicKey.parse(robot.nostr_pubkey), text, tags)
|
||||||
|
@ -37,7 +37,7 @@ class Notifications:
|
|||||||
self.save_message(order, robot, title, description)
|
self.save_message(order, robot, title, description)
|
||||||
if robot.nostr_pubkey:
|
if robot.nostr_pubkey:
|
||||||
nostr_send_notification_event.delay(
|
nostr_send_notification_event.delay(
|
||||||
robot_id=robot.id, order_id=order.id, text=description
|
robot_id=robot.id, order_id=order.id, text=title
|
||||||
)
|
)
|
||||||
if robot.telegram_enabled:
|
if robot.telegram_enabled:
|
||||||
self.send_telegram_message(robot.telegram_chat_id, title, description)
|
self.send_telegram_message(robot.telegram_chat_id, title, description)
|
||||||
|
@ -3,6 +3,8 @@ import { Box, Drawer, List, ListItem, Typography, useTheme } from '@mui/material
|
|||||||
import { AppContext, type UseAppStoreType } from '../../../contexts/AppContext';
|
import { AppContext, type UseAppStoreType } from '../../../contexts/AppContext';
|
||||||
import { RoboSatsTextIcon } from '../../../components/Icons';
|
import { RoboSatsTextIcon } from '../../../components/Icons';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { UseFederationStoreType, FederationContext } from '../../../contexts/FederationContext';
|
||||||
|
import { GarageContext, UseGarageStoreType } from '../../../contexts/GarageContext';
|
||||||
|
|
||||||
interface NotificationsDrawerProps {
|
interface NotificationsDrawerProps {
|
||||||
show: boolean;
|
show: boolean;
|
||||||
@ -12,11 +14,25 @@ interface NotificationsDrawerProps {
|
|||||||
const NotificationsDrawer = ({ show, setShow }: NotificationsDrawerProps): React.JSX.Element => {
|
const NotificationsDrawer = ({ show, setShow }: NotificationsDrawerProps): React.JSX.Element => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { page } = useContext<UseAppStoreType>(AppContext);
|
const { page, settings } = useContext<UseAppStoreType>(AppContext);
|
||||||
|
const { federation } = useContext<UseFederationStoreType>(FederationContext);
|
||||||
|
const { garage } = useContext<UseGarageStoreType>(GarageContext);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setShow(false);
|
setShow(false);
|
||||||
}, [page]);
|
}, [page]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (settings.connection === 'nostr' && !federation.loading) loadNotifciationsNostr();
|
||||||
|
}, [settings.connection, federation.loading]);
|
||||||
|
|
||||||
|
const loadNotifciationsNostr = (): void => {
|
||||||
|
federation.roboPool.subscribeNotifications(garage, {
|
||||||
|
onevent: (_event) => {},
|
||||||
|
oneose: () => {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer anchor='right' open={show} onClose={() => setShow(false)}>
|
<Drawer anchor='right' open={show} onClose={() => setShow(false)}>
|
||||||
<Box sx={{ width: 270, height: '100%' }} role='presentation'>
|
<Box sx={{ width: 270, height: '100%' }} role='presentation'>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { type Event } from 'nostr-tools';
|
import { nip17, type Event } from 'nostr-tools';
|
||||||
import { type Coordinator, type Settings } from '../../models';
|
import { Garage, type Coordinator, type Settings } from '../../models';
|
||||||
import defaultFederation from '../../../static/federation.json';
|
import defaultFederation from '../../../static/federation.json';
|
||||||
import { websocketClient, type WebsocketConnection, WebsocketState } from '../Websocket';
|
import { websocketClient, type WebsocketConnection, WebsocketState } from '../Websocket';
|
||||||
import thirdParties from '../../../static/thirdparties.json';
|
import thirdParties from '../../../static/thirdparties.json';
|
||||||
@ -100,14 +100,17 @@ class RoboPool {
|
|||||||
}
|
}
|
||||||
const authors = scope.map((f) => f.nostrHexPubkey).filter((item) => item !== undefined);
|
const authors = scope.map((f) => f.nostrHexPubkey).filter((item) => item !== undefined);
|
||||||
|
|
||||||
|
const subscribeBookPending = 'subscribeBookPending';
|
||||||
|
const subscribeBookSuccess = 'subscribeBookPending';
|
||||||
|
|
||||||
const requestPending = [
|
const requestPending = [
|
||||||
'REQ',
|
'REQ',
|
||||||
'subscribeBookPending',
|
subscribeBookPending,
|
||||||
{ authors, kinds: [38383], '#s': ['pending'] },
|
{ authors, kinds: [38383], '#s': ['pending'] },
|
||||||
];
|
];
|
||||||
const requestSuccess = [
|
const requestSuccess = [
|
||||||
'REQ',
|
'REQ',
|
||||||
'subscribeBookSuccess',
|
subscribeBookSuccess,
|
||||||
{
|
{
|
||||||
authors,
|
authors,
|
||||||
kinds: [38383],
|
kinds: [38383],
|
||||||
@ -118,6 +121,9 @@ class RoboPool {
|
|||||||
|
|
||||||
this.messageHandlers.push((_url: string, messageEvent: MessageEvent) => {
|
this.messageHandlers.push((_url: string, messageEvent: MessageEvent) => {
|
||||||
const jsonMessage = JSON.parse(messageEvent.data);
|
const jsonMessage = JSON.parse(messageEvent.data);
|
||||||
|
|
||||||
|
if (![subscribeBookPending, subscribeBookSuccess].includes(jsonMessage[1])) return;
|
||||||
|
|
||||||
if (jsonMessage[0] === 'EVENT') {
|
if (jsonMessage[0] === 'EVENT') {
|
||||||
const event: Event = jsonMessage[2];
|
const event: Event = jsonMessage[2];
|
||||||
const network = event.tags.find((e) => e[0] === 'network');
|
const network = event.tags.find((e) => e[0] === 'network');
|
||||||
@ -135,14 +141,18 @@ class RoboPool {
|
|||||||
.map((f) => f.nostrHexPubkey)
|
.map((f) => f.nostrHexPubkey)
|
||||||
.filter((item) => item !== undefined);
|
.filter((item) => item !== undefined);
|
||||||
|
|
||||||
|
const subscribeRatings = `subscribeRatings${id ?? ''}`;
|
||||||
const requestRatings = [
|
const requestRatings = [
|
||||||
'REQ',
|
'REQ',
|
||||||
`subscribeRatings${id ?? ''}`,
|
subscribeRatings,
|
||||||
{ kinds: [31986], '#p': pubkeys ?? defaultPubkeys, since: 1746316800 },
|
{ kinds: [31986], '#p': pubkeys ?? defaultPubkeys, since: 1746316800 },
|
||||||
];
|
];
|
||||||
|
|
||||||
this.messageHandlers.push((_url: string, messageEvent: MessageEvent) => {
|
this.messageHandlers.push((_url: string, messageEvent: MessageEvent) => {
|
||||||
const jsonMessage = JSON.parse(messageEvent.data);
|
const jsonMessage = JSON.parse(messageEvent.data);
|
||||||
|
|
||||||
|
if (subscribeRatings !== jsonMessage[1]) return;
|
||||||
|
|
||||||
if (jsonMessage[0] === 'EVENT') {
|
if (jsonMessage[0] === 'EVENT') {
|
||||||
events.onevent(jsonMessage[2]);
|
events.onevent(jsonMessage[2]);
|
||||||
} else if (jsonMessage[0] === 'EOSE') {
|
} else if (jsonMessage[0] === 'EOSE') {
|
||||||
@ -152,18 +162,38 @@ class RoboPool {
|
|||||||
this.sendMessage(JSON.stringify(requestRatings));
|
this.sendMessage(JSON.stringify(requestRatings));
|
||||||
};
|
};
|
||||||
|
|
||||||
subscribeChat = (hexPubKeys: string[], since: number, events: RoboPoolEvents): void => {
|
subscribeNotifications = (garage: Garage, events: RoboPoolEvents): void => {
|
||||||
const requestRatings = ['REQ', 'subscribeChat', { kinds: [1059], '#p': hexPubKeys, since }];
|
const hexPubKeys = Object.values(garage.slots).map((s) => s.nostrPubKey);
|
||||||
|
|
||||||
|
if (hexPubKeys.length === 0) return;
|
||||||
|
|
||||||
|
const subscribeChat = 'subscribeChat';
|
||||||
|
const requestNotifications = ['REQ', subscribeChat, { kinds: [1059], '#p': hexPubKeys }];
|
||||||
|
|
||||||
this.messageHandlers.push((_url: string, messageEvent: MessageEvent) => {
|
this.messageHandlers.push((_url: string, messageEvent: MessageEvent) => {
|
||||||
const jsonMessage = JSON.parse(messageEvent.data);
|
const jsonMessage = JSON.parse(messageEvent.data);
|
||||||
|
|
||||||
|
if (subscribeChat !== jsonMessage[1]) return;
|
||||||
|
|
||||||
if (jsonMessage[0] === 'EVENT') {
|
if (jsonMessage[0] === 'EVENT') {
|
||||||
events.onevent(jsonMessage[2]);
|
const wrappedEvent: Event = jsonMessage[2];
|
||||||
|
|
||||||
|
console.log('wrappedEvent', wrappedEvent);
|
||||||
|
|
||||||
|
const hexPubKey = wrappedEvent.tags.find((t) => t[0] == 'p')?.[1];
|
||||||
|
|
||||||
|
const slot = Object.values(garage.slots).find((s) => s.nostrPubKey == hexPubKey);
|
||||||
|
|
||||||
|
if (slot?.nostrSecKey) {
|
||||||
|
const unwrappedEvent = nip17.unwrapEvent(wrappedEvent, slot.nostrSecKey);
|
||||||
|
events.onevent(unwrappedEvent as Event);
|
||||||
|
}
|
||||||
} else if (jsonMessage[0] === 'EOSE') {
|
} else if (jsonMessage[0] === 'EOSE') {
|
||||||
events.oneose();
|
events.oneose();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.sendMessage(JSON.stringify(requestRatings));
|
|
||||||
|
this.sendMessage(JSON.stringify(requestNotifications));
|
||||||
};
|
};
|
||||||
|
|
||||||
sendEvent = (event: Event): void => {
|
sendEvent = (event: Event): void => {
|
||||||
|
Reference in New Issue
Block a user