Skip to content

使用 Coding Agent 接入反馈组件 ​

在 Coding Agent 中打开你的项目,然后复制并发送下面的 Prompt。Agent 会检查项目结构,按需要接入访客模式或产品已有账号,并验证结果。使用已有账号时,会连接现有登录流程并在服务端实现 JWT 签发。

接入已有账号需要 FeedLog SSO 密钥。请将密钥配置为服务端环境变量,不要写进 Prompt 或粘贴到对话中。Agent 会说明具体配置位置。

复制 Prompt ​

txt
Integrate the FeedLog feedback widget into this project. Work directly in the current repository: inspect the codebase, make the required changes, run the relevant checks, and verify the integration as far as the available environment allows. Do not stop at providing instructions or example code.

Communicate with me in the language I use. Follow all repository-level instructions, including AGENTS.md, CLAUDE.md, contribution guides, and existing coding conventions.

Official documentation:
- Widget: https://help.feedlog.ai/developers/widget
- SSO and JWT signing: https://help.feedlog.ai/developers/sso

Read the official documentation before editing if network access is available. If it is unavailable, continue using the requirements below. If the current official documentation conflicts with this prompt, follow the documentation and mention the difference in your final report.

## Goal

Install and initialize `@feedlog/widget`, connect the capabilities this product needs, and verify the integration.

Choose the identity approach from my request and the existing project:

- Guest-only: initialize with the FeedLog workspace URL and enable guest posting in the workspace. This mode needs no token endpoint or SSO secret.
- Existing product accounts: connect the application's sign-in state and sign-in UI, and issue JWTs from a trusted server-side endpoint. Signed-out access depends on workspace guest permissions.

If the intended approach is unclear after inspecting the project, ask before implementing authentication. A product can use guest-only mode even when it has its own accounts.

For existing-account integration, the widget uses the same JWT format as FeedLog browser SSO. The widget SDK handles its own token exchange.

## Inspect the project first

Before asking me for paths or implementation details, inspect the repository and determine:

- the frontend framework, version, package manager, and application entry points;
- where client-only startup code belongs;
- how the frontend reads the current sign-in state, when account integration is needed;
- how the server authenticates requests and reads the current user, when account integration is needed;
- where API routes, server actions, or backend handlers belong;
- how environment variables and deployment secrets are managed;
- whether this is a monorepo and where its frontend and backend applications live;
- the existing application theme, help entries, and layer conventions;
- the existing lint, typecheck, test, build, and browser-test commands.

Reuse the project's existing authentication, API, configuration, and error-handling patterns. Do not introduce a second authentication system or perform an unrelated authentication refactor.

Ask a focused question only when required information cannot be discovered from the repository.

## Handle incomplete repositories safely

Guest-only integration can be completed in a frontend repository. The following requirements apply when connecting existing product accounts, which also needs a trusted server environment.

If the repository contains only frontend code:

- never sign the JWT in the browser;
- never place the FeedLog SSO secret in a public or client-side environment variable;
- complete only the frontend work that is safe to implement;
- then ask for the backend repository or an existing authenticated endpoint that can issue the FeedLog JWT;
- report the integration as incomplete until the server-side issuer is connected.

If the repository contains only backend code:

- implement the JWT signing function and authenticated token endpoint;
- add the relevant tests;
- ask where the frontend application is located;
- report that widget initialization is still pending.

If both sides are present, complete both without asking for information that the code already provides.

## Install and initialize the widget

Install `@feedlog/widget` with the repository's existing package manager. It provides ES modules and TypeScript declarations.

Initialize once per page in the browser using the framework's established client-only lifecycle or plugin. Avoid duplicate initialization during route changes. Add options to this one call rather than calling `createWidget` again to update configuration.

For guest-only integration:

```ts
import { createWidget } from '@feedlog/widget'

createWidget({
  baseUrl: feedlogBaseUrl,
  theme: 'auto',
})
```

For existing accounts, include `auth: { getToken, login }` using the implementations below. Guest-only integration can skip the authentication and secret sections.

The `baseUrl` must be the user's FeedLog workspace URL, including the scheme. Reuse existing configuration when present; otherwise ask for it.

## Connect display controls where needed

Use the SDK's four public methods:

