Skip to content

feat: hand the identified contact to the messenger before a survey starts - #46

Merged
boehlerlukas merged 2 commits into
masterfrom
feat/survey-skip-known
Oct 8, 2026
Merged

boehlerlukas merged 2 commits into
masterfrom
feat/survey-skip-known

Conversation

@boehlerlukas

@boehlerlukas boehlerlukas commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Surveys 2.0: skip contact questions when the user is known (Android)

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 SDK change doesn't depend on that order. It needs an Android SDK release to take effect (and the wrappers pick it up when they bump their gleap-android-sdk dependency). No version bump here.

The messenger reads userId, email, name and phone from session-update once, when a survey starts. It skips the email and name/phone questions an identified contact already has, and closes the survey (survey-closed nothing_to_ask, then close-widget) when nothing is left to ask.

Fixed

  • Phone was never sent. GleapSessionProperties.fromJSONObject didn't read phone, so sessionData.phone was always missing and phone questions were never skipped. It now reads it (when it isn't JSON null). setGleapUserSession stores it the same way as the email, so a new contact without a phone no longer keeps the previous contact's phone.
  • Open widget wasn't told about identity changes. session-update reached an open widget only on ping, or when the file-access token changed. It is now sent after every accepted session answer, which covers identifyContact/identifyUser, updateContact and the new guest session after clearIdentity. It still waits for the first ping. This matches iOS and the JS SDK.
  • Survey started during identify. identifyContact runs in the background, so showSurvey(...) straight after it, or a server-triggered survey, could ping with the guest session and ask for known data. Surveys now wait in GleapWidgetLauncher.openWithScreenshot until no identify is queued or running, checking every 100 ms for at most 3 s. The widget home (SurveyType.NONE) is unchanged.
  • All questions skipped. close-widget → closeMainGleapActivity() → finish() already leaves a clean state: onDestroy resets isOpened, calls the widget-closed listener once, brings back the FAB and clears the dim. The only gap was the 500 ms delayed reveal after the ping. It could still show the web view and the card's dim bands on an activity that was already finishing. It now returns when isFinishing().

Not changed (checked)

  • sessionData keys are already userId / name / email / phone (GleapWidgetMessages.sessionUpdate).
  • On ping the order is config-update, session-update, then queued actions (start-survey).
  • config-update already sends isApp and surveyCallbacks.
  • close-widget can't arrive before onCreate, because the JS bridge is attached there.

Side effects

  • While an identify stays queued (e.g. offline with a pending identify), a survey opens up to 3 s later.
  • An identify that changes gleapId while the widget is open now reaches the open widget, and the messenger resets its state for the new contact. iOS and the JS SDK already behave this way.

Verification

JDK: Android Studio's bundled JBR (OpenJDK 21).

  • ./gradlew build: BUILD SUCCESSFUL.
  • ./gradlew test --rerun-tasks: 203 tests, 0 failures.
  • ./gradlew :gleap:assembleRelease :gleap:testDebugUnitTest: passes.
  • Not run on a device or emulator, so the survey flows were checked by reading the code. The same messenger behaviour was verified end to end against the JS SDK (JavaScript-SDK PR).

Follow-up: hold a survey back until the messenger has something to show (82418ce)

Messenger-App#240 69a4f8b renders an in-app survey only once its definition is in and something will be asked. An all-skipped survey closes (survey-closed nothing_to_ask, then close-widget) without rendering anything. The activity used to show its #66000000 dim loader as soon as a survey started, until the first ping + 500 ms, so such a survey still flashed a dim and a spinner.

What changed, for surveys only:

  • The loader, the dim and the web view stay hidden until the messenger reports content. For a card that is the first height-update. For full screen it is the first of survey-shown, survey-legacy or height-update. These messages are forwarded by appnew.html.
  • Once content is reported, the web view fades in. A card gets its dim bands; a full-screen survey gets its backdrop.
  • If nothing arrives within 1.2 s of the survey start (the same fallback as the JS SDK), today's loader shows. From then on it stays shown, so there is no dim → undim → dim.
  • survey-closed cancels a pending fallback. An all-skipped survey closes without anything having been visible.

Widget (non-survey) opens are unchanged.

appnew.html's own card dim and full-screen background are applied inside the web view, so they stay hidden along with it. appnew.html lives in Messenger-App, not in this repo.

Verified: ./gradlew build and ./gradlew test (203 tests) pass. Not driven on a device or emulator.

🤖 Generated with Claude Code

boehlerlukas and others added 2 commits October 8, 2026 14:30
…arts

The messenger skips survey contact questions an identified contact already
answered (Messenger-App#240). It reads userId, email, name and phone from
session-update once, when the survey starts.

- Parse phone from the session answer (it was dropped, so the phone question
  was never skipped) and store it like the email.
- Send session-update to an open widget after every session answer
  (identify, updateContact, the new session after clearIdentity), not only
  when the file session changed.
- Surveys (showSurvey, server triggers) wait for an identify in flight, at
  most 3 s, before the widget opens.
- The delayed reveal after the ping does nothing once the activity is
  finishing (a survey with nothing to ask closes right away).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The messenger renders an in-app survey only once its definition is in and
something will be asked (Messenger-App#240); a survey with nothing to ask
closes without rendering. The activity showed its dim loader as soon as a
survey started, so such a survey flashed a dim and spinner.

Surveys now keep the loader, the dim and the web view hidden until the
first height-update (card) or survey-shown / survey-legacy / height-update
(full screen), or until 1.2 s after the start, when today's loader shows
(and then stays). Widget opens are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@boehlerlukas
boehlerlukas merged commit a1f8c68 into master Oct 8, 2026
1 check passed
@boehlerlukas boehlerlukas mentioned this pull request Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant