feat: add user hash for intercom (#8263)
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com>
This commit is contained in:
parent
877220caa0
commit
8a2ab68e9a
|
@ -79,6 +79,9 @@ CALENDSO_ENCRYPTION_KEY=
|
||||||
# Intercom Config
|
# Intercom Config
|
||||||
NEXT_PUBLIC_INTERCOM_APP_ID=
|
NEXT_PUBLIC_INTERCOM_APP_ID=
|
||||||
|
|
||||||
|
# Secret to enable Intercom Identity Verification
|
||||||
|
INTERCOM_SECRET=
|
||||||
|
|
||||||
# Zendesk Config
|
# Zendesk Config
|
||||||
NEXT_PUBLIC_ZENDESK_KEY=
|
NEXT_PUBLIC_ZENDESK_KEY=
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
import crypto from "node:crypto";
|
||||||
|
|
||||||
|
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
|
||||||
|
import { defaultHandler } from "@calcom/lib/server";
|
||||||
|
|
||||||
|
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
const session = await getServerSession({ req, res });
|
||||||
|
const secret = process.env.INTERCOM_SECRET;
|
||||||
|
|
||||||
|
if (!session) {
|
||||||
|
return res.status(401).json({ message: "user not authenticated" });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!secret) {
|
||||||
|
return res.status(400).json({ message: "Intercom Identity Verification secret not set" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const hmac = crypto.createHmac("sha256", secret);
|
||||||
|
hmac.update(String(session.user.id));
|
||||||
|
const hash = hmac.digest("hex");
|
||||||
|
|
||||||
|
return res.status(200).json({ hash });
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defaultHandler({
|
||||||
|
GET: Promise.resolve({ default: handler }),
|
||||||
|
});
|
|
@ -39,8 +39,8 @@ const BillingView = () => {
|
||||||
const returnTo = router.asPath;
|
const returnTo = router.asPath;
|
||||||
const billingHref = `/api/integrations/stripepayment/portal?returnTo=${WEBAPP_URL}${returnTo}`;
|
const billingHref = `/api/integrations/stripepayment/portal?returnTo=${WEBAPP_URL}${returnTo}`;
|
||||||
|
|
||||||
const onContactSupportClick = () => {
|
const onContactSupportClick = async () => {
|
||||||
open();
|
await open();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -187,12 +187,12 @@ export default function HelpMenuItem({ onHelpItemSelect }: HelpMenuItemProps) {
|
||||||
<p className="">{t("specific_issue")}</p>
|
<p className="">{t("specific_issue")}</p>
|
||||||
<button
|
<button
|
||||||
className="hover:text-emphasis text-defualt font-medium underline"
|
className="hover:text-emphasis text-defualt font-medium underline"
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
setActive(true);
|
setActive(true);
|
||||||
if (isFreshChatEnabled) {
|
if (isFreshChatEnabled) {
|
||||||
setFreshChat(true);
|
setFreshChat(true);
|
||||||
} else if (isInterComEnabled) {
|
} else if (isInterComEnabled) {
|
||||||
open();
|
await open();
|
||||||
} else {
|
} else {
|
||||||
loadChat({ open: true });
|
loadChat({ open: true });
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,8 @@ export default function IntercomMenuItem(props: IntercomMenuItemProps) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={async () => {
|
||||||
open();
|
await open();
|
||||||
onHelpItemSelect();
|
onHelpItemSelect();
|
||||||
}}
|
}}
|
||||||
className="hover:bg-subtle hover:text-emphasis text-default flex w-full px-5 py-2 pr-4 text-sm font-medium">
|
className="hover:bg-subtle hover:text-emphasis text-default flex w-full px-5 py-2 pr-4 text-sm font-medium">
|
||||||
|
|
|
@ -25,12 +25,21 @@ export const useIntercom = () => {
|
||||||
const { hasPaidPlan } = useHasPaidPlan();
|
const { hasPaidPlan } = useHasPaidPlan();
|
||||||
const { hasTeamPlan } = useHasTeamPlan();
|
const { hasTeamPlan } = useHasTeamPlan();
|
||||||
|
|
||||||
const open = () => {
|
const open = async () => {
|
||||||
|
let userHash;
|
||||||
|
|
||||||
|
const req = await fetch(`/api/intercom-hash`);
|
||||||
|
const res = await req.json();
|
||||||
|
if (res?.hash) {
|
||||||
|
userHash = res.hash;
|
||||||
|
}
|
||||||
|
|
||||||
hookData.boot({
|
hookData.boot({
|
||||||
name: data?.name ?? "",
|
name: data?.name ?? "",
|
||||||
email: data?.email,
|
email: data?.email,
|
||||||
userId: String(data?.id),
|
userId: String(data?.id),
|
||||||
createdAt: String(dayjs(data?.createdDate).unix()),
|
createdAt: String(dayjs(data?.createdDate).unix()),
|
||||||
|
...(userHash && { userHash }),
|
||||||
customAttributes: {
|
customAttributes: {
|
||||||
//keys should be snake cased
|
//keys should be snake cased
|
||||||
user_name: data?.username,
|
user_name: data?.username,
|
||||||
|
|
|
@ -277,6 +277,7 @@
|
||||||
"ZOHOCRM_CLIENT_ID",
|
"ZOHOCRM_CLIENT_ID",
|
||||||
"ZOHOCRM_CLIENT_SECRET",
|
"ZOHOCRM_CLIENT_SECRET",
|
||||||
"ZOOM_CLIENT_ID",
|
"ZOOM_CLIENT_ID",
|
||||||
"ZOOM_CLIENT_SECRET"
|
"ZOOM_CLIENT_SECRET",
|
||||||
|
"INTERCOM_SECRET"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user