@proveanything/smartlinks 2.1.13 → 2.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/integrations.d.ts +28 -0
- package/dist/api/integrations.js +28 -0
- package/dist/docs/API_SUMMARY.md +132 -7
- package/dist/docs/connectors.md +98 -4
- package/dist/docs/entitlements.md +90 -0
- package/dist/docs/integrations.md +167 -9
- package/dist/docs/interactions.md +545 -540
- package/dist/docs/loyalty.md +17 -0
- package/dist/docs/server-functions.md +3 -0
- package/dist/openapi.yaml +239 -2
- package/dist/types/appManifest.d.ts +42 -1
- package/dist/types/integrations.d.ts +168 -3
- package/docs/API_SUMMARY.md +132 -7
- package/docs/connectors.md +98 -4
- package/docs/entitlements.md +90 -0
- package/docs/integrations.md +167 -9
- package/docs/interactions.md +545 -540
- package/docs/loyalty.md +17 -0
- package/docs/server-functions.md +3 -0
- package/openapi.yaml +239 -2
- package/package.json +87 -87
package/dist/docs/loyalty.md
CHANGED
|
@@ -302,6 +302,23 @@ A loyalty failure never causes the interaction event to fail — errors are caug
|
|
|
302
302
|
|
|
303
303
|
---
|
|
304
304
|
|
|
305
|
+
## External loyalty platforms
|
|
306
|
+
|
|
307
|
+
The schemes above are SmartLinks' own points. When a brand runs its programme on an external loyalty or
|
|
308
|
+
engagement platform, the platform stays the record of truth and SmartLinks connects to it through a
|
|
309
|
+
**connector app** and the integration engine — no member base is mirrored here:
|
|
310
|
+
|
|
311
|
+
| Flow | How |
|
|
312
|
+
|---|---|
|
|
313
|
+
| **Earn** — what happens on a pack or in a Hub awards points there | an outbound flow with `sourceEntity: 'interaction' \| 'event'`, an `eventMapping` onto the provider's registered events, signed delivery, retries — [integrations.md](integrations.md#event-sourced-flows-and-the-envelope) |
|
|
314
|
+
| **Profile** — member id, tier and points on the contact | the connector's webhook function calls `ctx.sl.members.apply(...)`; the contact gets `customFields.loyalty` and flat `loyaltyTier / loyaltyPoints / loyaltyMemberId`, usable in segments and comms targeting — [connectors.md](connectors.md#loyalty-and-crm-connectors) |
|
|
315
|
+
| **Gate / display** — "Gold members only", live balance | the entitlement check, answered on demand from a signed claim, the connector's cached `lookup`, or the contact's fields — [entitlements.md](entitlements.md) |
|
|
316
|
+
|
|
317
|
+
A collection runs one loyalty source: the native schemes here, or an external provider through a
|
|
318
|
+
connector.
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
305
322
|
## TypeScript Types
|
|
306
323
|
|
|
307
324
|
```typescript
|
|
@@ -517,6 +517,9 @@ Prefer the platform primitives above over a dependency; when you do need one, pi
|
|
|
517
517
|
| Check a tapped tag is real | `ctx.sl.tags.resolve(proofId)` → `{ id, claimSetId, code }` or `null` | `sl:tags:read` |
|
|
518
518
|
| Put a visitor's details on a contact | `ctx.sl.contacts.upsert({ email, firstName, … })` → `{ contactId, created }` (fills empty fields only) | `sl:contacts:write` |
|
|
519
519
|
| Record "they did X" | `ctx.sl.interactions.record({ interactionId, contactId, outcome, metadata })` | `sl:interactions:write` |
|
|
520
|
+
| Land a loyalty / CRM provider's view of a person (member id, tier, points, tags, external ids) | `ctx.sl.members.apply({ identity, contact?, loyalty?, tags?, externalIds? }, { provider })` → `{ contactId, op }` — matches by id, external id, email or phone; profile fields fill-empty only; see [connectors.md](connectors.md#loyalty-and-crm-connectors) | `sl:members:write` |
|
|
521
|
+
| Invoke a connector's action — redeem, enrol, issue a coupon, raise a ticket — with the connector's credentials | `ctx.sl.connectors.call('acme-loyalty', 'redeem', { rewardId })` → the action's result; `ctx.sl.connectors.actions(appId)` lists them; see [connectors.md](connectors.md#actions-provider-operations-on-demand) | `sl:connectors:write` |
|
|
522
|
+
| Ask "is this person gold or above?" without holding their member record | `ctx.sl.entitlements.check('tier>=gold')` → `{ allowed, basis, asOf, attributes }` for the signed-in caller (or `{ identity, token, fallback }`); see [entitlements.md](entitlements.md) | `sl:entitlements:read` |
|
|
520
523
|
| Take a booking with your own checks (hours, queue token, payment) | `ctx.sl.bookings.create({ slotId \| resource + time, contactId, status, idempotencyKey })` — never oversold, never double-booked; also `confirm` / `cancel` / `move` / `mine` / `freebusy` / `message` (everyone booked, hydrated) / `slots.*` / `blocks.*` (see [bookings.md](bookings.md)) | `sl:bookings:write` (`sl:bookings:read` to read) |
|
|
521
524
|
|
|
522
525
|
Notes:
|
package/dist/openapi.yaml
CHANGED
|
@@ -21235,6 +21235,32 @@ components:
|
|
|
21235
21235
|
- id
|
|
21236
21236
|
- title
|
|
21237
21237
|
- component
|
|
21238
|
+
ConnectorAction:
|
|
21239
|
+
type: object
|
|
21240
|
+
properties:
|
|
21241
|
+
name:
|
|
21242
|
+
type: string
|
|
21243
|
+
title:
|
|
21244
|
+
type: string
|
|
21245
|
+
description:
|
|
21246
|
+
type: string
|
|
21247
|
+
function:
|
|
21248
|
+
type: string
|
|
21249
|
+
visibility:
|
|
21250
|
+
type: string
|
|
21251
|
+
enum:
|
|
21252
|
+
- admin
|
|
21253
|
+
- member
|
|
21254
|
+
- public
|
|
21255
|
+
input:
|
|
21256
|
+
type: object
|
|
21257
|
+
additionalProperties: true
|
|
21258
|
+
output:
|
|
21259
|
+
type: object
|
|
21260
|
+
additionalProperties: true
|
|
21261
|
+
required:
|
|
21262
|
+
- name
|
|
21263
|
+
- function
|
|
21238
21264
|
AppConnectorDeclaration:
|
|
21239
21265
|
type: object
|
|
21240
21266
|
properties:
|
|
@@ -21280,10 +21306,18 @@ components:
|
|
|
21280
21306
|
type: string
|
|
21281
21307
|
fetch:
|
|
21282
21308
|
type: string
|
|
21309
|
+
describeEvents:
|
|
21310
|
+
type: string
|
|
21311
|
+
lookup:
|
|
21312
|
+
type: string
|
|
21283
21313
|
panels:
|
|
21284
21314
|
type: array
|
|
21285
21315
|
items:
|
|
21286
21316
|
$ref: "#/components/schemas/ConnectorPanel"
|
|
21317
|
+
actions:
|
|
21318
|
+
type: array
|
|
21319
|
+
items:
|
|
21320
|
+
$ref: "#/components/schemas/ConnectorAction"
|
|
21287
21321
|
aiGuide:
|
|
21288
21322
|
type: string
|
|
21289
21323
|
recordId:
|
|
@@ -29014,9 +29048,52 @@ components:
|
|
|
29014
29048
|
additionalProperties: true
|
|
29015
29049
|
required:
|
|
29016
29050
|
- appId
|
|
29051
|
+
EventMappingRule:
|
|
29052
|
+
type: object
|
|
29053
|
+
properties:
|
|
29054
|
+
id:
|
|
29055
|
+
type: string
|
|
29056
|
+
match:
|
|
29057
|
+
type: object
|
|
29058
|
+
additionalProperties: true
|
|
29059
|
+
event:
|
|
29060
|
+
type: string
|
|
29061
|
+
attributes:
|
|
29062
|
+
type: object
|
|
29063
|
+
additionalProperties:
|
|
29064
|
+
type: object
|
|
29065
|
+
additionalProperties: true
|
|
29066
|
+
required:
|
|
29067
|
+
- event
|
|
29068
|
+
EventMapping:
|
|
29069
|
+
type: object
|
|
29070
|
+
properties:
|
|
29071
|
+
rules:
|
|
29072
|
+
type: array
|
|
29073
|
+
items:
|
|
29074
|
+
$ref: "#/components/schemas/EventMappingRule"
|
|
29075
|
+
unmatched:
|
|
29076
|
+
type: string
|
|
29077
|
+
enum:
|
|
29078
|
+
- skip
|
|
29079
|
+
- passthrough
|
|
29080
|
+
required:
|
|
29081
|
+
- rules
|
|
29017
29082
|
IntegrationFlowConfig:
|
|
29018
29083
|
type: object
|
|
29019
29084
|
properties:
|
|
29085
|
+
signing:
|
|
29086
|
+
type: object
|
|
29087
|
+
additionalProperties: true
|
|
29088
|
+
identity:
|
|
29089
|
+
type: object
|
|
29090
|
+
additionalProperties: true
|
|
29091
|
+
eventMapping:
|
|
29092
|
+
$ref: "#/components/schemas/EventMapping"
|
|
29093
|
+
envelopeFormat:
|
|
29094
|
+
type: string
|
|
29095
|
+
enum:
|
|
29096
|
+
- cloudevents
|
|
29020
29097
|
connection:
|
|
29021
29098
|
$ref: "#/components/schemas/FlowConnection"
|
|
29022
29099
|
fieldMappings:
|
|
@@ -29049,9 +29126,11 @@ components:
|
|
|
29049
29126
|
schedule:
|
|
29050
29127
|
type: string
|
|
29051
29128
|
sourceEntity:
|
|
29052
|
-
type:
|
|
29129
|
+
type: object
|
|
29130
|
+
additionalProperties: true
|
|
29053
29131
|
targetEntity:
|
|
29054
|
-
type:
|
|
29132
|
+
type: object
|
|
29133
|
+
additionalProperties: true
|
|
29055
29134
|
config:
|
|
29056
29135
|
$ref: "#/components/schemas/IntegrationFlowConfig"
|
|
29057
29136
|
createdBy:
|
|
@@ -29424,6 +29503,144 @@ components:
|
|
|
29424
29503
|
settings:
|
|
29425
29504
|
type: object
|
|
29426
29505
|
additionalProperties: true
|
|
29506
|
+
ConnectorEventsSchema:
|
|
29507
|
+
type: object
|
|
29508
|
+
properties:
|
|
29509
|
+
events:
|
|
29510
|
+
type: array
|
|
29511
|
+
items:
|
|
29512
|
+
type: object
|
|
29513
|
+
additionalProperties: true
|
|
29514
|
+
limits:
|
|
29515
|
+
type: object
|
|
29516
|
+
additionalProperties: true
|
|
29517
|
+
required:
|
|
29518
|
+
- events
|
|
29519
|
+
ConnectorLookupInput:
|
|
29520
|
+
type: object
|
|
29521
|
+
properties:
|
|
29522
|
+
installation:
|
|
29523
|
+
$ref: "#/components/schemas/ConnectorInstallation"
|
|
29524
|
+
identity:
|
|
29525
|
+
type: object
|
|
29526
|
+
additionalProperties: true
|
|
29527
|
+
want:
|
|
29528
|
+
type: array
|
|
29529
|
+
items:
|
|
29530
|
+
type: string
|
|
29531
|
+
required:
|
|
29532
|
+
- installation
|
|
29533
|
+
- identity
|
|
29534
|
+
ConnectorLookupResult:
|
|
29535
|
+
type: object
|
|
29536
|
+
properties:
|
|
29537
|
+
found:
|
|
29538
|
+
type: boolean
|
|
29539
|
+
memberId:
|
|
29540
|
+
type: string
|
|
29541
|
+
tier:
|
|
29542
|
+
type: string
|
|
29543
|
+
points:
|
|
29544
|
+
type: number
|
|
29545
|
+
status:
|
|
29546
|
+
type: string
|
|
29547
|
+
attributes:
|
|
29548
|
+
type: object
|
|
29549
|
+
additionalProperties: true
|
|
29550
|
+
asOf:
|
|
29551
|
+
type: string
|
|
29552
|
+
required:
|
|
29553
|
+
- found
|
|
29554
|
+
EventEnvelope:
|
|
29555
|
+
type: object
|
|
29556
|
+
properties:
|
|
29557
|
+
specVersion:
|
|
29558
|
+
type: number
|
|
29559
|
+
id:
|
|
29560
|
+
type: string
|
|
29561
|
+
type:
|
|
29562
|
+
type: string
|
|
29563
|
+
entityType:
|
|
29564
|
+
type: string
|
|
29565
|
+
entityId:
|
|
29566
|
+
type: string
|
|
29567
|
+
occurredAt:
|
|
29568
|
+
type: string
|
|
29569
|
+
collectionId:
|
|
29570
|
+
type: string
|
|
29571
|
+
orgId:
|
|
29572
|
+
type: string
|
|
29573
|
+
appId:
|
|
29574
|
+
type: string
|
|
29575
|
+
identity:
|
|
29576
|
+
type: object
|
|
29577
|
+
additionalProperties: true
|
|
29578
|
+
contactId:
|
|
29579
|
+
type: string
|
|
29580
|
+
userId:
|
|
29581
|
+
type: string
|
|
29582
|
+
externalIds:
|
|
29583
|
+
type: object
|
|
29584
|
+
additionalProperties:
|
|
29585
|
+
type: string
|
|
29586
|
+
anonymousId:
|
|
29587
|
+
type: string
|
|
29588
|
+
sessionId:
|
|
29589
|
+
type: string
|
|
29590
|
+
emailHash:
|
|
29591
|
+
type: string
|
|
29592
|
+
phoneHash:
|
|
29593
|
+
type: string
|
|
29594
|
+
hashAlgorithm:
|
|
29595
|
+
type: string
|
|
29596
|
+
enum:
|
|
29597
|
+
- hmac-sha256
|
|
29598
|
+
email:
|
|
29599
|
+
type: string
|
|
29600
|
+
phone:
|
|
29601
|
+
type: string
|
|
29602
|
+
identityPolicy:
|
|
29603
|
+
$ref: "#/components/schemas/IdentityPolicy"
|
|
29604
|
+
product:
|
|
29605
|
+
type: object
|
|
29606
|
+
additionalProperties: true
|
|
29607
|
+
proof:
|
|
29608
|
+
type: object
|
|
29609
|
+
additionalProperties: true
|
|
29610
|
+
consent:
|
|
29611
|
+
type: object
|
|
29612
|
+
additionalProperties: true
|
|
29613
|
+
subject:
|
|
29614
|
+
type: object
|
|
29615
|
+
additionalProperties: true
|
|
29616
|
+
event:
|
|
29617
|
+
type: object
|
|
29618
|
+
additionalProperties: true
|
|
29619
|
+
attributes:
|
|
29620
|
+
type: object
|
|
29621
|
+
additionalProperties: true
|
|
29622
|
+
required:
|
|
29623
|
+
- specVersion
|
|
29624
|
+
- id
|
|
29625
|
+
- type
|
|
29626
|
+
- entityType
|
|
29627
|
+
- entityId
|
|
29628
|
+
- occurredAt
|
|
29629
|
+
- collectionId
|
|
29630
|
+
- orgId
|
|
29631
|
+
- appId
|
|
29632
|
+
- identity
|
|
29633
|
+
- contactId
|
|
29634
|
+
- userId
|
|
29635
|
+
- externalIds
|
|
29636
|
+
- anonymousId
|
|
29637
|
+
- sessionId
|
|
29638
|
+
- identityPolicy
|
|
29639
|
+
- product
|
|
29640
|
+
- proof
|
|
29641
|
+
- consent
|
|
29642
|
+
- subject
|
|
29643
|
+
- attributes
|
|
29427
29644
|
CapturedRequest:
|
|
29428
29645
|
type: object
|
|
29429
29646
|
properties:
|
|
@@ -29763,6 +29980,24 @@ components:
|
|
|
29763
29980
|
- webhook
|
|
29764
29981
|
- oauth2
|
|
29765
29982
|
- none
|
|
29983
|
+
IdentityPolicy:
|
|
29984
|
+
type: string
|
|
29985
|
+
enum:
|
|
29986
|
+
- externalIds
|
|
29987
|
+
- hashed
|
|
29988
|
+
- raw
|
|
29989
|
+
FlowSourceEntity:
|
|
29990
|
+
type: string
|
|
29991
|
+
enum:
|
|
29992
|
+
- product
|
|
29993
|
+
- interaction
|
|
29994
|
+
- contact
|
|
29995
|
+
- event
|
|
29996
|
+
FlowTargetEntity:
|
|
29997
|
+
type: string
|
|
29998
|
+
enum:
|
|
29999
|
+
- product
|
|
30000
|
+
- contact
|
|
29766
30001
|
UpdateFlowInput:
|
|
29767
30002
|
$ref: "#/components/schemas/CreateFlowInput"
|
|
29768
30003
|
ConnectorConsoleStep:
|
|
@@ -29773,6 +30008,8 @@ components:
|
|
|
29773
30008
|
- sample
|
|
29774
30009
|
- shape
|
|
29775
30010
|
- serialize
|
|
30011
|
+
- describeEvents
|
|
30012
|
+
- lookup
|
|
29776
30013
|
RunTrigger:
|
|
29777
30014
|
type: string
|
|
29778
30015
|
enum:
|
|
@@ -1030,6 +1030,27 @@ export interface ConnectorPanel {
|
|
|
1030
1030
|
/** Exported component name in the app's widgets bundle (manifest `widgets.files`). */
|
|
1031
1031
|
component: string;
|
|
1032
1032
|
}
|
|
1033
|
+
/**
|
|
1034
|
+
* A named provider operation invoked ON DEMAND (not by the engine): redeem a reward, enrol a member,
|
|
1035
|
+
* issue a coupon, raise a ticket, send a receipt. Called by an app function (`ctx.sl.connectors.call`),
|
|
1036
|
+
* by the Hub (public route — only `public`, or `member` for a signed-in person) or by the console. The
|
|
1037
|
+
* function receives `{ input, installation, caller }` and returns JSON; it runs with the connector's
|
|
1038
|
+
* own credentials and is told who asked.
|
|
1039
|
+
*/
|
|
1040
|
+
export interface ConnectorAction {
|
|
1041
|
+
/** `^[a-zA-Z][a-zA-Z0-9_-]{0,63}$` */
|
|
1042
|
+
name: string;
|
|
1043
|
+
title?: string;
|
|
1044
|
+
description?: string;
|
|
1045
|
+
/** This app's server function implementing it. */
|
|
1046
|
+
function: string;
|
|
1047
|
+
/** Who may invoke it outside functions and the console. Default 'admin'. */
|
|
1048
|
+
visibility?: 'admin' | 'member' | 'public';
|
|
1049
|
+
/** JSON Schema for `input`; `required` fields are checked before the function runs. */
|
|
1050
|
+
input?: Record<string, unknown>;
|
|
1051
|
+
/** JSON Schema for the result (documentation; not enforced). */
|
|
1052
|
+
output?: Record<string, unknown>;
|
|
1053
|
+
}
|
|
1033
1054
|
/**
|
|
1034
1055
|
* The connector contract. Every function named here is one of this app's server functions
|
|
1035
1056
|
* (manifest `functions.definitions`); the engine calls it with collection authority, capped by the
|
|
@@ -1078,8 +1099,22 @@ export interface AppConnectorDeclaration {
|
|
|
1078
1099
|
send?: string;
|
|
1079
1100
|
/** (ConnectorFetchInput) → ConnectorRecords: inbound pull, one page per call. */
|
|
1080
1101
|
fetch?: string;
|
|
1102
|
+
/**
|
|
1103
|
+
* Loyalty / engagement providers: → ConnectorEventsSchema, the event names (and attributes) the
|
|
1104
|
+
* provider has registered for this installation. A flow's eventMapping is validated against it when
|
|
1105
|
+
* saved, so a mapping that names an unregistered event or breaks a limit is refused with the reason.
|
|
1106
|
+
*/
|
|
1107
|
+
describeEvents?: string;
|
|
1108
|
+
/**
|
|
1109
|
+
* (ConnectorLookupInput) → ConnectorLookupResult: one identity → member id, tier, points, status.
|
|
1110
|
+
* Called by the entitlement check (see docs/entitlements.md) through a cache keyed on an identity
|
|
1111
|
+
* hash, for the TTL the collection sets — one call per active person per TTL, never a sync.
|
|
1112
|
+
*/
|
|
1113
|
+
lookup?: string;
|
|
1081
1114
|
};
|
|
1082
1115
|
panels?: ConnectorPanel[];
|
|
1116
|
+
/** On-demand operations the connector offers (see ConnectorAction). */
|
|
1117
|
+
actions?: ConnectorAction[];
|
|
1083
1118
|
/** Path (under the app's public files) of a guide the AI mapping assistant reads. */
|
|
1084
1119
|
aiGuide?: string;
|
|
1085
1120
|
/**
|
|
@@ -1088,9 +1123,15 @@ export interface AppConnectorDeclaration {
|
|
|
1088
1123
|
* Default 'id'; a flow can override it with `config.upsert.externalIdPath`.
|
|
1089
1124
|
*/
|
|
1090
1125
|
recordId?: string;
|
|
1091
|
-
/**
|
|
1126
|
+
/**
|
|
1127
|
+
* Requests per second toward the provider, shared by every SmartLinks worker; and, for providers that
|
|
1128
|
+
* cap registered events, how many distinct events / attributes per event they accept (a flow's
|
|
1129
|
+
* eventMapping is checked against them when saved).
|
|
1130
|
+
*/
|
|
1092
1131
|
limits?: {
|
|
1093
1132
|
requestsPerSecond?: number;
|
|
1133
|
+
maxEvents?: number;
|
|
1134
|
+
maxAttributes?: number;
|
|
1094
1135
|
};
|
|
1095
1136
|
}
|
|
1096
1137
|
/**
|
|
@@ -38,7 +38,66 @@ export interface FlowConnectorRef {
|
|
|
38
38
|
/** Per-flow settings, layered over the installation's. */
|
|
39
39
|
settings?: Record<string, unknown>;
|
|
40
40
|
}
|
|
41
|
+
import type { ConnectorInstallation } from './appManifest.js';
|
|
42
|
+
/** What about a person an event-sourced flow lets leave. Default 'hashed'. */
|
|
43
|
+
export type IdentityPolicy = 'externalIds' | 'hashed' | 'raw';
|
|
44
|
+
/**
|
|
45
|
+
* Many SmartLinks events → the provider's few registered event names. Rules are tried in order; the
|
|
46
|
+
* first match names the provider event and renders its attributes (a literal, a Liquid template over
|
|
47
|
+
* the envelope, or `{ path, default }`). An unmatched event is skipped (recorded as such) unless
|
|
48
|
+
* `unmatched: 'passthrough'`. Validated against the connector's `describeEvents` when the flow is saved.
|
|
49
|
+
*/
|
|
50
|
+
export interface EventMappingRule {
|
|
51
|
+
id?: string;
|
|
52
|
+
match?: {
|
|
53
|
+
types?: string[];
|
|
54
|
+
interactionIds?: string[];
|
|
55
|
+
outcomes?: string[];
|
|
56
|
+
appIds?: string[];
|
|
57
|
+
};
|
|
58
|
+
/** The provider's registered event name. */
|
|
59
|
+
event: string;
|
|
60
|
+
attributes?: Record<string, string | number | boolean | {
|
|
61
|
+
path: string;
|
|
62
|
+
default?: unknown;
|
|
63
|
+
} | {
|
|
64
|
+
value: unknown;
|
|
65
|
+
}>;
|
|
66
|
+
}
|
|
67
|
+
export interface EventMapping {
|
|
68
|
+
rules: EventMappingRule[];
|
|
69
|
+
unmatched?: 'skip' | 'passthrough';
|
|
70
|
+
}
|
|
71
|
+
/** What an outbound flow reads: the product that changed, or ONE spine event as the envelope. */
|
|
72
|
+
export type FlowSourceEntity = 'product' | 'interaction' | 'contact' | 'event';
|
|
73
|
+
/** What an inbound flow writes. */
|
|
74
|
+
export type FlowTargetEntity = 'product' | 'contact';
|
|
41
75
|
export interface IntegrationFlowConfig {
|
|
76
|
+
/**
|
|
77
|
+
* Signed deliveries: X-SmartLinks-Signature `t=<unix>,v1=<hex HMAC-SHA256(secret, t + '.' + body)>`
|
|
78
|
+
* over the exact bytes sent. `previousCredentialRef` keeps the old secret signing during a rotation.
|
|
79
|
+
*/
|
|
80
|
+
signing?: {
|
|
81
|
+
credentialRef: string;
|
|
82
|
+
previousCredentialRef?: string;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Event-sourced flows: what about the person leaves (default 'hashed': ids + HMAC hashes of email and
|
|
86
|
+
* phone, never the values). `hashKeyCredentialRef` names the brand's own hash key, so hashes match a
|
|
87
|
+
* mirror they built; otherwise a per-collection platform key is used.
|
|
88
|
+
*/
|
|
89
|
+
identity?: {
|
|
90
|
+
policy?: IdentityPolicy;
|
|
91
|
+
hashKeyCredentialRef?: string;
|
|
92
|
+
};
|
|
93
|
+
/** Event-sourced flows: fold SmartLinks events into the provider's registered events. */
|
|
94
|
+
eventMapping?: EventMapping;
|
|
95
|
+
/**
|
|
96
|
+
* Wrap each delivered body as a CloudEvents 1.0 structured event
|
|
97
|
+
* ({ specversion, id, type, source, subject, time, datacontenttype, dataschema, data }) — the shape
|
|
98
|
+
* event buses, lakes and serverless tools consume without custom code.
|
|
99
|
+
*/
|
|
100
|
+
envelopeFormat?: 'cloudevents';
|
|
42
101
|
connection?: FlowConnection;
|
|
43
102
|
fieldMappings?: FieldMapping[];
|
|
44
103
|
/** Run this flow through a connector app's functions instead of the built-in mapper/transport. */
|
|
@@ -57,8 +116,10 @@ export interface IntegrationFlow {
|
|
|
57
116
|
eventTypes: string[];
|
|
58
117
|
/** Cron/interval string for scheduled flows, or null. */
|
|
59
118
|
schedule: string | null;
|
|
60
|
-
|
|
61
|
-
|
|
119
|
+
/** Outbound: what the flow reads (product | interaction | contact | event). */
|
|
120
|
+
sourceEntity: FlowSourceEntity | string | null;
|
|
121
|
+
/** Inbound: what the flow writes (product | contact). */
|
|
122
|
+
targetEntity: FlowTargetEntity | string | null;
|
|
62
123
|
config: IntegrationFlowConfig;
|
|
63
124
|
createdBy: string | null;
|
|
64
125
|
createdAt: string;
|
|
@@ -267,7 +328,111 @@ export interface SaveConnectorInstallationInput {
|
|
|
267
328
|
settings?: Record<string, unknown>;
|
|
268
329
|
}
|
|
269
330
|
/** Steps the console may run directly (send and fetch only run inside a flow; shape/serialize as dry runs). */
|
|
270
|
-
export type ConnectorConsoleStep = 'testConnection' | 'describeTarget' | 'sample' | 'shape' | 'serialize';
|
|
331
|
+
export type ConnectorConsoleStep = 'testConnection' | 'describeTarget' | 'sample' | 'shape' | 'serialize' | 'describeEvents' | 'lookup';
|
|
332
|
+
/** `describeEvents` → what the provider has registered for this installation (loyalty / engagement). */
|
|
333
|
+
export interface ConnectorEventsSchema {
|
|
334
|
+
events: Array<{
|
|
335
|
+
name: string;
|
|
336
|
+
title?: string;
|
|
337
|
+
attributes?: Array<{
|
|
338
|
+
name: string;
|
|
339
|
+
type?: string;
|
|
340
|
+
required?: boolean;
|
|
341
|
+
}>;
|
|
342
|
+
}>;
|
|
343
|
+
limits?: {
|
|
344
|
+
maxEvents?: number;
|
|
345
|
+
maxAttributes?: number;
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
/** `lookup` input: one identity, as the collection's lookup policy sends it (raw, or hashed). */
|
|
349
|
+
export interface ConnectorLookupInput {
|
|
350
|
+
installation: ConnectorInstallation;
|
|
351
|
+
identity: {
|
|
352
|
+
externalId?: string | null;
|
|
353
|
+
email?: string | null;
|
|
354
|
+
phone?: string | null;
|
|
355
|
+
emailHash?: string | null;
|
|
356
|
+
phoneHash?: string | null;
|
|
357
|
+
contactId?: string | null;
|
|
358
|
+
};
|
|
359
|
+
/** Attribute names the gate wants, e.g. ['tier', 'points', 'status']. */
|
|
360
|
+
want?: string[];
|
|
361
|
+
}
|
|
362
|
+
/** `lookup` result. Throw (or return non-2xx) for an outage — never `found: false`. */
|
|
363
|
+
export interface ConnectorLookupResult {
|
|
364
|
+
found: boolean;
|
|
365
|
+
memberId?: string | null;
|
|
366
|
+
tier?: string | null;
|
|
367
|
+
points?: number | null;
|
|
368
|
+
status?: string | null;
|
|
369
|
+
attributes?: Record<string, unknown>;
|
|
370
|
+
/** When the provider's answer is from (ISO). */
|
|
371
|
+
asOf?: string | null;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* The one shape a SmartLinks event has when it leaves the platform — what event-sourced flows hand a
|
|
375
|
+
* connector's `serialize` / `send`, after the flow's identity policy and event mapping.
|
|
376
|
+
*/
|
|
377
|
+
export interface EventEnvelope {
|
|
378
|
+
/** Schema version of this envelope. Bumped only when a consumer could break (a field removed or changed). */
|
|
379
|
+
specVersion: number;
|
|
380
|
+
/** The event's id: stable across retries; use it as the provider's transaction / idempotency id. */
|
|
381
|
+
id: string;
|
|
382
|
+
/** Spine event name, e.g. 'interaction.submitted:<typeId>', 'contact.updated', 'tag.scanned:scan_redirect'. */
|
|
383
|
+
type: string;
|
|
384
|
+
entityType: string | null;
|
|
385
|
+
entityId: string | null;
|
|
386
|
+
occurredAt: string;
|
|
387
|
+
collectionId: string;
|
|
388
|
+
orgId: string;
|
|
389
|
+
appId: string | null;
|
|
390
|
+
identity: {
|
|
391
|
+
contactId: string | null;
|
|
392
|
+
userId: string | null;
|
|
393
|
+
/** Ids other systems know this person by, keyed by system (a connector's `provider`). */
|
|
394
|
+
externalIds: Record<string, string>;
|
|
395
|
+
/** The visitor / device id before anyone signed in (an analytics destination stitches on it later). Under every policy. */
|
|
396
|
+
anonymousId: string | null;
|
|
397
|
+
sessionId: string | null;
|
|
398
|
+
emailHash?: string | null;
|
|
399
|
+
phoneHash?: string | null;
|
|
400
|
+
hashAlgorithm?: 'hmac-sha256' | null;
|
|
401
|
+
/** Only under identity policy 'raw'. */
|
|
402
|
+
email?: string | null;
|
|
403
|
+
phone?: string | null;
|
|
404
|
+
};
|
|
405
|
+
identityPolicy: IdentityPolicy;
|
|
406
|
+
product: {
|
|
407
|
+
id: string;
|
|
408
|
+
name?: string | null;
|
|
409
|
+
sku?: string | null;
|
|
410
|
+
gtin?: string | null;
|
|
411
|
+
variantId?: string | null;
|
|
412
|
+
batchId?: string | null;
|
|
413
|
+
} | null;
|
|
414
|
+
proof: {
|
|
415
|
+
id: string;
|
|
416
|
+
} | null;
|
|
417
|
+
/**
|
|
418
|
+
* The person's communication consent, summarised per channel from the contact's comms state; null
|
|
419
|
+
* when the event is about nobody we hold. A CRM or CDP must not act against it.
|
|
420
|
+
*/
|
|
421
|
+
consent: {
|
|
422
|
+
channels: Record<'email' | 'sms' | 'push' | 'whatsapp', 'opted_in' | 'opted_out' | 'suppressed' | 'unknown'>;
|
|
423
|
+
topics: Record<string, boolean>;
|
|
424
|
+
updatedAt: string | null;
|
|
425
|
+
} | null;
|
|
426
|
+
/** The event's own fields: an interaction's interactionId / outcome / metadata, a scan's codeId / country, a contact's profile. */
|
|
427
|
+
subject: Record<string, unknown>;
|
|
428
|
+
/** From the flow's event mapping, when it has one. */
|
|
429
|
+
event?: {
|
|
430
|
+
name: string;
|
|
431
|
+
attributes: Record<string, unknown>;
|
|
432
|
+
rule: string | null;
|
|
433
|
+
};
|
|
434
|
+
attributes: Record<string, unknown>;
|
|
435
|
+
}
|
|
271
436
|
export type RunTrigger = 'manual' | 'event' | 'schedule' | 'test';
|
|
272
437
|
export type FlowRunStatus = 'running' | 'success' | 'partial' | 'failed' | 'skipped';
|
|
273
438
|
export type FlowRunItemStatus = 'sent' | 'failed' | 'skipped';
|