Skip to content

Commit

Permalink
feat: 通知を送信できるように (#163)
Browse files Browse the repository at this point in the history
  • Loading branch information
laminne committed Aug 9, 2023
1 parent ddbf271 commit 6bf86b9
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 1 deletion.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@
},
"dependencies": {
"@fastify/cors": "^8.3.0",
"@fastify/websocket": "^8.2.0",
"@prisma/client": "5.0.0",
"@types/node": "^20.4.1",
"@types/ws": "^8.5.5",
"date-fns": "^2.30.0",
"esbuild": "^0.18.17",
"fastify": "^4.20.0",
"pino": "^8.14.2",
"typescript": "^5.1.6"
"typescript": "^5.1.6",
"ws": "^8.13.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^6.1.0",
Expand Down
38 changes: 38 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/server/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export async function StartServer(port: number) {
logger.info(q.body, "inbox");
r.code(503).send();
});

try {
await app.listen({ port: port, host: "0.0.0.0" });
return;
Expand Down
54 changes: 54 additions & 0 deletions src/server/ws/websocket_handlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as http from "http";
import WebSocket, { WebSocketServer } from "ws";
import { IncomingMessage } from "http";
import { Snowflake } from "../../helpers/id_generator.js";
import logger from "../../helpers/logger.js";

export interface NotificationSendReceiver {
Send(payload: string, to: string): Promise<void>;
}

export class DummyNotificationSendReceiver implements NotificationSendReceiver {
async Send(): Promise<void> {
return;
}
}

export class WebSocketNotificationSendReceiver
implements NotificationSendReceiver
{
private ws: WebSocket.Server<
typeof WebSocket.WebSocket,
typeof IncomingMessage
>;
private connections: Map<Snowflake, WebSocket.WebSocket>;

constructor(server: http.Server) {
this.ws = new WebSocketServer({ noServer: true });
server.on("upgrade", (q, so, head) => {
// fixme: q.headers.authorizationを使って認証とユーザーの検証をする
this.ws.handleUpgrade(q, so, head, (w) => {
this.ws.emit("connection", w, q);
this.connections.set("123" as Snowflake, w);
});
});

this.connections = new Map<Snowflake, WebSocket.WebSocket>();

this.ws.on("connection", (w) => {
logger.info("connect");
w.on("message", () => {
console.log("received!");
});
});
}

async Send(payload: string, to: string): Promise<void> {
const cli = this.connections.get(to as Snowflake);
if (!cli) {
return;
}
cli.send(payload);
return;
}
}
35 changes: 35 additions & 0 deletions src/service/notification/@types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export interface CommonNotificationObject<T, U> {
type: T;
payload: U;
}

export type FollowedNotification = CommonNotificationObject<
"Followed",
FollowedNotificationPayload
>;

export interface FollowedNotificationPayload {
id: string;
nickName: string;
iconImageURL: string;
}

export type FollowSuccessNotification = CommonNotificationObject<
"FollowSuccess",
FollowSuccessNotificationPayload
>;
export interface FollowSuccessNotificationPayload {
id: string;
nickName: string;
iconImageURL: string;
}

export type ReactionNotification = CommonNotificationObject<
"Reaction",
ReactionNotificationPayload
>;
export interface ReactionNotificationPayload {
id: string;
nickName: string;
iconImageURL: string;
}
58 changes: 58 additions & 0 deletions src/service/notification/sender.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { NotificationSendReceiver } from "../../server/ws/websocket_handlers.js";
import { UserData } from "../data/user.js";
import { Snowflake } from "../../helpers/id_generator.js";
import {
FollowedNotification,
FollowSuccessNotification,
ReactionNotification,
} from "./@types.js";

export class NotificationSenderService {
private sender: NotificationSendReceiver;
constructor(sender: NotificationSendReceiver) {
this.sender = sender;
}

// フォローされた通知
async Followed(u: UserData, to: Snowflake) {
const payload: FollowedNotification = {
type: "Followed",
payload: {
id: u.id,
nickName: u.nickName,
iconImageURL: u.iconImageURL,
},
};
const serialized = JSON.stringify(payload);
await this.sender.Send(serialized, to);
return;
}
// フォローが成功した通知
async FollowSuccess(u: UserData, to: Snowflake) {
const payload: FollowSuccessNotification = {
type: "FollowSuccess",
payload: {
id: u.id,
nickName: u.nickName,
iconImageURL: u.iconImageURL,
},
};
const serialized = JSON.stringify(payload);
await this.sender.Send(serialized, to);
return;
}
// リアクションされた通知
async Reaction(u: UserData, to: Snowflake) {
const payload: ReactionNotification = {
type: "Reaction",
payload: {
id: u.id,
nickName: u.nickName,
iconImageURL: u.iconImageURL,
},
};
const serialized = JSON.stringify(payload);
await this.sender.Send(serialized, to);
return;
}
}

0 comments on commit 6bf86b9

Please sign in to comment.