@tangle-network/agent-integrations 0.6.0 → 0.7.1

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/README.md CHANGED
@@ -1,156 +1,158 @@
1
- # Agent Integrations
2
-
3
- `@tangle-network/agent-integrations` is a vendor-neutral integration layer for
4
- apps, sandboxes, and agents that need user-authorized connections such as email,
5
- calendar, Slack, CRM, storage, webhooks, and workflow triggers.
6
-
7
- The package does not pick a single integration vendor. Nango, Pipedream,
8
- Zapier-style platforms, Activepieces, executor services, and first-party
9
- connectors should all sit behind the same provider interface.
10
-
11
- ## Mental Model
1
+ # @tangle-network/agent-integrations
2
+
3
+ Vendor-neutral integration contracts for agent apps, sandboxes, and generated
4
+ software that need user-authorized access to external systems.
5
+
6
+ The package standardizes connector catalogs, user connections, scoped sandbox
7
+ capabilities, action invocation, trigger events, provider adapters, and
8
+ first-party connector adapters. Product code can route through Nango, Pipedream,
9
+ Activepieces, a custom gateway, or first-party adapters without changing the
10
+ agent-facing tool contract.
11
+
12
+ ## Contents
13
+
14
+ - [What It Provides](#what-it-provides)
15
+ - [Architecture](#architecture)
16
+ - [Install](#install)
17
+ - [Core Primitives](#core-primitives)
18
+ - [Provider Strategy](#provider-strategy)
19
+ - [Executable Coverage](#executable-coverage)
20
+ - [Examples](#examples)
21
+ - [Security Model](#security-model)
22
+ - [Development](#development)
23
+
24
+ ## What It Provides
25
+
26
+ - A normalized connector/action/trigger catalog.
27
+ - User-owned connection records that reference secrets without storing raw
28
+ credentials in public shapes.
29
+ - Short-lived capability tokens for sandbox-safe access to a subset of a user's
30
+ connection.
31
+ - Policy checks for read/write/destructive actions.
32
+ - Invocation-envelope validation before sandbox tool calls reach the hub.
33
+ - A generic HTTP provider boundary for hosted integration gateways.
34
+ - A first-party `ConnectorAdapter` boundary for direct provider execution.
35
+ - A declarative REST adapter factory for promoting REST APIs from reviewed specs.
36
+ - A broad coverage catalog for planning hundreds of integrations without
37
+ pretending every catalog item is executable.
38
+
39
+ ## Architecture
12
40
 
13
41
  ```txt
14
- Connector catalog -> User connection -> Scoped capability -> Action or trigger
42
+ connector catalog
43
+ -> user connection
44
+ -> scoped capability
45
+ -> policy decision
46
+ -> provider/action invocation
47
+ -> audit-safe result or normalized trigger event
15
48
  ```
16
49
 
17
- - **Connectors** describe what can be connected: Gmail, Google Calendar, Slack,
18
- HubSpot, webhooks, internal tools.
19
- - **Connections** are user/team-owned grants. They carry secret references, not
20
- raw credentials.
21
- - **Capabilities** are short-lived, sandbox-safe tokens that authorize a subset
22
- of actions on a connection.
23
- - **Actions** are read/write/destructive operations.
24
- - **Triggers** normalize inbound events from providers into one event shape.
50
+ Main boundaries:
25
51
 
26
- ## Why This Exists
52
+ - `IntegrationHub`: product-facing facade for catalogs, connections,
53
+ capabilities, and action invocation.
54
+ - `IntegrationProvider`: vendor or gateway implementation boundary.
55
+ - `ConnectorAdapter`: first-party connector boundary for direct API execution.
56
+ - `IntegrationActionGuard`: optional cross-cutting hook for idempotency,
57
+ approval, audit logging, rate limits, and conflict handling.
27
58
 
28
- Agent Builder and sandbox apps need to support prompts like:
59
+ ## Install
29
60
 
30
- ```txt
31
- At Gmail, build me an app that summarizes unread support emails and drafts replies.
61
+ ```sh
62
+ pnpm add @tangle-network/agent-integrations
32
63
  ```
33
64
 
34
- The generated app should be able to request Gmail access, instantiate inside the
35
- user's sandbox, and let the agent read/write through a scoped integration
36
- capability. The sandbox should never receive reusable provider secrets.
37
-
38
- ## Core Usage
39
-
40
- ### Product Flow
41
-
42
- For Agent Builder and sandbox apps, the intended flow is:
43
-
44
- ```txt
45
- generated app declares required tools
46
- -> app searches the integration catalog by intent
47
- -> user connects the missing accounts
48
- -> runtime issues a short-lived capability to the sandbox
49
- -> reads run immediately
50
- -> writes pause for policy approval
51
- -> every call returns an audit-safe result
65
+ ## Core Primitives
66
+
67
+ | Primitive | Purpose |
68
+ |---|---|
69
+ | `IntegrationConnector` | Normalized catalog entry for a provider connection. |
70
+ | `IntegrationConnection` | User/team/agent-owned grant with scopes and secret references. |
71
+ | `IntegrationHub` | Facade for provider catalogs, connection storage, capabilities, and invocation. |
72
+ | `IntegrationCapability` | Short-lived authorization for a specific subject, connection, scope set, and action set. |
73
+ | `buildIntegrationToolCatalog` | Converts connector actions into agent/tool definitions. |
74
+ | `searchIntegrationTools` | Intent search over normalized integration tools. |
75
+ | `buildIntegrationCoverageConnectors` | Planning catalog for 100+ high-value integrations. |
76
+ | `buildIntegrationInvocationEnvelope` | Sandbox-safe action envelope. |
77
+ | `validateIntegrationInvocationEnvelope` | Runtime validation for tool/action consistency and input limits. |
78
+ | `createHttpIntegrationProvider` | Adapter for hosted integration gateways. |
79
+ | `createConnectorAdapterProvider` | Runs first-party `ConnectorAdapter`s through the same provider contract. |
80
+ | `declarativeRestConnector` | Builds REST-backed first-party adapters from compact specs. |
81
+
82
+ ## Provider Strategy
83
+
84
+ The package deliberately avoids vendor lock-in.
85
+
86
+ - Use a hosted gateway when it compresses long-tail OAuth/API coverage.
87
+ - Promote high-volume, sensitive, or strategically important integrations to
88
+ first-party adapters.
89
+ - Keep product and sandbox code on `IntegrationHub` contracts so provider changes
90
+ do not alter generated apps or agent tool calls.
91
+ - Treat catalog coverage and executable coverage as different states.
92
+
93
+ See [Provider Decision Matrix](./docs/provider-decision-matrix.md).
94
+
95
+ ## Executable Coverage
96
+
97
+ Current first-party adapters:
98
+
99
+ - Google Calendar
100
+ - Microsoft Calendar
101
+ - Google Sheets
102
+ - Slack
103
+ - Slack Events
104
+ - HubSpot
105
+ - Notion database
106
+ - Stripe payments pack
107
+ - Stripe webhook receiver
108
+ - Twilio SMS
109
+ - Generic webhook
110
+ - GitHub
111
+ - GitLab
112
+ - Airtable
113
+ - Asana
114
+ - Salesforce
115
+
116
+ Broad planning coverage is generated from
117
+ `buildIntegrationCoverageConnectors()` and tracked in
118
+ [Integration Coverage Checklist](./docs/integration-coverage-checklist.md).
119
+
120
+ ## Examples
121
+
122
+ Runnable examples live in [`examples/`](./examples):
123
+
124
+ - [`examples/basic-hub.ts`](./examples/basic-hub.ts) - catalog search,
125
+ connection storage, capability issue, and action invocation.
126
+ - [`examples/first-party-adapter.ts`](./examples/first-party-adapter.ts) -
127
+ first-party adapter provider wiring.
128
+ - [`examples/declarative-rest.ts`](./examples/declarative-rest.ts) - compact
129
+ REST connector spec.
130
+
131
+ The README stays short; examples are separate so they can be copied and expanded
132
+ without obscuring the package contract.
133
+
134
+ ## Security Model
135
+
136
+ - Capability tokens expire.
137
+ - Capability tokens do not contain provider credentials.
138
+ - Connection records carry secret references, not raw secrets.
139
+ - Write and destructive actions can require approval.
140
+ - Invocation envelopes validate action/tool consistency, idempotency keys,
141
+ metadata shape, known tools, and input size.
142
+ - Action invocation checks ownership, connection status, scopes, allowed actions,
143
+ and expiration.
144
+ - `IntegrationActionGuard` can enforce idempotency, approval, audit logging,
145
+ conflict handling, and rate limits across all providers.
146
+
147
+ ## Development
148
+
149
+ ```sh
150
+ pnpm install
151
+ pnpm typecheck
152
+ pnpm test
153
+ pnpm build
52
154
  ```
53
155
 
54
- The SDK surface for that flow is:
55
-
56
- - `buildIntegrationToolCatalog` and `searchIntegrationTools` for discoverable
57
- tool catalogs.
58
- - `buildIntegrationCoverageConnectors` for broad planning coverage across
59
- 100+ high-value integrations before each one has a first-party executor.
60
- - `toMcpTools` for MCP-compatible tool export.
61
- - `IntegrationHub.issueCapability` for scoped sandbox handoff.
62
- - `createDefaultIntegrationPolicyEngine` for allow / approval / deny decisions.
63
- - `buildIntegrationInvocationEnvelope` and
64
- `validateIntegrationInvocationEnvelope` for sandbox-safe tool calls with
65
- action/tool consistency, idempotency-key, metadata-shape, known-tool, and
66
- input-size checks.
67
- - `createConnectorAdapterProvider` to run first-party adapters through the hub.
68
-
69
- ```ts
70
- import {
71
- InMemoryConnectionStore,
72
- IntegrationHub,
73
- buildIntegrationToolCatalog,
74
- createMockIntegrationProvider,
75
- searchIntegrationTools,
76
- } from '@tangle-network/agent-integrations'
77
-
78
- const provider = createMockIntegrationProvider()
79
- const hub = new IntegrationHub({
80
- providers: [provider],
81
- store: new InMemoryConnectionStore(),
82
- capabilitySecret: 'dev-secret',
83
- })
84
-
85
- const catalog = buildIntegrationToolCatalog(await hub.listConnectors())
86
- const tools = searchIntegrationTools(catalog, 'search unread gmail', { maxRisk: 'read' })
87
-
88
- const connection = await hub.upsertConnection({
89
- id: 'conn_1',
90
- owner: { type: 'user', id: 'user_1' },
91
- providerId: 'mock',
92
- connectorId: 'gmail',
93
- status: 'active',
94
- grantedScopes: ['email.read'],
95
- createdAt: new Date().toISOString(),
96
- updatedAt: new Date().toISOString(),
97
- })
98
-
99
- const capability = await hub.issueCapability({
100
- subject: { type: 'sandbox', id: 'sandbox_1' },
101
- connectionId: connection.id,
102
- scopes: ['email.read'],
103
- allowedActions: ['messages.search'],
104
- ttlMs: 60_000,
105
- })
106
-
107
- const result = await hub.invokeWithCapability(capability.token, {
108
- action: 'messages.search',
109
- input: { q: 'is:unread' },
110
- })
111
- ```
112
-
113
- ## Provider Boundary
114
-
115
- Providers implement OAuth, action execution, and optional triggers. Product code
116
- should depend on `IntegrationHub`, not on a vendor SDK.
117
-
118
- Provider adapters are expected to store raw credentials in their own secure
119
- vault or return secret references. Connection records should remain safe to log
120
- after sanitization.
121
-
122
- For a hosted integration gateway, use the generic HTTP adapter:
123
-
124
- ```ts
125
- import { createHttpIntegrationProvider } from '@tangle-network/agent-integrations'
126
-
127
- const provider = createHttpIntegrationProvider({
128
- id: 'gateway',
129
- kind: 'pipedream',
130
- baseUrl: 'https://integrations.example',
131
- bearer: process.env.INTEGRATION_GATEWAY_TOKEN,
132
- connectors: [/* normalized connector catalog */],
133
- })
134
- ```
156
+ ## License
135
157
 
136
- The HTTP adapter keeps product code stable while the backing provider can be
137
- Nango, Pipedream, Activepieces, a Zapier-style service, or an internal gateway.
138
-
139
- See [Provider Decision Matrix](./docs/provider-decision-matrix.md) for the
140
- build-vs-buy policy. The short version: use a vendor gateway only to compress
141
- time-to-coverage, but keep all product and sandbox code on this package's
142
- contracts so high-volume or strategic connectors can be moved first-party
143
- without changing agent code.
144
-
145
- ## Security Defaults
146
-
147
- - Capabilities expire.
148
- - Capability tokens contain no provider credential.
149
- - Secret refs are redacted from public telemetry.
150
- - Write/destructive actions can be policy-gated.
151
- - Sandbox invocation envelopes are validated before conversion to hub requests.
152
- - Action invocation checks connection ownership, status, scopes, allowed
153
- actions, and expiration.
154
- - Optional `IntegrationActionGuard` wraps every action invocation for
155
- idempotency, audit logging, conflict detection, rate limits, and
156
- approval gates.
158
+ MIT
package/dist/index.d.ts CHANGED
@@ -789,6 +789,51 @@ interface NotionDatabaseOptions {
789
789
  }
790
790
  declare function notionDatabase(opts: NotionDatabaseOptions): ConnectorAdapter;
791
791
 
792
+ type RestCredentialPlacement = {
793
+ kind: 'bearer';
794
+ } | {
795
+ kind: 'header';
796
+ header: string;
797
+ prefix?: string;
798
+ } | {
799
+ kind: 'query';
800
+ parameter: string;
801
+ };
802
+ interface RestConnectorSpec {
803
+ kind: string;
804
+ displayName: string;
805
+ description: string;
806
+ auth: ConnectorAdapter['manifest']['auth'];
807
+ category: ConnectorAdapter['manifest']['category'];
808
+ defaultConsistencyModel: ConnectorAdapter['manifest']['defaultConsistencyModel'];
809
+ baseUrl: string | {
810
+ metadataKey: string;
811
+ fallback?: string;
812
+ };
813
+ credentialPlacement?: RestCredentialPlacement;
814
+ defaultHeaders?: Record<string, string>;
815
+ capabilities: RestOperationSpec[];
816
+ test?: RestRequestSpec;
817
+ }
818
+ interface RestOperationSpec {
819
+ name: string;
820
+ class: 'read' | 'mutation';
821
+ description: string;
822
+ parameters: Record<string, unknown>;
823
+ requiredScopes?: string[];
824
+ request: RestRequestSpec;
825
+ cas?: 'etag-if-match' | 'native-idempotency' | 'optimistic-read-verify' | 'none';
826
+ externalEffect?: boolean;
827
+ }
828
+ interface RestRequestSpec {
829
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
830
+ path: string;
831
+ query?: Record<string, string | number | boolean | undefined>;
832
+ headers?: Record<string, string>;
833
+ body?: 'args' | string | Record<string, unknown>;
834
+ }
835
+ declare function declarativeRestConnector(spec: RestConnectorSpec): ConnectorAdapter;
836
+
792
837
  /**
793
838
  * Twilio SMS connector — outbound texts + recent-message lookup. The
794
839
  * agent's "send the caller a confirmation link" surface.
@@ -922,6 +967,16 @@ declare const stripeWebhookReceiverConnector: ConnectorAdapter;
922
967
 
923
968
  declare const slackEventsConnector: ConnectorAdapter;
924
969
 
970
+ declare const githubConnector: ConnectorAdapter;
971
+
972
+ declare const gitlabConnector: ConnectorAdapter;
973
+
974
+ declare const airtableConnector: ConnectorAdapter;
975
+
976
+ declare const asanaConnector: ConnectorAdapter;
977
+
978
+ declare const salesforceConnector: ConnectorAdapter;
979
+
925
980
  interface IntegrationToolDefinition {
926
981
  name: string;
927
982
  title: string;
@@ -1446,4 +1501,4 @@ declare function createHttpIntegrationProvider(options: HttpIntegrationProviderO
1446
1501
  declare function signCapability(capability: IntegrationCapability, secret: string): string;
1447
1502
  declare function verifyCapabilityToken(token: string, secret: string): IntegrationCapability;
1448
1503
 
1449
- export { type AuthSpec, type CASStrategy, type Capability, type CapabilityClass, type CapabilityMutation, type CapabilityMutationResult, type CapabilityParameterSchema, type CapabilityRead, type CapabilityReadResult, type CompleteAuthRequest, type ConnectorAdapter, type ConnectorAdapterProviderOptions, type ConnectorCredentials, type ConnectorInvocation, type ConnectorManifest, type ConnectorManifestValidationIssue, type ConnectorManifestValidationResult, type ConsistencyModel, CredentialsExpired, DEFAULT_SIGNATURE_TOLERANCE_SECONDS, type DataSourceMetadata, type EventHandlerResult, type ExchangeCodeInput, type GenericHmacVerifyOptions, type GoogleCalendarOptions, type GoogleSheetsOptions, type GraphqlOperationSpec, type HttpIntegrationProviderOptions, type HubSpotOptions, type ImportCatalogOptions, InMemoryConnectionStore, InMemoryOAuthFlowStore, type InboundEvent, type IntegrationActionGuard, type IntegrationActionPack, type IntegrationActionRequest, type IntegrationActionResult, type IntegrationActionRisk, type IntegrationActor, type IntegrationApprovalRequest, type IntegrationApprovalResolution, type IntegrationCapability, type IntegrationConnection, type IntegrationConnectionStore, type IntegrationConnector, type IntegrationConnectorAction, type IntegrationConnectorCategory, type IntegrationConnectorTrigger, type IntegrationCoveragePriority, type IntegrationCoverageSpec, type IntegrationDataClass, IntegrationError, type IntegrationGuardContext, IntegrationHub, type IntegrationHubOptions, type IntegrationInvocationEnvelope, type IntegrationInvocationEnvelopeValidationOptions, type IntegrationPolicyDecision, type IntegrationPolicyEffect, type IntegrationPolicyEngine, type IntegrationPolicyRule, type IntegrationProvider, type IntegrationProviderKind, type IntegrationToolDefinition, type IntegrationToolSearchFilters, type IntegrationToolSearchResult, type IntegrationTriggerEvent, type IntegrationTriggerSubscription, type InvokeWithCapabilityRequest, type IssueCapabilityRequest, type IssuedIntegrationCapability, type McpCatalog, type McpCatalogTool, type McpToolDefinition, type MicrosoftCalendarOptions, type NormalizedIntegrationResult, type NotionDatabaseOptions, type OAuthFlowStore, type OAuthTokens, type OpenApiDocument, type OpenApiOperation, type ParsedStripeSignatureHeader, type PendingOAuthFlow, type RateLimitSpec, type RefreshInput, type ResolvedDataSource, ResourceContention, type SecretRef, type SlackOptions, type SlackVerifyOptions, type StartAuthRequest, type StartAuthResult, type StartOAuthInput, type StartOAuthOutput, StaticIntegrationPolicyEngine, type StaticIntegrationPolicyOptions, type StripeVerifyOptions, type TwilioVerifyOptions, _resetPendingFlowsForTests, assertValidConnectorManifest, buildApprovalRequest, buildIntegrationCoverageConnectors, buildIntegrationInvocationEnvelope, buildIntegrationToolCatalog, consumePendingFlow, createConnectorAdapterProvider, createDefaultIntegrationPolicyEngine, createHttpIntegrationProvider, createMockIntegrationProvider, exchangeAuthorizationCode, firstHeader, googleCalendar, googleSheets, hubspot, importGraphqlConnector, importMcpConnector, importOpenApiConnector, integrationCoverageChecklistMarkdown, integrationToolName, invocationRequestFromEnvelope, listIntegrationCoverageSpecs, manifestToConnector, microsoftCalendar, normalizeIntegrationResult, notionDatabase, parseIntegrationToolName, parseStripeSignatureHeader, redactApprovalRequest, redactCapability, redactInvocationEnvelope, refreshAccessToken, sanitizeConnection, searchIntegrationTools, signCapability, slack, slackEventsConnector, startOAuthFlow, stripePackConnector, stripeWebhookReceiverConnector, toMcpTools, twilioSmsConnector, validateConnectorManifest, validateIntegrationInvocationEnvelope, verifyCapabilityToken, verifyHmacSignature, verifySlackSignature, verifyStripeSignature, verifyTwilioSignature, webhookConnector };
1504
+ export { type AuthSpec, type CASStrategy, type Capability, type CapabilityClass, type CapabilityMutation, type CapabilityMutationResult, type CapabilityParameterSchema, type CapabilityRead, type CapabilityReadResult, type CompleteAuthRequest, type ConnectorAdapter, type ConnectorAdapterProviderOptions, type ConnectorCredentials, type ConnectorInvocation, type ConnectorManifest, type ConnectorManifestValidationIssue, type ConnectorManifestValidationResult, type ConsistencyModel, CredentialsExpired, DEFAULT_SIGNATURE_TOLERANCE_SECONDS, type DataSourceMetadata, type EventHandlerResult, type ExchangeCodeInput, type GenericHmacVerifyOptions, type GoogleCalendarOptions, type GoogleSheetsOptions, type GraphqlOperationSpec, type HttpIntegrationProviderOptions, type HubSpotOptions, type ImportCatalogOptions, InMemoryConnectionStore, InMemoryOAuthFlowStore, type InboundEvent, type IntegrationActionGuard, type IntegrationActionPack, type IntegrationActionRequest, type IntegrationActionResult, type IntegrationActionRisk, type IntegrationActor, type IntegrationApprovalRequest, type IntegrationApprovalResolution, type IntegrationCapability, type IntegrationConnection, type IntegrationConnectionStore, type IntegrationConnector, type IntegrationConnectorAction, type IntegrationConnectorCategory, type IntegrationConnectorTrigger, type IntegrationCoveragePriority, type IntegrationCoverageSpec, type IntegrationDataClass, IntegrationError, type IntegrationGuardContext, IntegrationHub, type IntegrationHubOptions, type IntegrationInvocationEnvelope, type IntegrationInvocationEnvelopeValidationOptions, type IntegrationPolicyDecision, type IntegrationPolicyEffect, type IntegrationPolicyEngine, type IntegrationPolicyRule, type IntegrationProvider, type IntegrationProviderKind, type IntegrationToolDefinition, type IntegrationToolSearchFilters, type IntegrationToolSearchResult, type IntegrationTriggerEvent, type IntegrationTriggerSubscription, type InvokeWithCapabilityRequest, type IssueCapabilityRequest, type IssuedIntegrationCapability, type McpCatalog, type McpCatalogTool, type McpToolDefinition, type MicrosoftCalendarOptions, type NormalizedIntegrationResult, type NotionDatabaseOptions, type OAuthFlowStore, type OAuthTokens, type OpenApiDocument, type OpenApiOperation, type ParsedStripeSignatureHeader, type PendingOAuthFlow, type RateLimitSpec, type RefreshInput, type ResolvedDataSource, ResourceContention, type RestConnectorSpec, type RestCredentialPlacement, type RestOperationSpec, type RestRequestSpec, type SecretRef, type SlackOptions, type SlackVerifyOptions, type StartAuthRequest, type StartAuthResult, type StartOAuthInput, type StartOAuthOutput, StaticIntegrationPolicyEngine, type StaticIntegrationPolicyOptions, type StripeVerifyOptions, type TwilioVerifyOptions, _resetPendingFlowsForTests, airtableConnector, asanaConnector, assertValidConnectorManifest, buildApprovalRequest, buildIntegrationCoverageConnectors, buildIntegrationInvocationEnvelope, buildIntegrationToolCatalog, consumePendingFlow, createConnectorAdapterProvider, createDefaultIntegrationPolicyEngine, createHttpIntegrationProvider, createMockIntegrationProvider, declarativeRestConnector, exchangeAuthorizationCode, firstHeader, githubConnector, gitlabConnector, googleCalendar, googleSheets, hubspot, importGraphqlConnector, importMcpConnector, importOpenApiConnector, integrationCoverageChecklistMarkdown, integrationToolName, invocationRequestFromEnvelope, listIntegrationCoverageSpecs, manifestToConnector, microsoftCalendar, normalizeIntegrationResult, notionDatabase, parseIntegrationToolName, parseStripeSignatureHeader, redactApprovalRequest, redactCapability, redactInvocationEnvelope, refreshAccessToken, salesforceConnector, sanitizeConnection, searchIntegrationTools, signCapability, slack, slackEventsConnector, startOAuthFlow, stripePackConnector, stripeWebhookReceiverConnector, toMcpTools, twilioSmsConnector, validateConnectorManifest, validateIntegrationInvocationEnvelope, verifyCapabilityToken, verifyHmacSignature, verifySlackSignature, verifyStripeSignature, verifyTwilioSignature, webhookConnector };