feat(chat): add promotional external entry flow

This commit is contained in:
2026-07-13 12:43:18 +08:00
parent e5ee9940ca
commit 3752b3b729
44 changed files with 1623 additions and 190 deletions
+12 -18
View File
@@ -3,6 +3,7 @@
*
* 外部应用可以通过 query 传入 Facebook 相关信息和最终目标页,例如:
* `/external-entry?target=chat&asid=xxx&psid=yyy`
* `/external-entry?target=chat&mode=promotion&promotion_type=voice`
*
* 页面不直接 `redirect()`,而是把数据交给 Client 组件先写入本地存储,
* 再通过 `router.replace()` 清理 URL 并跳转到最终页面。
@@ -23,27 +24,20 @@ export default async function ExternalEntryPage({
return (
<ExternalEntryPersist
deviceId={pickFirst(params.deviceId, params.device_id)}
asid={pickFirst(params.asid)}
psid={pickFirst(params.psid)}
avatarUrl={pickFirst(params.avatarUrl, params.avatar_url)}
target={pickFirst(params.target)}
redirect={pickFirst(params.redirect)}
next={pickFirst(params.next)}
deviceId={pickParam(params.device_id)}
asid={pickParam(params.asid)}
psid={pickParam(params.psid)}
avatarUrl={pickParam(params.avatar_url)}
target={pickParam(params.target)}
mode={pickParam(params.mode)}
promotionType={pickParam(params.promotion_type)}
/>
);
}
function pickFirst(
...values: Array<string | string[] | undefined>
): string | null {
for (const value of values) {
if (Array.isArray(value)) {
const first = value.find((item) => item.trim().length > 0);
if (first) return first;
continue;
}
if (value && value.trim().length > 0) return value;
function pickParam(value: string | string[] | undefined): string | null {
if (Array.isArray(value)) {
return value.find((item) => item.trim().length > 0) ?? null;
}
return null;
return value && value.trim().length > 0 ? value : null;
}