跳转到内容

TokenService

此内容尚不支持你的语言。

Signs and validates the deeplink tokens that authorize third-party-channel deeplinks (links.pidgr.com/c/{short_code}?t={token}). Each token carries the (campaign, recipient, step) tuple, is signed with a per-organization key, and expires. Key rotation is automatic with a 7-day overlap window, so callers never have to coordinate around it.

Method Description
SignDeeplinkToken Sign a deeplink token (internal only)
ValidateDeeplinkToken Validate a deeplink token and decode its payload

Returned in ValidateDeeplinkTokenResponse.failure_reason when valid is false.

Value Description
VALIDATION_FAILURE_REASON_INVALID_SIGNATURE Token bytes parsed but the signature did not verify under any active or overlap-window key version.
VALIDATION_FAILURE_REASON_EXPIRED Token signature verified but its embedded expiry has passed.
VALIDATION_FAILURE_REASON_KEY_RETIRED The key version that signed the token is past the rotation overlap window. Operationally equivalent to EXPIRED but distinguishable for telemetry.
VALIDATION_FAILURE_REASON_MALFORMED Token bytes could not be parsed at all. Indicates a tampered or truncated URL.

Sign a deeplink token for a (campaign, recipient, step) tuple.

Authorization: Internal service only (called by the dispatch layer assembling a deeplink during message composition)

Field Type Description
campaign_id string Campaign whose deeplink this token authorizes. Required; must be a UUID and exist within the caller’s organization.
recipient_user_id string Recipient the token authorizes. Required; must be a UUID and a member of the campaign’s audience.
step_kind ChannelStepKind Step kind the deeplink targets. Required.
ttl_seconds int64 Token lifetime in seconds from now. Required; must be between 1 second and 30 days. Longer tokens are not signed.
Field Type Description
token string The signed token, ready to URL-embed in links.pidgr.com/c/{short_code}?t={token}. Opaque — clients should not parse or mutate it; pass it back to ValidateDeeplinkToken.
expires_at Timestamp The expiry the token carries.
key_version int32 Key version used to sign. May be recorded for telemetry, but clients should not branch logic on it — rotation overlap windows are managed transparently.

Validate a deeplink token before showing the sign-in gate. The token itself is the lookup key; valid responses carry the decoded payload. The token does not authenticate the recipient (that is the sign-in flow’s job) — it authorizes “this deeplink path is for this recipient”, so the app can refuse to render a token whose embedded recipient mismatches the signed-in user.

Authorization: Public (no authentication required) — called by the app before the sign-in gate

Field Type Description
token string The token bytes from the deeplink URL’s t query parameter. Required, non-empty.
campaign_id string Campaign UUID from the URL path (translated from the short code via CampaignService.GetCampaignByShortCode). Validation rejects tokens whose embedded campaign_id does not match — defense against replaying a token from a different campaign.
Field Type Description
valid bool True when signature and expiry both check out under any active or overlap-window key version.
failure_reason ValidationFailureReason Reason validation failed. Set only when valid is false; UNSPECIFIED when valid. Drives client UX (silent retry vs “this link expired” vs “this link looks tampered”).
payload DeeplinkTokenPayload Decoded payload. Populated only when valid is true.
Field Type Description
campaign_id string Campaign UUID the deeplink targets. Used for the authenticated GetCampaign follow-up after the recipient signs in.
recipient_user_id string Recipient UUID the token authorizes. Clients should compare this against the signed-in user and refuse to render the campaign card on mismatch.
step_kind ChannelStepKind Step kind the deeplink targets — reminder vs escalation. Lets the client pick the right campaign-card variant before the sign-in gate.
expires_at Timestamp Expiry the token carries. Validation rejects tokens past this time even if the signature checks out.