Tell the account manager while the account is adding seats
An account added five seats two weeks ago and seven more this morning. Seat growth usually reaches the account manager as a line in the quarterly review, after the renewal call is booked, so the first conversation about a bigger plan happens once the team has grown into the old one. The right moment is this week, with the seat count in the message.
seats_added_30d- Seats added to this account in the last thirty days
days_since_seat_added- Days since the last seat was added
active_users_30d- People in this account who used the product in the last thirty days
Opens a task for the account manager when seats added this month pass the level your team set for growth and the last one was added this week, with the seat count and the active users in the note. Which plan to propose stays with the account manager.
from datetime import timedelta
from snowplow_signals import (
Attribute, AttributeKey, AtomicProperty, EntityProperty, Event, StreamAttributeGroup,
)
seat_added = Event(name="seat_added", vendor="com.example", version="1-0-0")
module_used = Event(name="module_used", vendor="com.example", version="1-0-0")
account = AttributeKey(
name="account",
property=EntityProperty(vendor="com.example", name="account", major_version=1, path="id"),
)
# seat_added fires once per seat, so a counter is the seat count.
seats_added_30d = Attribute(
name="seats_added_30d",
type="int32",
events=[seat_added],
aggregation="counter",
period=timedelta(days=30),
default_value=0,
)
days_since_seat_added = Attribute(
name="days_since_seat_added",
type="double",
events=[seat_added],
aggregation="time_since_last",
time_unit="d",
)
active_users_30d = Attribute(
name="active_users_30d",
type="int32",
events=[module_used],
aggregation="approx_count_distinct",
property=AtomicProperty(name="user_id"),
period=timedelta(days=30),
)
# Keyed on the account, so one record covers everyone in it.
saas_expansion_seats = StreamAttributeGroup(
name="saas_expansion_seats",
version=1,
attribute_key=account,
owner="you@example.com",
attributes=[seats_added_30d, days_since_seat_added, active_users_30d],
)// In the job that syncs account state to your CRM
const account = await signals.getServiceAttributes({
name: "saas_expansion_seats",
attribute_key: "account",
identifier: accountId,
});
// { seats_added_30d: 12, days_since_seat_added: 0.3, active_users_30d: 41 }
if (account.seats_added_30d >= crm.rules.seatGrowth && account.days_since_seat_added <= 7) {
crm.createTask({
owner: crm.accountManager(accountId),
type: "expansion_outreach",
note: `Added ${account.seats_added_30d} seats this month, ${account.active_users_30d} people active`,
});
}