tangled
alpha
login
or
join now
bad-example.com
/
spacedust-utils
6
fork
atom
demos for spacedust
6
fork
atom
overview
issues
pulls
pipelines
hello terrible terrible atproto hack
bad-example.com
9 months ago
97b5a657
a2ed5896
+100
-54
3 changed files
expand all
collapse all
unified
split
server
index.js
web-content
index.html
service-worker.js
+29
-8
server/index.js
···
49
49
50
50
const handleSubscribe = async (req, res) => {
51
51
const body = await getRequesBody(req);
52
52
-
console.log('got body', body);
53
53
-
doStuff(JSON.parse(body));
52
52
+
const { did, sub } = JSON.parse(body);
53
53
+
doStuff(did, sub);
54
54
res.setHeader('Content-Type', 'application/json');
55
55
res.writeHead(201);
56
56
res.end('{"oh": "hi"}');
57
57
}
58
58
59
59
-
const doStuff = sub => {
60
60
-
let n = 0;
61
61
-
setInterval(() => {
62
62
-
webpush.sendNotification(sub, `oh hi: ${n}`);
63
63
-
n += 1;
64
64
-
}, 2000);
59
59
+
const doStuff = (did, sub) => {
60
60
+
console.log('subscribing for', did);
61
61
+
const ws = new WebSocket(`wss://spacedust.microcosm.blue/subscribe?instant=true&wantedSubjectDids=${did}`);
62
62
+
63
63
+
ws.addEventListener('message', event => {
64
64
+
console.log('got', event.data);
65
65
+
let data;
66
66
+
try {
67
67
+
data = JSON.parse(event.data);
68
68
+
} catch (err) {
69
69
+
console.error(err);
70
70
+
return;
71
71
+
}
72
72
+
const { link: { source, source_record } } = data;
73
73
+
const title = `new ${source}`;
74
74
+
const body = `from ${source_record}`;
75
75
+
webpush.sendNotification(sub, JSON.stringify({ title, body }));
76
76
+
});
77
77
+
78
78
+
ws.addEventListener('error', err => {
79
79
+
console.log('uh oh', err);
80
80
+
});
81
81
+
82
82
+
ws.addEventListener('close', () => {
83
83
+
console.log('closed. bye!');
84
84
+
});
85
85
+
65
86
}
66
87
67
88
const requestListener = pubkey => (req, res) => {
+43
-12
server/web-content/index.html
···
7
7
8
8
hiiiiii
9
9
10
10
+
<label><input id="did" placeholder="did:plc:..." /> DID</label>
10
11
<button id="subscribe">subscribe</button>
11
12
12
13
<p id="error-message"></p>
···
16
17
const err = m => {
17
18
document.getElementById('error-message').textContent = m;
18
19
throw new Error(m);
20
20
+
};
21
21
+
const clearErr = () => {
22
22
+
document.getElementById('error-message').textContent = '';
19
23
};
20
24
21
25
if (!('serviceWorker' in navigator)) err('service worker not supported');
···
86
90
}
87
91
88
92
document.getElementById('subscribe').addEventListener('click', async () => {
89
89
-
const perm = await askPermission();
90
90
-
console.log({ perm });
91
91
-
const sub = await subscribeUserToPush();
92
92
-
console.log({ sub });
93
93
-
const res = await fetch('/subscribe', {
94
94
-
method: 'POST',
95
95
-
body: JSON.stringify(sub),
96
96
-
headers: {
97
97
-
'Content-Type': 'application/json',
98
98
-
},
99
99
-
});
100
100
-
console.log('res', res);
93
93
+
clearErr();
94
94
+
95
95
+
const did = document.getElementById('did').value;
96
96
+
if (!did.startsWith('did:')) err('should start with `did:`');
97
97
+
98
98
+
let perm;
99
99
+
try {
100
100
+
perm = await askPermission();
101
101
+
} catch (err) {
102
102
+
console.error(err);
103
103
+
err('notification permissions are needed to give you notifications');
104
104
+
}
105
105
+
106
106
+
let sub;
107
107
+
try {
108
108
+
sub = await subscribeUserToPush();
109
109
+
} catch (err) {
110
110
+
console.error(err);
111
111
+
err('failed to subscribe for notification');
112
112
+
}
113
113
+
114
114
+
let res;
115
115
+
try {
116
116
+
res = await fetch('/subscribe', {
117
117
+
method: 'POST',
118
118
+
body: JSON.stringify({ did, sub }),
119
119
+
headers: {
120
120
+
'Content-Type': 'application/json',
121
121
+
},
122
122
+
});
123
123
+
} catch (err) {
124
124
+
console.error(err);
125
125
+
err('failed to create subscription with backend');
126
126
+
}
127
127
+
128
128
+
if (!res.ok) {
129
129
+
console.error(await res.text());
130
130
+
err('not-ok response trying to create backend subscription');
131
131
+
}
101
132
});
102
133
103
134
</script>
+28
-34
server/web-content/service-worker.js
···
16
16
}
17
17
18
18
self.addEventListener('push', function(event) {
19
19
-
console.log('Received a push message', event);
19
19
+
const { title, body } = event.data.json();
20
20
21
21
// Display notification or handle data
22
22
// Example: show a notification
23
23
-
const title = 'New Notification';
24
24
-
const body = event.data.text();
25
25
-
const icon = '/images/icon.png';
26
26
-
const tag = 'simple-push-demo-notification-tag';
23
23
+
// const title = 'New Notification';
24
24
+
// const body = event.data.text();
25
25
+
// const icon = '/images/icon.png';
26
26
+
// const tag = 'simple-push-demo-notification-tag';
27
27
28
28
-
event.waitUntil(
29
29
-
self.registration.showNotification(title, {
30
30
-
body: body,
31
31
-
icon: icon,
32
32
-
tag: tag
33
33
-
})
34
34
-
);
28
28
+
event.waitUntil(self.registration.showNotification(title, { body }));
35
29
36
30
// Attempt to resubscribe after receiving a notification
37
37
-
event.waitUntil(resubscribeToPush());
31
31
+
// event.waitUntil(resubscribeToPush());
38
32
});
39
33
40
40
-
function resubscribeToPush() {
41
41
-
return self.registration.pushManager.getSubscription()
42
42
-
.then(function(subscription) {
43
43
-
if (subscription) {
44
44
-
return subscription.unsubscribe();
45
45
-
}
46
46
-
})
47
47
-
.then(function() {
48
48
-
return self.registration.pushManager.subscribe({
49
49
-
userVisibleOnly: true,
50
50
-
applicationServerKey: urlBase64ToUint8Array(PUBKEY)
51
51
-
});
52
52
-
})
53
53
-
.then(function(subscription) {
54
54
-
console.log('Resubscribed to push notifications:', subscription);
55
55
-
// Optionally, send new subscription details to your server
56
56
-
})
57
57
-
.catch(function(error) {
58
58
-
console.error('Failed to resubscribe:', error);
59
59
-
});
60
60
-
}
34
34
+
// function resubscribeToPush() {
35
35
+
// return self.registration.pushManager.getSubscription()
36
36
+
// .then(function(subscription) {
37
37
+
// if (subscription) {
38
38
+
// return subscription.unsubscribe();
39
39
+
// }
40
40
+
// })
41
41
+
// .then(function() {
42
42
+
// return self.registration.pushManager.subscribe({
43
43
+
// userVisibleOnly: true,
44
44
+
// applicationServerKey: urlBase64ToUint8Array(PUBKEY)
45
45
+
// });
46
46
+
// })
47
47
+
// .then(function(subscription) {
48
48
+
// console.log('Resubscribed to push notifications:', subscription);
49
49
+
// // Optionally, send new subscription details to your server
50
50
+
// })
51
51
+
// .catch(function(error) {
52
52
+
// console.error('Failed to resubscribe:', error);
53
53
+
// });
54
54
+
// }