Skip the steps this user has finished
A new user signed up twenty minutes ago, connected a data source and invited a teammate from the settings page. The checklist in the corner still says invite a teammate, because it reads a flag that updates after the next sync. The user now knows the guide is behind them, and the guide has one less chance to be read. The next thing they need is the step after the two they finished.
steps_completed- The setup steps this user has completed since signup
last_step_completed- The step they completed most recently
steps_completed_1h- Steps completed in the last hour
Drops every step on this user's completed list from the checklist and opens the panel on the one after their last completed step. The order of the steps is your product's. Which ones are done comes from Signals.
from datetime import timedelta
from snowplow_signals import Attribute, Event, EventProperty, StreamAttributeGroup, user_id
step_completed = Event(name="onboarding_step_completed", vendor="com.example", version="1-0-0")
step = EventProperty(vendor="com.example", name="onboarding_step_completed", major_version=1, path="step")
steps_completed = Attribute(
name="steps_completed",
type="string_list",
events=[step_completed],
aggregation="unique_list",
property=step,
ttl=timedelta(days=90),
)
last_step_completed = Attribute(
name="last_step_completed",
type="string",
events=[step_completed],
aggregation="last",
property=step,
ttl=timedelta(days=90),
)
steps_completed_1h = Attribute(
name="steps_completed_1h",
type="int32",
events=[step_completed],
aggregation="counter",
period=timedelta(hours=1),
default_value=0,
)
# New users are logged in from the first screen, so the group keys on the user id.
saas_onboarding_steps = StreamAttributeGroup(
name="saas_onboarding_steps",
version=1,
attribute_key=user_id,
owner="you@example.com",
attributes=[steps_completed, last_step_completed, steps_completed_1h],
)// In the code that renders the onboarding checklist
const user = await signals.getServiceAttributes({
name: "saas_onboarding_steps",
attribute_key: "user_id",
identifier: userId,
});
// { steps_completed: ["connect_source", "invite_teammate"], last_step_completed: "invite_teammate", steps_completed_1h: 2 }
const done = new Set(user.steps_completed);
const remaining = checklist.steps.filter((step) => !done.has(step.id));
guide.render({ steps: remaining, open: remaining[0] });