knock-server.ts
// Knock 클라이언트 생성 및 사용자 ID 반환
export async function getKnockClient() {
const session = await auth();
// 세션에 profile_id가 없으면 에러
if (!session?.user.profile_id) {
throw new Error('No profile ID found in session');
}
const knockClient = new Knock(process.env.KNOCK_API_SECRET as string);
return {
client: knockClient,
userId: `${process.env.NEXT_PUBLIC_CHANNEL_ID}_${session.user.profile_id}`,
};
}
// Knock에 사용자 등록
export async function registerKnockUser(userId: string, userData: {...}) {
const knockClient = new Knock(process.env.KNOCK_API_SECRET as string);
try {
// Knock에 사용자 정보 등록
await knockClient.users.identify(userId, {
name: userData.name,
email: userData.email,
avatar: userData.avatar,
});
return true;
} catch (error) {
console.error('Failed to register Knock user:', error);
return false;
}
}
auth.ts
// 로그인 성공 시 Knock에 사용자 등록
const knockUserId = `${process.env.NEXT_PUBLIC_CHANNEL_ID}_${profileId}`;
await registerKnockUser(knockUserId, {
name: user.name || undefined,
email: profileData.email || undefined,
avatar: (user as ExtendedUser).image || undefined,
});
knock-provider.tsx
export function NotificationProvider({ children }: PropsWithChildren) {
// 세션에서 사용자 정보 가져오기
const { data: session, status } = useSession();
// Knock 사용자 ID 생성 (CHANNEL_ID_PROFILE_ID 형식)
const knockUserId = `${process.env.NEXT_PUBLIC_CHANNEL_ID}_${session?.user.profile_id}`;
return (
<KnockProvider
apiKey={process.env.NEXT_PUBLIC_KNOCK_PUBLIC_API_KEY!}
userId={knockUserId}
>
<KnockFeedProvider
feedId={process.env.NEXT_PUBLIC_KNOCK_FEED_CHANNEL_ID!}
defaultFeedOptions={{...}}
>
{children}
</KnockFeedProvider>
</KnockProvider>
);
}
동작 흐름:
주요 특징: