Repository navigation
feat: start surveys with the identified contact and close all-skipped surveys cleanly - #170
Merged
Merged
Conversation
… surveys cleanly The messenger now skips survey contact questions an identified contact already answered (Messenger-App#240) and, when nothing is left to ask, closes the survey (survey-closed nothing_to_ask + close-widget) before it is shown. - showSurvey (manual, outbound triggers, links, survey pages) waits for an identify / updateContact in flight (at most 5 s), so the messenger reads the new contact when the survey starts. - A close-widget before the first-ping open no longer gets reopened 300 ms later as an empty, stuck "open" frame. A frame that was never shown hides without the close animation and without a close event. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A card or page survey started in a frame that already measured an earlier survey card was revealed at once with the old height, so a survey with nothing to ask (the messenger now reports no height for it) flashed an empty card before it closed. Each new survey start now resets the height and waits for the survey's first height-update, or the 1.2 s fallback, like a cold frame. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Surveys 2.0: skip contact questions when the user is known (JS SDK)
Part of the "skip contact questions when the user is known" feature:
Deploy order: Server first, then Messenger-App and Frontend (see Server#2079). This PR doesn't depend on that order, because it only changes how the SDK hosts a survey. It needs a JS SDK release to take effect. The feature itself works without this PR, but without it the two problems below remain. No version bump or build output here:
build/andpublished/are left for the release.What the messenger needs from the host
session-updatesends the whole session (GleapSession.getSession()), souserId,email,nameandphonefrom the server'sgetPublicSessionDatareach the messenger. It is sent again after every session answer (validateSession→notifySessionReady→sendSessionUpdate), so afteridentifyandupdateContacttoo. AfterclearIdentitythe SDK sendssession-clearedand then the new guest session.Gleap.identify(...)and thenGleap.showSurvey(...)straight away, or an outbound trigger firing while identify is in flight, started the survey as the guest. The guest was asked for their email, and then the identifiedsession-update(newgleapId) reset the survey in the messenger while it was open. NowshowSurveywaits until no identify / updateContact is in flight, at most 5 s. Every path goes through it: manual calls, outbound triggers,gleap_surveylinks, banners, modals and survey pages. With nothing in flight it still starts synchronously, as before.survey-closed(reason: "nothing_to_ask") and thenclose-widget. On a cold frame this can arrive before the SDK's "open 300 ms after the first ping" timer fires. The timer then opened the frame anyway, leaving an empty card stuck open (isOpened() === true). The timer is now cancelled byhideWidget. A frame that was never shown hides without the close animation and without acloseevent, because noopenevent fired either.Changes
GleapSession:trackContactUpdatecounts identify / partial-update requests until they settle.onContactSettled(cb, 5000)runscbonce none is pending.Gleap.showSurvey: starts throughonContactSettled.GleapFrameManager: the ping-open timer is kept inopenAfterPingTimeoutand cleared inhideWidget/destroy.hideWidgetdoesn't animate or fireclosewhen the widget never opened.Small side effect:
Gleap.close()on an already closed widget no longer fires acloseevent.Verification
npm test: 521 passed.npm run build: compiles (the existing bundle-size warnings only).survey-closed,close, thenopen300 ms later: an empty white card stays on screen,isOpened()truesurvey-closed, frame never visible, noopen/close,isOpened()falseopen→survey-closed→close, hiddenidentify()+showSurvey()at once (identify answer delayed 1.2 s)start-surveygoes out withuserId=null, the email question is shown, then the identified session-update resets itstart-surveygoes out aftersession-update userId=user_42,nothing_to_ask, closedc_nps), the email and name are skippedclearIdentity()+showSurvey()format: 'page'), contact-onlyFollow-up: a reused frame waits for the new survey's height (9a66bd9)
Messenger-App#240 69a4f8b holds every in-app survey back: nothing is rendered and no
height-updateis sent until the definition is in and something will be asked. In a frame that had already measured an earlier survey card,setAppModeskipped the wait (surveyAwaitingHeightwas false), so the next card was shown at once with the old height. An all-skipped survey then flashed an empty card before closing. Every new card or page survey start now resetsframeHeightand waits for its own firstheight-update, or the existing 1.2 s fallback, the same as a frame that has never shown a survey.Verified with the same harness against a build of Messenger #240 at 69a4f8b:
Gleap.close(), then an all-skipped card in the same frame--measuring(invisible), then hiddennothing_to_ask, never visiblenpm test: 521 pass.npm run build: compiles, and its output was reverted.🤖 Generated with Claude Code