- `createWidget(options)`: initialize once per page.
- `openWidget()`: open the feedback panel.
- `closeWidget()`: close the panel while preserving the conversation and draft.
- `updateWidget(options)`: update `theme`, `zIndex`, and `launcher` fields.

All return `void`. After initialization is called, controls can be used without waiting for loading to finish. Panel open/close and launcher state are separate controls.

Use workspace placement and closing defaults unless the project has an explicit reason to override them. Connect these options only where they serve the requested integration:

- Theme: use `auto` for the operating system's theme. For an application theme toggle, pass the current `light` or `dark` value at initialization and call `updateWidget({ theme })` when it changes.
- Custom help entry: connect the existing entry to `openWidget()`. If it should replace the floating button, initialize with `launcher: { state: 'hidden' }`.
- Unread indicator: configure `onUnreadChange: (count) => { ... }` in the initial options when a custom entry needs a badge. Render the supplied count, including clearing the badge at zero.
- Host dialogs: call `closeWidget()` when the application needs the panel closed for a business interaction.
- Layering: the default `zIndex` is 40. Set it at initialization or through `updateWidget` if the application's layer conventions require it.
- Launcher: `alignment` accepts `left` or `right`; `bottomOffset` and `sideOffset` accept non-negative safe integers in CSS pixels; `state` accepts `button`, `tab`, or `hidden`.

`updateWidget` merges supplied fields, including individual launcher fields. `baseUrl`, `auth`, `onUnreadChange`, and `embedPath` are initialization options. Initial placement respects the customer's saved drag position before SDK and workspace defaults; explicitly updating position through `updateWidget` replaces that saved drag. State and theme updates preserve the position.

Dragging and button/tab preferences survive reloads in the same browser tab. Hidden state lasts for the current page, unless initialization explicitly sets `hidden` again. These SDK controls do not change workspace settings.

## Implement `auth.getToken`

`auth.getToken()` must call an authenticated endpoint in this application. It must have three distinct outcomes:

- return a JWT string when a user is signed in;
- return `null` only when the application has confirmed that no user is signed in;
- throw an error when the request fails, times out, returns an unexpected response, or cannot be parsed.

Do not return `null` for a temporary failure. FeedLog treats `null` as an explicit sign-out and clears the cached widget session.

Do not sign the JWT in browser code.

## Implement `auth.login`

Connect `auth.login()` to the application's existing sign-in experience, such as its current sign-in route, modal, popup, or identity-provider redirect.

Preserve the current page or use the project's existing callback/redirect mechanism when appropriate. Do not create a second sign-in flow for the widget.

For a modal or popup, return a Promise that settles when the entire interaction ends, including cancellation. While waiting, the widget hides its panel and launcher; after the interaction ends, it checks identity and restores the widget. Returning `void` keeps the widget visible and checks identity again immediately. For a full-page redirect, returning immediately is appropriate because the page navigates away.

The completion of `login()` does not prove that sign-in succeeded. The widget calls `getToken()` again to determine the resulting state, so do not build the integration around a custom success value from `login()`.

## Add the server-side token endpoint

Add an endpoint using the project's existing server API conventions. It must:

1. Authenticate the request with the project's existing server-side session or middleware.
2. Read the user identity from that trusted server-side session.
3. Never trust an email, name, or picture supplied directly by the browser for JWT claims.
4. Return the application's normal signed-out response when there is no current user.
5. Sign and return a FeedLog JWT when a user is signed in.
6. Avoid caching one user's token for another user.
7. Never log the JWT, SSO secret, session cookie, or other credentials.

Use a response shape that fits the existing API conventions. A typical response is:

```json
{
  "token": "<signed-jwt>"
}
```

For a signed-out request, the endpoint may return `{ "token": null }` or the project's established unauthenticated status. Make `getToken()` interpret that case as `null` while continuing to throw for temporary and unexpected failures.

## Sign the FeedLog JWT

Sign with HS256 on the server.

Supported claims:

- `email`: required; use the current authenticated user's valid email address;
- `exp`: required; Unix timestamp in seconds;
- `name`: optional;
- `picture`: optional; absolute avatar URL.

Use a one-hour lifetime by default. The expiration must not be more than 24 hours in the future.

