77 lines
No EOL
1.6 KiB
TypeScript
77 lines
No EOL
1.6 KiB
TypeScript
import type {
|
|
AnyLanyardPayload,
|
|
LanyardInitStatePayload,
|
|
LanyardPayload,
|
|
LanyardPresence,
|
|
LanyardPresenceUpdatePayload
|
|
} from "types/lanyard";
|
|
|
|
export class Lanyard {
|
|
private socket: WebSocket;
|
|
private readonly userId: string;
|
|
private readonly updateCallback: (presence: LanyardPresence) => void;
|
|
private heartbeatInterval?: number;
|
|
|
|
constructor(
|
|
userId: string,
|
|
updateCallback: (presence: LanyardPresence) => void
|
|
) {
|
|
this.userId = userId;
|
|
this.updateCallback = updateCallback;
|
|
this.socket = new WebSocket("wss://api.lanyard.rest/socket");
|
|
this.initialize();
|
|
}
|
|
|
|
private send(data: AnyLanyardPayload) {
|
|
this.socket.send(JSON.stringify(data));
|
|
}
|
|
|
|
private initialize() {
|
|
this.socket.onmessage = event => {
|
|
const payload: LanyardPayload = JSON.parse(event.data);
|
|
switch (payload.op) {
|
|
case 1: {
|
|
// Initialize
|
|
this.send({
|
|
op: 2,
|
|
d: {
|
|
subscribe_to_ids: [this.userId]
|
|
}
|
|
});
|
|
|
|
this.send({ op: 3 });
|
|
|
|
const interval =
|
|
"heartbeat_interval" in payload.d
|
|
? payload.d.heartbeat_interval
|
|
: 30000;
|
|
|
|
this.heartbeatInterval = window.setInterval(() => {
|
|
this.send({ op: 3 });
|
|
}, interval);
|
|
break;
|
|
}
|
|
case 0: {
|
|
const typedPayload = payload as
|
|
| LanyardInitStatePayload
|
|
| LanyardPresenceUpdatePayload;
|
|
|
|
const presence =
|
|
typedPayload.t === "INIT_STATE"
|
|
? typedPayload.d[this.userId]
|
|
: typedPayload.d;
|
|
|
|
this.updateCallback(presence);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
public close() {
|
|
if (this.heartbeatInterval) {
|
|
clearInterval(this.heartbeatInterval);
|
|
}
|
|
this.socket.close();
|
|
}
|
|
} |