{"id":13495877,"url":"https://github.com/netless-io/flat-server","last_synced_at":"2025-05-15T01:09:22.292Z","repository":{"id":36978575,"uuid":"317419225","full_name":"netless-io/flat-server","owner":"netless-io","description":"A Node.js server for the Agora Flat open source classroom.","archived":false,"fork":false,"pushed_at":"2025-03-26T08:34:02.000Z","size":5245,"stargazers_count":661,"open_issues_count":25,"forks_count":271,"subscribers_count":18,"default_branch":"main","last_synced_at":"2025-04-13T23:53:54.285Z","etag":null,"topics":["agora","agora-flat","flat","flat-server","nodejs","online-classroom"],"latest_commit_sha":null,"homepage":"https://flat.whiteboard.agora.io","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/netless-io.png","metadata":{"files":{"readme":"README-zh.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-12-01T03:57:28.000Z","updated_at":"2025-03-26T07:56:46.000Z","dependencies_parsed_at":"2024-01-02T02:45:34.058Z","dependency_job_id":"556c91f4-cbf0-458b-8529-e9fbe9751005","html_url":"https://github.com/netless-io/flat-server","commit_stats":{"total_commits":746,"total_committers":20,"mean_commits":37.3,"dds":"0.23860589812332444","last_synced_commit":"9581bb43ebbeb20e7e7ce785d49adfc5d24ca432"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netless-io%2Fflat-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netless-io%2Fflat-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netless-io%2Fflat-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/netless-io%2Fflat-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/netless-io","download_url":"https://codeload.github.com/netless-io/flat-server/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254254043,"owners_count":22039792,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agora","agora-flat","flat","flat-server","nodejs","online-classroom"],"created_at":"2024-07-31T19:01:39.158Z","updated_at":"2025-05-15T01:09:17.286Z","avatar_url":"https://github.com/netless-io.png","language":"TypeScript","readme":"# Agora Flat Server\n\n项目 flat-server 是 [Agora Flat](https://github.com/netless-io/flat) 开源教室搭配使用的 `Node.js` 后端。主要是用于响应 Flat 前端的请求：\n\n## 特性\n\n- 帐户系统\n    - [x] 微信登陆\n    - [x] Github 登陆\n    - [x] 谷歌登陆\n- 房间管理\n    - [x] 预定房间\n    - [x] 周期性房间\n- [x] 互动白板、实时音视频（RTC）、即时消息（RTM）签名鉴权\n- [x] 云端录制回放\n- [x] 多媒体课件云存储（云盘）\n\n## 本地开发\n\n通过以下方式可以让 flat-server 在本地中运行起来：\n\n### 安装\n\n```shell\nyarn install --frozen-lockfile\n```\n\n### 配置环境变量\n\n1. 创建文件 `config/development.local.yaml`\n2. 按照文件 `config/defaults.yaml` 的格式添加环境变量。\n\n- 环境变量值可参考下方: [环境变量值参考](#环境变量值参考)。\n\n### 运行项目\n\n1. 项目根目录执行：\n\n```shell\n   yarn run start\n```\n\n2. 打开另一个控制台，执行：\n\n```shell\n   node ./dist/index.js\n```\n\n如果启动成功，那么控制台应该会出现 `ready on http://0.0.0.0:80`。\n\n## 部署\n\n本地开发不需要部署。如果需要上线，依据你习惯的方式部署。\n\n\u003e **Warning**\n\u003e 如果你之前部署过此项目, 请先查看 [迁移文档](./scripts/migration/README-zh.md)\n\n## 环境变量值参考\n\n```yaml\nserver:\n    # server 启动端口\n    port: 80\n\nredis:\n    # Redis 连接地址 \n    host:\n    # Redis 连接端口\n    port:\n    # Redis 连接用户名\n    username:\n    # Redis 连接密码\n    password:\n    # Redis 连接 db 名\n    db:\n    # 基于 Redis 实现的延迟队列 db 名\n    queueDB:\n\nmysql:\n    # MySQL 连接地址\n    host:\n    # MySQL 连接端口\n    port:\n    # MySQL 用户名\n    username:\n    # MySQL 密码\n    password:\n    # MySQL 要连接的数据库名\n    db:\n\njwt:\n    # JWT 秘钥\n    secret:\n    # JWT 加密算法，见: https://github.com/auth0/node-jsonwebtoken/tree/d71e383862fc735991fd2e759181480f066bf138#algorithms-supported\n    algorithms:\n\n# 所服务的前端地址\nwebsite: https://flat-web-dev.whiteboard.agora.io\n\nlog:\n    # Log 日志路径，详情见: https://github.com/netless-io/flat-server/blob/main/src/utils/EnvVariable.ts\n    pathname: \"{{PROJECT_DIR}}/logs\"\n    # Log 文件名称，详情见: https://github.com/netless-io/flat-server/blob/main/src/utils/EnvVariable.ts\n    filename: \"{{DAY_DATE}}\"\n\ncloud_storage:\n    # 云盘同一时间上传文件数，默认 3\n    concurrent: 3\n    # 云盘上传单个文件大小最大值，默认 500M\n    single_file_size: 524288000\n    # 云盘总量最大值，默认 2G\n    total_size: 2147483648\n    # 云盘上传路径的前缀，默认 cloud-storage，前后不能有 /\n    prefix_path: cloud-storage\n    # 云盘支持上传的文件扩展名\n    allow_file_suffix:\n        - ppt\n        - pptx\n        - doc\n        - docx\n        - pdf\n        - png\n        - jpg\n        - jpeg\n        - gif\n        - mp3\n        - mp4\n\nuser:\n    avatar:\n        # 最大大小。默认： 5M\n        size: 5242880\n        # 用户支持上传的图片后缀\n        allow_suffix:\n            - png\n            - jpg\n            - jpeg\n\noauth:\n    logo:\n        # 上传 logo 在 oss 中的路径。默认为：oauth-logo（前后不能有 /）\n        prefix_path: oauth-logo\n        # 最大大小。默认：5M\n        size: 5242880\n        # logo 支持上传的图片后缀\n        allow_suffix:\n            - png\n            - jpg\n            - jpeg\n\nlogin:\n    wechat:\n        # 见: https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html\n        web:\n            # 是否开启 web/desktop 端微信登录\n            enable: false\n            # App ID\n            app_id:\n            # App 秘钥\n            app_secret:\n        # 见: https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Login/Development_Guide.html\n        mobile:\n            # 是否开启移动端端微信登录\n            enable: false\n            # App ID\n            app_id:\n            # App 秘钥\n            app_secret:\n    # 见: https://docs.github.com/cn/developers/apps/building-oauth-apps/authorizing-oauth-apps\n    github:\n        # 是否开启 GitHub 登录\n        enable: false\n        # GitHub Client ID\n        client_id:\n        # GitHub Client Secret\n        client_secret:\n    # 开发中，见: https://developers.google.com/identity/protocols/oauth2\n    google:\n        # 是否开启 Google 登录\n        enable: false\n        # Google Client ID\n        client_id:\n        # Google Client Secret\n        client_secret:\n        # 回调地址\n        redirect_uri:\n    apple:\n        # 是否开启 apple 登录\n        enable: false\n    # 暂不对外开放\n    agora:\n        # 是否开启 Agora 登录\n        enable: false\n        # Agora Client ID\n        client_id:\n        # Agora Client Secret\n        client_secret:\n        # Phone message login\n    sms:\n        # 是否开启 SMS 登录\n        enable: true\n        # 是否强制开启绑定手机号\n        force: false\n        # 只有 server.env 为 dev 时生效\n        # 需要自己执行 MYSQL 以插入用户\n        # INSERT INTO user_phone (version, user_uuid, user_name, phone_number) VALUES (1, 'uuid', 'name', 'phone');\n        # INSERT INTO users (version, user_uuid, user_name, user_password, avatar_url) VALUES (1, 'uuid', 'name', '', 'url');\n        test_users:\n            -   phone:\n                code:\n        chinese_mainland:\n            # 见:  https://help.aliyun.com/document_detail/419273.htm?spm=a2c4g.11186623.0.0.34371d58IYPbs3\n            access_id:\n            access_secret:\n            template_code:\n            sign_name:\n        # 香港、澳门、台湾\n        hmt:\n            access_id:\n            access_secret:\n            template_code:\n            sign_name:\n        global:\n            access_id:\n            access_secret:\n            template_code:\n            sign_name:\n\nagora:\n    # 用于 RTC 与 RTM。见: https://docs.agora.io/cn/Agora%20Platform/get_appid_token?platform=All%20Platforms\n    app:\n        # Agora App ID\n        id:\n        # Agora App Certificate\n        certificate:\n    # 用于课程回放，见: https://docs.agora.io/cn/cloud-recording/faq/restful_authentication?platform=All%20Platforms\n    restful:\n        # Agora RESTful ID\n        id:\n        # Agora RESTful Secret\n        secret:\n    # 用于云端录制存储用户音视频。见: https://docs.agora.io/cn/cloud-recording/restfulapi/\n    # 路径: Cloud Recording Start -\u003e Schema -\u003e clientRequest -\u003e storageConfig\n    oss:\n        access_id:\n        access_secret:\n        vendor:\n        region:\n        bucket:\n        folder:\n        prefix:\n    # 视频截图服务\n    # https://docs.agora.io/cn/cloud-recording/cloud_recording_screen_capture?platform=RESTful\n    screenshot:\n        enable: false\n        oss:\n            access_id:\n            access_secret:\n            vendor:\n            region:\n            bucket:\n            folder:\n            prefix:\n    # 消息通知服务\n    # 见: https://docs-preprod.agora.io/cn/Agora%20Platform/ncs\n    messageNotification:\n        enable: false\n        events:\n            # 目前只支持 `productID: 3` 和 `eventType: 45`\n            -   productID:\n                eventType:\n                secret:\n\n# 见: https://docs.agora.io/cn/whiteboard/generate_whiteboard_token_at_app_server?platform=RESTful\nwhiteboard:\n    # 白板 AK\n    access_key:\n    # 白板 SK\n    secret_access_key:\n    # 转码地区\n    # \"cn-hz\" | \"us-sv\" | \"sg\" | \"in-mum\" | \"gb-lon\"\n    convert_region:\n\n# 存储服务\nstorage_service:\n    # 目前只支持 oss\n    type: oss\n    oss:\n        access_key:\n        secret_key:\n        endpoint:\n        bucket:\n        region:\n\n# 内容审查\ncensorship:\n    # 需要配置 agora 下的 screenshot 和 messageNotification 服务\n    # messageNotification 需要加上: productID: 3 以及 eventType: 45 (有关这一点，请看: https://docs.agora.io/cn/cloud-recording/cloud_recording_callback_rest)\n    # 其原理是对房间内的所有视频流进行定时截图，通过消息通知服务得知截图地址，并调用第三方(如: 阿里云) 的审查 API 对其进行检查\n    video:\n        enable: false\n        # 目前只支持阿里云\n        type: aliCloud\n        # 见: https://help.aliyun.com/document_detail/63004.html\n        aliCloud:\n            access_id:\n            access_secret:\n            endpoint:\n    # 见: https://docs.agora.io/cn/cloud-recording/audio_inspect_restful?platform=RESTful\n    # 注意: 目前只有中文说明\n    voice:\n        enable: false\n        # 当前只支持阿里云\n        type: aliCloud\n        aliCloud:\n            uid:\n            access_id:\n            access_secret:\n            callback_address:\n    text:\n        enable: false\n        # 当前只支持阿里云\n        type: aliCloud\n        # 见: https://help.aliyun.com/document_detail/63004.html\n        aliCloud:\n            access_id:\n            access_secret:\n            endpoint:\n```\n\n如果需要部署，那么需要确保在部署的环境变量中存在以下变量:\n\n| 变量名              | 描述              | 备注             |\n|------------------|-----------------|----------------|\n| METRICS_ENABLED  | 是否开启 metrics 监控 |                |\n| METRICS_ENDPOINT | metrics url 路径  | 例如: `/metrics` |\n| METRICS_PORT     | metrics 端口      | 例如: `9193`     |\n\n## 技术选型\n\n- [Node.js](https://github.com/nodejs/node)\n- [TypeScript](https://github.com/microsoft/TypeScript)\n- [Webpack](https://github.com/webpack/webpack)\n- [ESLint](https://github.com/eslint/eslint)\n- [Babel](https://github.com/babel/babel)\n- [MySQL](https://github.com/mysql/mysql-server)\n- [Redis](https://github.com/redis/redis)\n- [Fastify](https://github.com/fastify/fastify)\n- [Ajv](https://github.com/ajv-validator/ajv)\n- [TypeORM](https://github.com/typeorm/typeorm)\n- [Axios](https://github.com/axios/axios)\n- [date-fns](https://github.com/date-fns/date-fns)\n- [ioredis](https://github.com/luin/ioredis)\n\n## 免责声明\n\n你可以将 Flat 用于商业用途但请注意我们不接受商业化需求定制与部署支持以及其它客户服务。如有相关需求请前往[灵动课堂](https://www.agora.io/cn/agora-flexible-classroom)。\n\n本项目仅用于学习和交流使用，请遵守所在国的法律法规，切勿用于涉及政治、宗教、色情、犯罪等领域，一切违法后果请自负。\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetless-io%2Fflat-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnetless-io%2Fflat-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnetless-io%2Fflat-server/lists"}