Fix new Session event not triggered every time a new session is created (#624)

* Fix new Session event not triggered every time a new session is created

* make syncWithBackend method private
This commit is contained in:
Matti Nannt
2023-07-31 16:40:21 +02:00
committed by GitHub
parent d707e2e49e
commit 3d0d633bc8
8 changed files with 55 additions and 66 deletions

View File

@@ -0,0 +1,5 @@
---
"@formbricks/js": patch
---
Fix new Session event not triggered every time a new session is created

View File

@@ -36,6 +36,8 @@ COPY --from=installer --chown=nextjs:nodejs /app/packages/database/migrations ./
ENV NEXTAUTH_SECRET=$NEXTAUTH_SECRET
EXPOSE 3000
CMD if [ "$NEXTAUTH_SECRET" != "RANDOM_STRING" ]; then \
pnpm dlx prisma migrate deploy && node apps/web/server.js; \
else \

View File

@@ -2,6 +2,7 @@ import { getSurveys } from "@/app/api/v1/js/surveys";
import { responses } from "@/lib/api/response";
import { transformErrorToDetails } from "@/lib/api/validator";
import { getActionClasses } from "@formbricks/lib/services/actionClass";
import { getEnvironment } from "@formbricks/lib/services/environment";
import { createPerson, getPerson } from "@formbricks/lib/services/person";
import { getProductByEnvironmentId } from "@formbricks/lib/services/product";
import { createSession, extendSession, getSession } from "@formbricks/lib/services/session";
@@ -31,6 +32,16 @@ export async function POST(req: Request): Promise<NextResponse> {
const { environmentId, personId, sessionId } = inputValidation.data;
// check if environment exists
const environment = await getEnvironment(environmentId);
if (!environment) {
return responses.badRequestResponse(
"Environment does not exist",
{ environmentId: "Environment with this ID does not exist" },
true
);
}
if (!personId) {
// create a new person
const person = await createPerson(environmentId);

View File

@@ -12,7 +12,7 @@ export const getQuestionResponseMapping = (
questionResponseMapping.push({
question: question.headline,
answer: answer.toString(),
answer: typeof answer !== "undefined" ? answer.toString() : "",
});
}

View File

@@ -35,12 +35,7 @@ const addSyncEventListener = (debug?: boolean): void => {
}
syncIntervalId = window.setInterval(async () => {
logger.debug("Syncing.");
const syncResult = await sync();
if (syncResult.ok !== true) {
return err(syncResult.error);
}
const state = syncResult.value;
config.update({ state });
await sync();
}, updateInverval);
// clear interval on page unload
window.addEventListener("beforeunload", () => {
@@ -95,21 +90,13 @@ export const initialize = async (
if (isExpired(existingSession)) {
logger.debug("Session expired. Resyncing.");
const syncResult = await sync();
// if create sync fails, clear config and start from scratch
if (syncResult.ok !== true) {
try {
await sync();
} catch (e) {
logger.debug("Sync failed. Clearing config and starting from scratch.");
await resetPerson();
return await initialize(c);
}
const state = syncResult.value;
config.update({ state });
const trackActionResult = await trackAction("New Session");
if (trackActionResult.ok !== true) return err(trackActionResult.error);
} else {
logger.debug("Session valid. Continuing.");
// continue for now - next sync will check complete state
@@ -120,19 +107,7 @@ export const initialize = async (
config.update({ environmentId: c.environmentId, apiHost: c.apiHost, state: undefined });
logger.debug("Syncing.");
const syncResult = await sync();
if (syncResult.ok !== true) {
return err(syncResult.error);
}
const state = syncResult.value;
config.update({ state });
const trackActionResult = await trackAction("New Session");
if (trackActionResult.ok !== true) return err(trackActionResult.error);
await sync();
}
logger.debug("Add session event listeners");

View File

@@ -179,26 +179,12 @@ export const setPersonAttribute = async (
export const resetPerson = async (): Promise<Result<void, NetworkError>> => {
logger.debug("Resetting state & getting new state from backend");
config.update({ state: undefined });
const syncResult = await sync();
let error: NetworkError;
match(
syncResult,
(state) => {
config.update({ state });
},
(err) => {
// pass error to outer scope
error = err;
}
);
if (error) {
return err(error);
try {
await sync();
return okVoid();
} catch (e) {
return err(e);
}
return okVoid();
};
export const getPerson = (): TPerson => {

View File

@@ -1,12 +1,11 @@
import { TJsState } from "@formbricks/types/v1/js";
import { trackAction } from "./actions";
import { Config } from "./config";
import { NetworkError, Result, err, ok } from "./errors";
import { Logger } from "./logger";
const logger = Logger.getInstance();
const config = Config.getInstance();
export const sync = async (): Promise<Result<TJsState, NetworkError>> => {
const syncWithBackend = async (): Promise<Result<TJsState, NetworkError>> => {
const url = `${config.get().apiHost}/api/v1/js/sync`;
const response = await fetch(url, {
@@ -34,3 +33,20 @@ export const sync = async (): Promise<Result<TJsState, NetworkError>> => {
return ok((await response.json()).data as TJsState);
};
export const sync = async (): Promise<void> => {
const syncResult = await syncWithBackend();
if (syncResult.ok !== true) {
throw syncResult.error;
}
const state = syncResult.value;
const oldState = config.get().state;
config.update({ state });
// if session is new, track action
if (!oldState?.session || oldState.session.id !== state.session.id) {
const trackActionResult = await trackAction("New Session");
if (trackActionResult.ok !== true) {
throw trackActionResult.error;
}
}
};

View File

@@ -36,18 +36,12 @@ export const closeSurvey = async (): Promise<void> => {
document.getElementById(containerId).remove();
addWidgetContainer();
const syncResult = await sync();
match(
syncResult,
(value) => {
config.update({ state: value });
surveyRunning = false;
},
(error) => {
errorHandler.handle(error);
}
);
try {
await sync();
surveyRunning = false;
} catch (e) {
errorHandler.handle(e);
}
};
export const addWidgetContainer = (): void => {