From b79db3b306bdd84fa5ca7c4ba672363d69338887 Mon Sep 17 00:00:00 2001 From: Louis Date: Sat, 29 Jun 2024 14:02:58 +0200 Subject: [PATCH] docs: updated api.md and added readme --- README.md | 94 ++++++++++- assets/prisma-erd.svg | 2 + documentation/api.md | 367 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 418 insertions(+), 45 deletions(-) create mode 100644 assets/prisma-erd.svg diff --git a/README.md b/README.md index daf0d19..0c0371c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,95 @@ -# Lyve +![lyve logo](https://raw.githubusercontent.com/lyve-app/lyve-backend/main/assets/lyve_logo.svg) +## About the Project +> This is the backend codebase of the lyve platform + +Lyve is a livestreaming platform where users can create and watch livestreams. Viewers can engage with streamers through chat and by sending rewards, fostering a lively and interactive community. Lyve enhances the experience with gamification, offering achievements and promotion points that help streamers gain more visibility on the platform. + +### Techstack + +#### API + +[![API Technologies](https://skillicons.dev/icons?i=ts,express,nodejs,prisma,postgres,jest,rabbitmq,azure,githubactions,docker)](https://skillicons.dev) + +- Socketio + +Hosted on a Azure App Service + +#### Media-Server + +[![Media-Server Technologies](https://skillicons.dev/icons?i=ts,express,nodejs,rabbitmq,azure,docker)](https://skillicons.dev) + +- Mediasoup + +Hosted on a Azure VPS + +## Structure + +This codebase is a yarn workspace monorepo. + +There are two backends in this repo [api](https://github.com/lyve-app/lyve-backend/tree/main/apps/api) and [media-server](https://github.com/lyve-app/lyve-backend/tree/main/apps/media-server), both can be found in the `/apps` directory + +```txt +. +├── README.md +├── apps +│ ├── api +│ │ ├── Dockerfile +│ │ ├── jest.config.ts +│ │ ├── package.json +│ │ ├── prisma +│ │ │ ├── migrations +│ │ │ └── schema.prisma +│ │ ├── src +│ │ │ ├── app.ts +│ │ │ ├── config +│ │ │ ├── controller +│ │ │ ├── index.ts +│ │ │ ├── interfaces +│ │ │ ├── middleware +│ │ │ ├── routes +│ │ │ ├── service +│ │ │ ├── types +│ │ │ ├── utils +│ │ │ └── validations +│ │ ├── test +│ │ │ ├── integration +│ │ │ └── unit +│ │ ├── tsconfig.app.json +│ │ ├── tsconfig.json +│ │ ├── tsconfig.spec.json +│ │ ├── web.config +│ │ └── yarn.lock +│ └── media-server +│ ├── Dockerfile +│ ├── jest.config.ts +│ ├── package.json +│ ├── src +│ │ ├── app.ts +│ │ ├── config +│ │ ├── index.ts +│ │ ├── middleware +│ │ ├── types +│ │ └── utils +│ ├── test +│ ├── tsconfig.app.json +│ ├── tsconfig.json +│ ├── tsconfig.spec.json +│ ├── web.config +│ └── yarn.lock +├── commitlint.config.js +├── docker-compose.yml +├── package.json +└── yarn.lock +``` + +## Database + +![ERD](assets/prisma-erd.svg) + +## Contributing + + + + diff --git a/assets/prisma-erd.svg b/assets/prisma-erd.svg new file mode 100644 index 0000000..6029632 --- /dev/null +++ b/assets/prisma-erd.svg @@ -0,0 +1,2 @@ + +UserStringidStringusernameStringdispnameStringemailStringavatar_urlStringbioDateTimecreated_atDateTimeupdatedAtIntfollowerCountIntfollowingCountIntnumStreamsIntnum10minStreamsFloatminStreamedIntlevelIntpromotionPointsIntcoinsFollowsDateTimecreated_atStreamStringidStringserverIdBooleanactiveIntviewerCountStringpreviewImgUrlDateTimecreated_atDateTimeended_atFloatdurationStringgenreIntmostViewersNotificationStringidNotificationTypetypeStringstreamIdStringachievemntIdStringrewardIdStringuserWhoFiredEventStringmessageDateTimecreated_atDateTimeupdated_atAchievementStringidAchievementTypetypeStringnameIntlevelIntconditionIntpromotionPointsUserToAchievementIntprogressDateTimecreated_atDateTimeupdated_atRewardsStringidRewardTypetypeIntpointsStringsenderIdDateTimecreated_atfollowedByfollowingstreamerrecipientuserachievementreceiver \ No newline at end of file diff --git a/documentation/api.md b/documentation/api.md index c47fe81..d43b5ba 100644 --- a/documentation/api.md +++ b/documentation/api.md @@ -1116,33 +1116,79 @@ Error: ## Websocket Schnittstelle -### Live Chat +### Types + +```ts +type SocketCallback = (response?: SocketResponse) => void; + +interface SocketResponse { + success: boolean; + data: T | null; + error: { + name: string; + code: number; + msg: string; + }[]; +} +``` + +> The payloads also use Mediasoup datatypes. Further information on these data types can be found in the official Mediasoup and Mediasoup client documentation https://mediasoup.org/documentation/v3/. #### Client to Server -##### `"join"` +##### `"connect-transport"` -Lets the user join the chat room +Will send a signal over the API to the media-server to connects the client-side WebRTC transport with the server-side WebRTC transport **Payload** ```json -{} +{ + "data": { + "transportId": "transport id", + "dtlsParameters": DtlsParameters, + "direction": StreamSendDirection, + } +} ``` -**Acknowledgment:** Yes +##### `"send-track"` + +Will send a signal over the api to the media-server to instruct the mediasoup router to receive audio and video streams + +**Payload** + +```json +{ + "data": { + "transportId": "tranport id", + "direction": StreamSendDirection, // "send" or "recv" + "paused": boolean, + "kind": MediaKind, + "rtpParameters": RtpParameters, + "rtpCapabilities": RtpCapabilities, + "appData": AppData + } +} +``` + +##### `"get-recv-tracks"` + +Will send a signal over the api to the media-server to instruct the mediasoup router to send audio and video streams + +**Payload** ```json { "data": { - "viewerCount": 0 + "rtpCapabilities": RtpCapabilities } } ``` -##### `"leave"` +##### `"resume-consumers"` -Lets the user leave the chat room +Will send a signal over the api to the media-server to instruct the mediasoup router to unpause the video stream **Payload** @@ -1150,99 +1196,327 @@ Lets the user leave the chat room {} ``` -**Acknowledgment:** No +##### `"join_stream"` -##### `"sendMsg"` +Allows a client to join a stream. When a new peer requests to join, the API signals the media server. The media server then initiates the signaling process to connect the peer with the router. Additionally, the API adds the client to the WebSocket room, enabling interaction with specific WebSocket events related to the stream. -Broadcasts a message to all users in the same room +If the client is a viewer the API will broadcast a `"user_joined"` event to all clients in the stream. **Payload** ```json { "data": { - "msg": "..." + "streamId": "stream id" } } ``` -**Acknowledgment:** No +**Acknowledgment:** Yes + +Acknowledgment Data: + +```json +data: null +``` + +##### `"leave_stream"` + +Allows a client to leave a stream. API will send a event to the media-server to cleanup the websocket tranports, producers, and consumers of the peer. +If the client is the host of the stream the stream will end and the API will broadcast the `"stream-ended"` event. +If the client was a viewer the API will broadcast a `"user_leaved"` event to all clients in the stream. + +**Payload** + +```json +{ + "data": { + "streamId": "stream id" + } +} +``` + +##### `"send_msg"` + +Allows a client to send a message in the stream chat + +Message Types that are supported are: + +- Text +- GIF +- Sticker +- Emojis + +**Payload** + +```json +{ + "data": { + // only one is required (msg or gif) + "msg": "message", + "gif": { + "height": "100", + "width": "100", + "url": "gif url" + } + } +} +``` + +##### `"send_reward"` + +Allows a client to send a reward to the streamer + +**Payload** + +```json +{ + "data": { + "msg": "message", + "reward": { + "type": "" // RewardType (see prisma schema), + } + } +} +``` + +**Acknowledgment:** Yes + +Acknowledgment Data: + +```json +data: null +``` #### Server to Client -##### `"streamEnded"` +##### `"you-joined-as-streamer"` -Informs all users in the room that the stream has ended +Informs client that he joined a stream as streamer **Payload** ```json { "data": { - "ended_at": "" + "streamId": "stream id", + "routerRtpCapabilities": RtpCapabilities, + "recvTransportOptions": TransportOptions, + "sendTransportOptions": TransportOptions, } } ``` -**Acknowledgment:** No +##### `"you-joined-as-streamer"` -##### `"userJoined"` +Informs client that he joined a stream as streamer -Informs all users in the room that a new user has joined +**Payload** -**Receiving Payload** +```json +{ + "data": { + "streamId": "stream id", + "routerRtpCapabilities": RtpCapabilities, + "recvTransportOptions": TransportOptions, + } +} +``` + +##### `"get-recv-tracks-res"` + +Returns a list of consumer parameters as results of `"get-recv-tracks"` + +**Payload** ```json { "data": { - "viewerCount": 100 // for updating the viewer count + "consumerParametersArr": Consumer[], } } ``` -**Acknowledgment:** No +##### `"send-track-send-res"` + +Returns the results of `"send-track"` type: send -##### `"userLeaved"` +**Payload** -Informs all users in the room that a user leaved +```json +{ + "data": { + "id": "server-side transport id", + "error": "error msg" // or empty + } +} +``` -**Receiving Payload** +##### `"send-track-recv-res"` + +Returns the results of `"send-track"` type: recv + +**Payload** ```json { "data": { - "viewerCount": 100 // for updating the viewer count + "id": "server-side transport id", + "error": "error msg" // or empty } } ``` -**Acknowledgment:** No +##### `"connect-transport-send-res"` -##### `"newChatMsg"` +Returns the results of `"connect-transport"` type: send -Broadcasts message to all users in the room that a new user has joined +**Payload** -**Receiving Payload** +```json +{ + "data": { + "error": "error msg" // or empty + } +} +``` + +##### `"connect-transport-recv-res"` + +Returns the results of `"connect-transport"` type: recv + +**Payload** ```json { "data": { - "id": "", // msg id - "msg": "" // maybe this is later updated to tokens: MessageToken[] - "sender": { - "id": "", - "username": "", - "avatar_url": "" + "error": "error msg" // or empty + } +} +``` + +##### `"you-left-stream"` + +Informs the clients that `"leave_stream"` was successful + +**Payload** + +```json +{} +``` + +##### `"resume-consumers-done"` + +Returns the results of `"resume-consumers"` + +**Payload** + +```json +{ + "data": { + "error": "error msg" // or empty + } +} +``` + +##### `"user_joined"` + +Informs all users in the stream that a new user has joined + +**Payload** + +```json +{ + "data": { + "user": { + "id": "user id", + "username": "username", + "dispname": "dispname", + "avatar_url": "url" // or null } } } ``` -**Acknowledgment:** No +##### `"user_leaved"` -##### `"receivedReward"` +Informs all users in the stream that a new user has leaved -Broadcasts to all users in the room user gifted a reward +**Payload** + +```json +{ + "data": { + "user": { + "id": "user id", + "username": "username", + "dispname": "dispname", + "avatar_url": "url" // or null + } + } +} +``` + +##### `"viewer_count"` + +Sends the current viewer count of a stream. Will be send every time a user joined or leaved + +**Payload** + +```json +{ + "data": { + "viewerCount": 100 + } +} +``` + +##### `"stream_ended"` + +Informs all viewer that the current stream ended. Will be send if the streamer ends the stream. + +**Payload** + +```json +{ + "data": { + "ended_at": Date, // as string + "duration": 100, // duration of the stream in seconds + } +} +``` + +##### `"new_msg"` + +Broadcasts message to all users in the stream + +**Payload** + +```json +{ + "data": { + "id": "", // msg id + // either msg or gif + "msg": "", + "gif": { + "height": "100", + "width": "100", + "url": "gif url" + }, + "sender": { + "id": "user id", + "username": "username", + "dispname": "dispname", + "avatar_url": "url" + }, + "created_at": "date time" // as string + } +} +``` + +##### `"resv_reward"` + +Broadcasts that a viewer gifted a reward to a streamer **Receiving Payload** @@ -1256,12 +1530,17 @@ Broadcasts to all users in the room user gifted a reward "points": "" // the promotion points one receives for receiving the reward }, "sender": { - "id": "", - "username": "", - "avatar_url": "" + "id": "user id", + "username": "username", + "dispname": "dispname", + "avatar_url": "url" + }, + "receiver": { + "id": "user id", + "username": "username", + "dispname": "dispname", + "avatar_url": "url" } } } ``` - -**Acknowledgment:** No