{"id":19287872,"url":"https://github.com/deeppavlov/dream-landing","last_synced_at":"2026-05-16T15:38:00.275Z","repository":{"id":41397519,"uuid":"460113276","full_name":"deeppavlov/dream-landing","owner":"deeppavlov","description":"Landing and demo page for Dream social bot","archived":false,"fork":false,"pushed_at":"2022-07-01T11:18:25.000Z","size":731,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-16T15:22:24.493Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/deeppavlov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-02-16T17:44:46.000Z","updated_at":"2022-09-13T18:28:41.000Z","dependencies_parsed_at":"2022-09-18T10:20:45.708Z","dependency_job_id":null,"html_url":"https://github.com/deeppavlov/dream-landing","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/deeppavlov/dream-landing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeppavlov%2Fdream-landing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeppavlov%2Fdream-landing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeppavlov%2Fdream-landing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeppavlov%2Fdream-landing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/deeppavlov","download_url":"https://codeload.github.com/deeppavlov/dream-landing/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deeppavlov%2Fdream-landing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33108232,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T04:41:52.686Z","status":"ssl_error","status_checked_at":"2026-05-16T04:41:52.009Z","response_time":115,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2024-11-09T22:07:27.971Z","updated_at":"2026-05-16T15:38:00.248Z","avatar_url":"https://github.com/deeppavlov.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dream Landing\n\nThis repository is home to the Dream landing and demo page.\n\n## Development\n\nFirst, run the development server:\n\n```bash\nnpm run dev\n```\n\nthen open [http://localhost:3000](http://localhost:3000).\n\nYou can use the command\n\n```bash\nnpm run dev:msw\n```\n\nto mock dream endpoints in development. You can edit the mock handlers in `mocks/browser.ts`.\n\nRun tests for utility functions:\n```bash\nnpm test\n```\n\n## Documentation\n\nThis project uses [Next.JS](https://nextjs.org/docs) and TypeScript.\n\n## Next steps\n\nFor saving text feedback to a database:\n 1. Open up `components/FeedbackPopup.tsx`\n 2. On line 9 change the variable `SPREADSHEET_API_URL` to the new endpoint that accepts the text feedback (the variable could also be renamed to make more sense)\n 3. The POST request is made on line 15. Change the object there, to define the JSON data sent to the endpoint.\n\nFor the new developer:\n 1. Read through this documentation and the codebase\n 2. Finish implementing the surveys feature\n    1. Create the UI component, for the floating window in `components/`\n    2. You could probably modify `ActionBtn.tsx` to work as the answer button in the survey window\n    3. Create a hook in `hooks/` for gathering the `ClientContext` and querying the survey endpoint on every bot reply\n    4. Once the database is ready, the Agent folks, will probably provide a Dream endpoint for saving survey results, so that could be used directly from the client\n    5. (Optionally) we could cut down on client side requests by grouping together sending messages and querying for active surveys into a single endpoint\n 3. If it's fixed, add back utterance ratings\n 4. If there are no other urgent tasks:\n    1. Shared types could be moved to one file\n    2. `useChat` and the overall state management is pretty messy. A central store could be introduced + instead of saving the message history in local storage, it could be fetched from the API on load.\n    3. Next.js and React are huge dependencies (about ~60% of the final bundle), but we do not use heavily any specific feature from either. Theoritcally, the whole site could be ported to use Vite (and vite-plugin-ssr) instead of Next.js and Preact instead of React. Exploration of this can be found on the [`feat/optimize-load`](https://github.com/deepmipt/dream-landing/tree/feat/optimize-load) branch.\n\n### Project structure:\n\n - `pages/`\n   - `index.tsx` Main page with chat window and sidebar\n   - `chat.module.css` Styles for `index.tsx`\n   - `shared.tsx` The page users see when they visit a shared dialog\n   - `shared.module.css` Styles for `shared.tsx`\n   - `api/`\n     - `preview.ts` Generates an image preview for a shared dialog\n     - `survey.ts` Given a user context return active survey, if any\n- `components/` See [Components](#components)\n- `public/` Public static assets (fonts, logo, favicon)\n- `styles/`\n    - `global.css` Global styles (style reset)\n- `hooks/`\n    - `useChat.ts` Hook that keeps the chat state, sends and receives messages\n    - `useOnSmallerScreen.ts` Hook that monitors screen size\n    - `usePost.ts` A minimal fetch hook for post requests\n    - `useStored.ts` Hook for localstorage\n- `utils/`\n    - `analytics.ts` Google Analytics wrappers\n    - `renderChat.ts` Render a list of messages to an image (in NodeJS context)\n    - `shareUrl.ts` Generate a share url for a list of messages or parse a shared url \n    - `surveyConfig.ts` Find a matching survey given a client context\n- `surveys/` Survey specification files (see `survey-config-spec.yaml`)\n- `mocks/`\n  - `browser.ts` MSW mock handlers for Dream endpoints\n- `survey-config-spec.yaml` An example for a survey config (not a valid config itself)\n\n### Features overview\n\n#### Chat \nThe main purpose of the landing site is to allow users to chat with the Dream social bot. This is done through Dream's REST API:\n\n - `POST` https://7019.deeppavlov.ai/ - Get a reply from Dream\n    - Request spec:\n    ```ts\n    {\n        user_id: string; // User ID (generated on client side)\n        payload: string; // Message text\n    }\n    ```\n    - Response spec:\n    ```ts\n    {\n        dialog_id: string; // ID of current dialog (generated on server side)\n        utt_id: string; // ID of current utterance\n        user_id: string; // User ID (same as the one we sent)\n        response: string; // Response text\n        active_skill: string; // Name of Dream skill that generated the repsonse\n    }\n    ```\n - `POST` https://7019.deeppavlov.ai/rating/dialog - Post a rating (1-5) for the dialog\n    - Request spec:\n    ```ts\n    {\n        user_id: string; // User ID\n        rating: number; // Rating (1-5)\n        dialog_id: string; // Dialog ID\n    }\n    ```\n    - Response: empty on success\n - `GET` https://7019.deeppavlov.ai/api/dialogs/ - Get the chat history for the dialog\n    - Response spec:\n    ```ts\n    {\n        utterances: {\n            utt_id: string;\n            text: string;\n            user: {\n                user_type: \"human\" | \"bot\";\n            };\n        }[];\n    }\n    ```\n\n\nInterfacing with this API is done in `hooks/useChat.ts`. This hook stores the user ID, dialog ID, chat history and the current rating. It saves the chat history (as well as the user/dialog ID) to local store, instead of fetching them from the API. This is because when the project's development started, the endpoint for fetching message history did not work reliably. Now that that is fixed, fetching messages instaed of storing should be experimented with.\n\nDream has (will have) multiple versions deployed, at the very least one for each supported language. The chat can handle this via the `version` search parameter, which is parsed in the `useChat` hook, and the consequently used to select the right API endpoint. Also the version id is used to prefix all keys in the local storage, so that a user can chat with multiple version without interference. The id for the default (English) version is an empty string, to remain backwards compatible with older deployments.\n\nThe main chat window is mostly implemented in `pages/index.tsx`. The chat history specifically is in `components/MessageHistory.tsx`, the individual chat bubbles in `components/MessageBubble.tsx`, and the sidebar in `components/Sidebar.tsx`.\n\n#### Sharing\n\nAn important feature of the site is sharing dialogs or parts of them on social media. The client side generates unique sharing URLs via the utilities in `utils/shareUrl.ts`, which point to the `pages/shared.tsx` page, and encode the dialog id, the bot version, and the range of messages to be shown.\n\nThe `pages/shared.tsx` route fetches the shared dialog from the API and renders the selected messages with the `components/MessageHistory.tsx` component, the same one used in the main chat view.\n\nThe `pages/api/preview.ts` endpoint renders shared dialogs onto a canvas on the server and returns it as an image, to be used as thumbnail on social media shares (the necessary open graph tags are configured in `pages/shared.tsx`, since that's the site the platforms crawl). The actual rendering is implemented in `utils/renderChat.ts`.\n\n**IMPORTANT:** If the design of the chat bubbles changes in the future, it is neccessary to update the canvas rendering logic as well in `utils/renderChat.ts`\n\n#### Rating \u0026 feedback\n\nIt is possible to give a 1-5 rating to the overall dialog with Dream. The UI for the stars is in `components/StarsRating.tsx`, while the logic for posting the rating is in `useChat`.\n\nWhen clicking the \"leave feedback\" link, the popup defined in `components/FeedbackPopup.tsx` shows up. The textual feedback entered here is currently saved to a Google Sheet, but this should be moved to the Dream database ASAP (consult with Maxim Talimanchuk). \n\nGiving a rating (or reaction) to each individual bot reply should also be possible, but due to an underlying bug in Dream, it is currently disabled. The UI is there, though and completely functional, only lines 80-87 need to be uncommented in `components/MessageBubble.tsx`. Timeline of fix to be discussed with Fedor Ignatov.\n\n#### Surveys\n\nConducting randomly sampled surveys amongst the users while they are chatting should be possible. The currently running surveys are defined by YAML specification files, located in the `surveys/` folder, see `survey-config-spec.yaml` for an example, or `utils/surveyConfig.schema.json` for the exact JSON Schema.\n\nThe client queries the `pages/api/survey.ts` endpoint after every bot message received (if it's not already showing a survey), sending along some information about the user and the current conversation (see `ClientContext` in `utils/surveyConfig.ts`). The endpoint then decides, based on random chance and the `ClientContext`, which survey to send back, if any.\n\nOn the client side, the active survey, if any, should be shown in a floating window (see Figma design), and should disappear after the user answered, closed it, or certain time has elapsed, and the results, or lack thereof, sent back.\n\nCurrently, only the survey configs and the query endpoint are done. The UI component, and the endpoint for saving results remain to be done. Ideally, these survey results should be saved in the same database where feedback is saved, so it also needs to be coordinated with Maxim Talimanchuk.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeeppavlov%2Fdream-landing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeeppavlov%2Fdream-landing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeeppavlov%2Fdream-landing/lists"}