For example, the payload should be equivalent to:

```ts
{
  email: user.email,
  name: user.name,
  picture: user.avatarUrl,
  exp: Math.floor(Date.now() / 1000) + 60 * 60,
}
```

Omit optional claims when the application does not have reliable values. Do not invent an email address when the current user has none; return a clear, safe error and report the limitation.

Reuse a suitable JWT library already present in the server project when possible. Otherwise add a maintained library compatible with the project's runtime. Do not implement cryptography manually.

## Configure the SSO secret safely

The FeedLog SSO secret is created in:

FeedLog Dashboard -> Developer -> Single Sign-On -> New Secret

Use the secret exactly as the UTF-8 string shown by FeedLog. Do not hex-decode or Base64-decode it before signing.

First check whether an appropriate server-side secret variable already exists, without printing its value. Follow the project's naming convention. If no convention exists, use:

```env
FEEDLOG_BASE_URL=
FEEDLOG_SSO_SECRET=
```

Only the base URL may be exposed to the browser when necessary. `FEEDLOG_SSO_SECRET` must remain server-only and must not use a public prefix such as `VITE_`, `NEXT_PUBLIC_`, `NUXT_PUBLIC_`, or `PUBLIC_`.

If the secret is not configured:

- add the server-side environment-variable declaration and an empty placeholder to the appropriate example environment file;
- do not generate a replacement secret;
- do not ask me to paste the real secret into chat;
- tell me how to create it in FeedLog and place it in the project's local secret store and deployment platform;
- ask me only to confirm when it has been configured.

You may complete code changes, static checks, and tests with a safe test-only secret, but do not claim that the live authentication flow was verified until the real deployment secret is configured. Never put a real secret in a fixture, snapshot, command output, or test log.

## FeedLog dashboard setting

The widget must be enabled in FeedLog Dashboard -> Settings -> Widget. Guest-only integration also requires guest posting to be enabled. If you cannot perform these external actions, continue the repository work and list the required manual steps.

## Error handling

Handle missing or invalid FeedLog URLs and configuration loading failures. When connecting product accounts, also handle these cases using the project's existing error conventions:

- the user is signed out;
- the signed-in user has no valid email;
- the token endpoint request fails or times out;
- JWT signing fails;
- the FeedLog base URL is missing or invalid;
- the FeedLog SSO secret is missing;
- widget initialization fails.

Errors must not expose the JWT, secret, session cookie, or other credentials.

## Verify the integration

Run the repository checks appropriate to the changes. Keep unrelated pre-existing failures separate. Use the project's approved browser workflow for behavior checks; report manual checks if browser verification is unavailable.

For every integration, verify:

1. The widget initializes once in the browser and opens from its intended entry.
2. The application builds and loads successfully.
3. Guest-only access follows workspace permissions, when selected.
4. Any connected theme toggle, custom entry, unread badge, or dialog control behaves as intended.
5. The widget's layer order fits the application's navigation and dialogs on desktop and mobile.

For existing-account integration, also verify:

1. Signed-in requests receive an HS256 JWT with trusted `email` and an `exp` no more than 24 hours away.
2. A confirmed signed-out state returns `null`; temporary failures throw.
3. Sign-in from the widget completes without requiring a second click, and cancellation restores the widget.
4. The SSO secret stays out of browser code, client bundles, logs, and version control.
5. The widget identifies the signed-in customer correctly when a configured FeedLog instance is available.

Use focused tests where the repository has an established test setup. Distinguish verified behavior from checks blocked by external configuration.

## Final report

Report concisely:

1. the integration mode and files changed;
2. where initialization and any display controls live;
3. for account integration, where the token endpoint lives and how it reads the authenticated user;
4. the environment-variable names used, without their values;
5. the checks run and their results;
6. required FeedLog Dashboard or deployment steps;
7. anything incomplete or not verified.

Complete the authorized repository work rather than ending with sample code alone.

Agent 可能会询问 FeedLog 地址、使用方式,或所需代码的位置。你需要在 FeedLog 控制台启用反馈组件;访客模式需要开启访客提交,接入已有账号则需要创建 SSO 密钥的权限。

开源的反馈收集工具。可以自己部署,也可以用我们托管的版本。