@notionhq/apps 0.0.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/LICENSE.md +21 -0
- package/README.md +30 -0
- package/dist/cli/build.d.ts +13 -0
- package/dist/cli/build.d.ts.map +1 -0
- package/dist/cli/build.js +36 -0
- package/dist/cli/build.test.d.ts +2 -0
- package/dist/cli/build.test.d.ts.map +1 -0
- package/dist/cli/codegen.d.ts +10 -0
- package/dist/cli/codegen.d.ts.map +1 -0
- package/dist/cli/codegen.js +41 -0
- package/dist/cli/codegen.test.d.ts +2 -0
- package/dist/cli/codegen.test.d.ts.map +1 -0
- package/dist/cli/discover.d.ts +32 -0
- package/dist/cli/discover.d.ts.map +1 -0
- package/dist/cli/discover.js +37 -0
- package/dist/cli/discover.test.d.ts +2 -0
- package/dist/cli/discover.test.d.ts.map +1 -0
- package/dist/cli/emit-manifest.d.ts +10 -0
- package/dist/cli/emit-manifest.d.ts.map +1 -0
- package/dist/cli/emit-manifest.js +131 -0
- package/dist/cli/emit-manifest.test.d.ts +2 -0
- package/dist/cli/emit-manifest.test.d.ts.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +36 -0
- package/dist/context.d.ts +7 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +30 -0
- package/dist/error.d.ts +8 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +11 -0
- package/dist/manifest.d.ts +25 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +0 -0
- package/dist/output.d.ts +7 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +8 -0
- package/dist/runtime-metadata.d.ts +9 -0
- package/dist/runtime-metadata.d.ts.map +1 -0
- package/dist/runtime-metadata.js +33 -0
- package/dist/runtime-metadata.test.d.ts +2 -0
- package/dist/runtime-metadata.test.d.ts.map +1 -0
- package/dist/triggers.d.ts +365 -0
- package/dist/triggers.d.ts.map +1 -0
- package/dist/triggers.generated.d.ts +246 -0
- package/dist/triggers.generated.d.ts.map +1 -0
- package/dist/triggers.generated.js +239 -0
- package/dist/triggers.js +0 -0
- package/dist/workflow.d.ts +125 -0
- package/dist/workflow.d.ts.map +1 -0
- package/dist/workflow.js +210 -0
- package/dist/workflow.test.d.ts +2 -0
- package/dist/workflow.test.d.ts.map +1 -0
- package/docs/BUILD.md +66 -0
- package/package.json +74 -0
- package/src/cli/build.test.ts +73 -0
- package/src/cli/build.ts +57 -0
- package/src/cli/codegen.test.ts +21 -0
- package/src/cli/codegen.ts +51 -0
- package/src/cli/discover.test.ts +26 -0
- package/src/cli/discover.ts +73 -0
- package/src/cli/emit-manifest.test.ts +45 -0
- package/src/cli/emit-manifest.ts +190 -0
- package/src/cli/index.ts +41 -0
- package/src/context.ts +49 -0
- package/src/error.ts +12 -0
- package/src/manifest.ts +26 -0
- package/src/output.ts +8 -0
- package/src/runtime-metadata.test.ts +54 -0
- package/src/runtime-metadata.ts +46 -0
- package/src/triggers.generated.ts +489 -0
- package/src/triggers.ts +500 -0
- package/src/workflow.test.ts +788 -0
- package/src/workflow.ts +418 -0
package/src/context.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Client } from "@notionhq/client";
|
|
2
|
+
import type { ClientOptions } from "@notionhq/client/build/src/Client.js";
|
|
3
|
+
|
|
4
|
+
export type CapabilityContext = {
|
|
5
|
+
/** Notion API SDK client for this execution. */
|
|
6
|
+
notion: Client;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const FIX_STEPS =
|
|
10
|
+
"\n\nTo fix this:\n" +
|
|
11
|
+
"1. Create a personal access token at https://app.notion.com/developers/tokens\n" +
|
|
12
|
+
"2. Add NOTION_API_TOKEN=<your-token> to your .env file\n" +
|
|
13
|
+
"3. For deployed apps, run: ntn apps env push";
|
|
14
|
+
|
|
15
|
+
function missingTokenMessage(): string {
|
|
16
|
+
return (
|
|
17
|
+
"NOTION_API_TOKEN is not set. " +
|
|
18
|
+
"context.notion requires an API token to make requests in workflow capabilities to Notion." +
|
|
19
|
+
FIX_STEPS
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function createUnauthenticatedNotionProxy(): Client {
|
|
24
|
+
return new Proxy({} as Client, {
|
|
25
|
+
get(_target, prop) {
|
|
26
|
+
if (prop === "then" || typeof prop === "symbol") {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
throw new Error(missingTokenMessage());
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function createCapabilityContext(): CapabilityContext {
|
|
35
|
+
const options: ClientOptions = {};
|
|
36
|
+
|
|
37
|
+
if (process.env.NOTION_API_BASE_URL) {
|
|
38
|
+
options.baseUrl = process.env.NOTION_API_BASE_URL;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!process.env.NOTION_API_TOKEN) {
|
|
42
|
+
return { notion: createUnauthenticatedNotionProxy() };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
options.auth = process.env.NOTION_API_TOKEN;
|
|
46
|
+
const notion = new Client(options);
|
|
47
|
+
|
|
48
|
+
return { notion };
|
|
49
|
+
}
|
package/src/error.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An error that occurred during the execution of an app capability.
|
|
3
|
+
*/
|
|
4
|
+
export class ExecutionError extends Error {
|
|
5
|
+
override readonly cause: unknown;
|
|
6
|
+
|
|
7
|
+
constructor(cause: unknown) {
|
|
8
|
+
super(`Error during app execution: ${cause}`);
|
|
9
|
+
this.name = "ExecutionError";
|
|
10
|
+
this.cause = cause;
|
|
11
|
+
}
|
|
12
|
+
}
|
package/src/manifest.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** The only capability type supported by this SDK. */
|
|
2
|
+
export type CapabilityType = "workflow";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* One capability in the manifest: its type, its key (derived from its
|
|
6
|
+
* filename), and its handler-free configuration.
|
|
7
|
+
*/
|
|
8
|
+
export type CapabilityManifestEntry = {
|
|
9
|
+
type: CapabilityType;
|
|
10
|
+
key: string;
|
|
11
|
+
config: unknown;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The full app manifest, emitted by `notion-apps build` as
|
|
16
|
+
* `dist/manifest.json` and read by the platform at deploy time. This is a
|
|
17
|
+
* complete, static description of the app.
|
|
18
|
+
*/
|
|
19
|
+
export type AppManifest = {
|
|
20
|
+
sdkVersion: string;
|
|
21
|
+
/** Reserved platform fields; workflow-only apps always emit empty arrays. */
|
|
22
|
+
databases: never[];
|
|
23
|
+
xldbs: never[];
|
|
24
|
+
pacers: never[];
|
|
25
|
+
capabilities: CapabilityManifestEntry[];
|
|
26
|
+
};
|
package/src/output.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Writes a notion_output envelope to stdout using the shared wire format.
|
|
3
|
+
* The platform runner scans a run's log stream for this envelope to
|
|
4
|
+
* recover the capability's result.
|
|
5
|
+
*/
|
|
6
|
+
export function writeOutput(value: unknown): void {
|
|
7
|
+
process.stdout.write(`\n<__notion_output__>${JSON.stringify(value)}</__notion_output__>\n`);
|
|
8
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
|
|
5
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
6
|
+
|
|
7
|
+
import { readRunMetadata } from "./runtime-metadata.js";
|
|
8
|
+
|
|
9
|
+
const temporaryDirectories: string[] = [];
|
|
10
|
+
|
|
11
|
+
function temporaryPath(name: string): string {
|
|
12
|
+
const directory = fs.mkdtempSync(path.join(os.tmpdir(), "notion-apps-metadata-"));
|
|
13
|
+
temporaryDirectories.push(directory);
|
|
14
|
+
return path.join(directory, name);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
vi.unstubAllEnvs();
|
|
19
|
+
for (const directory of temporaryDirectories.splice(0)) {
|
|
20
|
+
fs.rmSync(directory, { recursive: true, force: true });
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe("readRunMetadata", () => {
|
|
25
|
+
it("throws when the metadata path is not configured", () => {
|
|
26
|
+
vi.stubEnv("NOTION_RUN_METADATA_PATH", undefined);
|
|
27
|
+
|
|
28
|
+
expect(() => readRunMetadata()).toThrow("Workflow run metadata path is not configured");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("reads workflow run metadata", () => {
|
|
32
|
+
const metadataPath = temporaryPath("metadata.json");
|
|
33
|
+
const metadata = {
|
|
34
|
+
workspaceId: "workspace-id",
|
|
35
|
+
workerId: "worker-id",
|
|
36
|
+
runGroupId: "run-group-id",
|
|
37
|
+
runId: "run-id",
|
|
38
|
+
capabilityType: "workflow" as const,
|
|
39
|
+
attemptNumber: 2,
|
|
40
|
+
};
|
|
41
|
+
fs.writeFileSync(metadataPath, JSON.stringify(metadata));
|
|
42
|
+
vi.stubEnv("NOTION_RUN_METADATA_PATH", metadataPath);
|
|
43
|
+
|
|
44
|
+
expect(readRunMetadata()).toEqual(metadata);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("rejects invalid workflow run metadata", () => {
|
|
48
|
+
const metadataPath = temporaryPath("metadata.json");
|
|
49
|
+
fs.writeFileSync(metadataPath, JSON.stringify({ runId: "run-id" }));
|
|
50
|
+
vi.stubEnv("NOTION_RUN_METADATA_PATH", metadataPath);
|
|
51
|
+
|
|
52
|
+
expect(() => readRunMetadata()).toThrow("Invalid workflow run metadata");
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
|
|
3
|
+
import { Ajv, type JSONSchemaType } from "ajv";
|
|
4
|
+
|
|
5
|
+
export type RunMetadata = {
|
|
6
|
+
workspaceId: string;
|
|
7
|
+
workerId: string;
|
|
8
|
+
runGroupId: string;
|
|
9
|
+
runId: string;
|
|
10
|
+
capabilityType: "workflow";
|
|
11
|
+
attemptNumber: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const runMetadataSchema: JSONSchemaType<RunMetadata> = {
|
|
15
|
+
type: "object",
|
|
16
|
+
properties: {
|
|
17
|
+
workspaceId: { type: "string" },
|
|
18
|
+
workerId: { type: "string" },
|
|
19
|
+
runGroupId: { type: "string" },
|
|
20
|
+
runId: { type: "string" },
|
|
21
|
+
capabilityType: { type: "string", const: "workflow" },
|
|
22
|
+
attemptNumber: { type: "number" },
|
|
23
|
+
},
|
|
24
|
+
required: ["workspaceId", "workerId", "runGroupId", "runId", "capabilityType", "attemptNumber"],
|
|
25
|
+
additionalProperties: false,
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const ajv = new Ajv();
|
|
29
|
+
const validateRunMetadata = ajv.compile(runMetadataSchema);
|
|
30
|
+
|
|
31
|
+
/** @internal */
|
|
32
|
+
export function readRunMetadata(): RunMetadata {
|
|
33
|
+
const runMetadataPath = process.env.NOTION_RUN_METADATA_PATH;
|
|
34
|
+
if (runMetadataPath === undefined) {
|
|
35
|
+
throw new Error("Workflow run metadata path is not configured");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const parsed: unknown = JSON.parse(readFileSync(runMetadataPath, "utf8"));
|
|
39
|
+
if (!validateRunMetadata(parsed)) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`Invalid workflow run metadata: ${ajv.errorsText(validateRunMetadata.errors)}`,
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return parsed;
|
|
46
|
+
}
|
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
// Generated by scripts/generate-triggers.ts — do not edit by hand.
|
|
2
|
+
// Regenerate with: pnpm run generate
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
CalendarEventCanceledEvent,
|
|
6
|
+
CalendarEventCreatedEvent,
|
|
7
|
+
CalendarEventUpdatedEvent,
|
|
8
|
+
DiscordInteractionEvent,
|
|
9
|
+
GoogleDriveOauthFilesChangedEvent,
|
|
10
|
+
MailEmailReceivedEvent,
|
|
11
|
+
MailEmailSentEvent,
|
|
12
|
+
MailLabelAppliedEvent,
|
|
13
|
+
NotionAgentMentionedEvent,
|
|
14
|
+
NotionButtonPressedEvent,
|
|
15
|
+
NotionCommentAddedEvent,
|
|
16
|
+
NotionDatabaseAgentUpdatedEvent,
|
|
17
|
+
NotionMeetingNoteSummaryCompletedEvent,
|
|
18
|
+
NotionPageCreatedEvent,
|
|
19
|
+
NotionPageDeletedEvent,
|
|
20
|
+
NotionPageUpdatedEvent,
|
|
21
|
+
RecurrenceEvent,
|
|
22
|
+
SlackAppMentionEvent,
|
|
23
|
+
SlackMessageEvent,
|
|
24
|
+
SlackReactionAddedEvent,
|
|
25
|
+
WebhookEvent,
|
|
26
|
+
} from "./triggers.js";
|
|
27
|
+
|
|
28
|
+
export type {
|
|
29
|
+
Actor,
|
|
30
|
+
ActorLike,
|
|
31
|
+
CalendarEventCanceledEvent,
|
|
32
|
+
CalendarEventCreatedEvent,
|
|
33
|
+
CalendarEventLike,
|
|
34
|
+
CalendarEventUpdatedEvent,
|
|
35
|
+
ChatMessageLike,
|
|
36
|
+
ChatThreadMessage,
|
|
37
|
+
DiscordChatThreadMessage,
|
|
38
|
+
DiscordInteractionEvent,
|
|
39
|
+
EmailMessageLike,
|
|
40
|
+
EmailThreadLike,
|
|
41
|
+
EmailTriggerMessage,
|
|
42
|
+
GoogleDriveOauthFilesChangedEvent,
|
|
43
|
+
LinkLike,
|
|
44
|
+
MailEmailReceivedEvent,
|
|
45
|
+
MailEmailSentEvent,
|
|
46
|
+
MailLabelAppliedEvent,
|
|
47
|
+
MessageLike,
|
|
48
|
+
NotionAgentMentionedEvent,
|
|
49
|
+
NotionButtonPressedEvent,
|
|
50
|
+
NotionCommentAddedEvent,
|
|
51
|
+
NotionDatabaseAgentUpdatedEvent,
|
|
52
|
+
NotionMeetingNoteSummaryCompletedEvent,
|
|
53
|
+
NotionPageCreatedEvent,
|
|
54
|
+
NotionPageDeletedEvent,
|
|
55
|
+
NotionPageEdit,
|
|
56
|
+
NotionPageUpdatedEvent,
|
|
57
|
+
RecurrenceEvent,
|
|
58
|
+
RecurrenceFrequency,
|
|
59
|
+
SlackAppMentionEvent,
|
|
60
|
+
SlackChatThreadMessage,
|
|
61
|
+
SlackMessageEvent,
|
|
62
|
+
SlackReactionAddedEvent,
|
|
63
|
+
ThreadLike,
|
|
64
|
+
ThreadMessage,
|
|
65
|
+
TimestampLike,
|
|
66
|
+
TriggerEvent,
|
|
67
|
+
TriggerEventBase,
|
|
68
|
+
TriggerEventMap,
|
|
69
|
+
TriggerType,
|
|
70
|
+
VendorActor,
|
|
71
|
+
VendorExtensions,
|
|
72
|
+
WebhookEvent,
|
|
73
|
+
} from "./triggers.js";
|
|
74
|
+
|
|
75
|
+
/** A message was posted in a subscribed Slack channel. */
|
|
76
|
+
export type SlackMessageTrigger = {
|
|
77
|
+
type: "slack.message";
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/** A reaction was added to a Slack message. */
|
|
81
|
+
export type SlackReactionAddedTrigger = {
|
|
82
|
+
type: "slack.reaction.added";
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/** The Notion app was mentioned in a Slack message. */
|
|
86
|
+
export type SlackAppMentionTrigger = {
|
|
87
|
+
type: "slack.app.mention";
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/** A Discord interaction was received. */
|
|
91
|
+
export type DiscordInteractionTrigger = {
|
|
92
|
+
type: "discord.interaction";
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/** An email was received. */
|
|
96
|
+
export type MailEmailReceivedTrigger = {
|
|
97
|
+
type: "mail.email.received";
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/** An email was sent. */
|
|
101
|
+
export type MailEmailSentTrigger = {
|
|
102
|
+
type: "mail.email.sent";
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/** A label was applied to an email. */
|
|
106
|
+
export type MailLabelAppliedTrigger = {
|
|
107
|
+
type: "mail.label.applied";
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/** A calendar event was created. */
|
|
111
|
+
export type CalendarEventCreatedTrigger = {
|
|
112
|
+
type: "calendar.event.created";
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/** A calendar event was updated. */
|
|
116
|
+
export type CalendarEventUpdatedTrigger = {
|
|
117
|
+
type: "calendar.event.updated";
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/** A calendar event was canceled. */
|
|
121
|
+
export type CalendarEventCanceledTrigger = {
|
|
122
|
+
type: "calendar.event.canceled";
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/** A page has been added to a database. */
|
|
126
|
+
export type NotionPageCreatedTrigger = {
|
|
127
|
+
type: "notion.page.created";
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/** A page was updated. */
|
|
131
|
+
export type NotionPageUpdatedTrigger = {
|
|
132
|
+
type: "notion.page.updated";
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/** A page was deleted. */
|
|
136
|
+
export type NotionPageDeletedTrigger = {
|
|
137
|
+
type: "notion.page.deleted";
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/** A meeting note's AI summary finished generating. */
|
|
141
|
+
export type NotionMeetingNoteSummaryCompletedTrigger = {
|
|
142
|
+
type: "notion.meetingNote.summary.completed";
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/** A comment was added to a page discussion. */
|
|
146
|
+
export type NotionCommentAddedTrigger = {
|
|
147
|
+
type: "notion.page.discussion.comment.added";
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
/** An agent was mentioned in page content or a person property. */
|
|
151
|
+
export type NotionAgentMentionedTrigger = {
|
|
152
|
+
type: "notion.agent.mentioned";
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
/** A button block was pressed. */
|
|
156
|
+
export type NotionButtonPressedTrigger = {
|
|
157
|
+
type: "notion.button.pressed";
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/** A database agent's configuration was updated. */
|
|
161
|
+
export type NotionDatabaseAgentUpdatedTrigger = {
|
|
162
|
+
type: "notion.database.agent.updated";
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
/** An incoming webhook request was received. */
|
|
166
|
+
export type WebhookTrigger = {
|
|
167
|
+
type: "webhooks.webhook";
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
/** Files changed in a watched Google Drive folder or drive. */
|
|
171
|
+
export type GoogleDriveOauthFilesChangedTrigger = {
|
|
172
|
+
type: "googleDriveOauth.filesChanged";
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
/** A recurring schedule fired. */
|
|
176
|
+
export type RecurrenceTrigger = {
|
|
177
|
+
type: "recurrence";
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
/** Creators for each event that can trigger a workflow. */
|
|
181
|
+
export const triggers = {
|
|
182
|
+
/**
|
|
183
|
+
* Declare that a workflow can run on `slack.message` events.
|
|
184
|
+
*
|
|
185
|
+
* A message was posted in a subscribed Slack channel.
|
|
186
|
+
*/
|
|
187
|
+
slackMessage(): SlackMessageTrigger {
|
|
188
|
+
return {
|
|
189
|
+
type: "slack.message",
|
|
190
|
+
};
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Declare that a workflow can run on `slack.reaction.added` events.
|
|
195
|
+
*
|
|
196
|
+
* A reaction was added to a Slack message.
|
|
197
|
+
*/
|
|
198
|
+
slackReactionAdded(): SlackReactionAddedTrigger {
|
|
199
|
+
return {
|
|
200
|
+
type: "slack.reaction.added",
|
|
201
|
+
};
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Declare that a workflow can run on `slack.app.mention` events.
|
|
206
|
+
*
|
|
207
|
+
* The Notion app was mentioned in a Slack message.
|
|
208
|
+
*/
|
|
209
|
+
slackAppMention(): SlackAppMentionTrigger {
|
|
210
|
+
return {
|
|
211
|
+
type: "slack.app.mention",
|
|
212
|
+
};
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Declare that a workflow can run on `discord.interaction` events.
|
|
217
|
+
*
|
|
218
|
+
* A Discord interaction was received.
|
|
219
|
+
*/
|
|
220
|
+
discordInteraction(): DiscordInteractionTrigger {
|
|
221
|
+
return {
|
|
222
|
+
type: "discord.interaction",
|
|
223
|
+
};
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Declare that a workflow can run on `mail.email.received` events.
|
|
228
|
+
*
|
|
229
|
+
* An email was received.
|
|
230
|
+
*/
|
|
231
|
+
mailEmailReceived(): MailEmailReceivedTrigger {
|
|
232
|
+
return {
|
|
233
|
+
type: "mail.email.received",
|
|
234
|
+
};
|
|
235
|
+
},
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Declare that a workflow can run on `mail.email.sent` events.
|
|
239
|
+
*
|
|
240
|
+
* An email was sent.
|
|
241
|
+
*/
|
|
242
|
+
mailEmailSent(): MailEmailSentTrigger {
|
|
243
|
+
return {
|
|
244
|
+
type: "mail.email.sent",
|
|
245
|
+
};
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Declare that a workflow can run on `mail.label.applied` events.
|
|
250
|
+
*
|
|
251
|
+
* A label was applied to an email.
|
|
252
|
+
*/
|
|
253
|
+
mailLabelApplied(): MailLabelAppliedTrigger {
|
|
254
|
+
return {
|
|
255
|
+
type: "mail.label.applied",
|
|
256
|
+
};
|
|
257
|
+
},
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Declare that a workflow can run on `calendar.event.created` events.
|
|
261
|
+
*
|
|
262
|
+
* A calendar event was created.
|
|
263
|
+
*/
|
|
264
|
+
calendarEventCreated(): CalendarEventCreatedTrigger {
|
|
265
|
+
return {
|
|
266
|
+
type: "calendar.event.created",
|
|
267
|
+
};
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Declare that a workflow can run on `calendar.event.updated` events.
|
|
272
|
+
*
|
|
273
|
+
* A calendar event was updated.
|
|
274
|
+
*/
|
|
275
|
+
calendarEventUpdated(): CalendarEventUpdatedTrigger {
|
|
276
|
+
return {
|
|
277
|
+
type: "calendar.event.updated",
|
|
278
|
+
};
|
|
279
|
+
},
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Declare that a workflow can run on `calendar.event.canceled` events.
|
|
283
|
+
*
|
|
284
|
+
* A calendar event was canceled.
|
|
285
|
+
*/
|
|
286
|
+
calendarEventCanceled(): CalendarEventCanceledTrigger {
|
|
287
|
+
return {
|
|
288
|
+
type: "calendar.event.canceled",
|
|
289
|
+
};
|
|
290
|
+
},
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Declare that a workflow can run on `notion.page.created` events.
|
|
294
|
+
*
|
|
295
|
+
* A page has been added to a database.
|
|
296
|
+
*/
|
|
297
|
+
notionPageCreated(): NotionPageCreatedTrigger {
|
|
298
|
+
return {
|
|
299
|
+
type: "notion.page.created",
|
|
300
|
+
};
|
|
301
|
+
},
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Declare that a workflow can run on `notion.page.updated` events.
|
|
305
|
+
*
|
|
306
|
+
* A page was updated.
|
|
307
|
+
*/
|
|
308
|
+
notionPageUpdated(): NotionPageUpdatedTrigger {
|
|
309
|
+
return {
|
|
310
|
+
type: "notion.page.updated",
|
|
311
|
+
};
|
|
312
|
+
},
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Declare that a workflow can run on `notion.page.deleted` events.
|
|
316
|
+
*
|
|
317
|
+
* A page was deleted.
|
|
318
|
+
*/
|
|
319
|
+
notionPageDeleted(): NotionPageDeletedTrigger {
|
|
320
|
+
return {
|
|
321
|
+
type: "notion.page.deleted",
|
|
322
|
+
};
|
|
323
|
+
},
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Declare that a workflow can run on `notion.meetingNote.summary.completed` events.
|
|
327
|
+
*
|
|
328
|
+
* A meeting note's AI summary finished generating.
|
|
329
|
+
*/
|
|
330
|
+
notionMeetingNoteSummaryCompleted(): NotionMeetingNoteSummaryCompletedTrigger {
|
|
331
|
+
return {
|
|
332
|
+
type: "notion.meetingNote.summary.completed",
|
|
333
|
+
};
|
|
334
|
+
},
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Declare that a workflow can run on `notion.page.discussion.comment.added` events.
|
|
338
|
+
*
|
|
339
|
+
* A comment was added to a page discussion.
|
|
340
|
+
*/
|
|
341
|
+
notionCommentAdded(): NotionCommentAddedTrigger {
|
|
342
|
+
return {
|
|
343
|
+
type: "notion.page.discussion.comment.added",
|
|
344
|
+
};
|
|
345
|
+
},
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Declare that a workflow can run on `notion.agent.mentioned` events.
|
|
349
|
+
*
|
|
350
|
+
* An agent was mentioned in page content or a person property.
|
|
351
|
+
*/
|
|
352
|
+
notionAgentMentioned(): NotionAgentMentionedTrigger {
|
|
353
|
+
return {
|
|
354
|
+
type: "notion.agent.mentioned",
|
|
355
|
+
};
|
|
356
|
+
},
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Declare that a workflow can run on `notion.button.pressed` events.
|
|
360
|
+
*
|
|
361
|
+
* A button block was pressed.
|
|
362
|
+
*/
|
|
363
|
+
notionButtonPressed(): NotionButtonPressedTrigger {
|
|
364
|
+
return {
|
|
365
|
+
type: "notion.button.pressed",
|
|
366
|
+
};
|
|
367
|
+
},
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Declare that a workflow can run on `notion.database.agent.updated` events.
|
|
371
|
+
*
|
|
372
|
+
* A database agent's configuration was updated.
|
|
373
|
+
*/
|
|
374
|
+
notionDatabaseAgentUpdated(): NotionDatabaseAgentUpdatedTrigger {
|
|
375
|
+
return {
|
|
376
|
+
type: "notion.database.agent.updated",
|
|
377
|
+
};
|
|
378
|
+
},
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Declare that a workflow can run on `webhooks.webhook` events.
|
|
382
|
+
*
|
|
383
|
+
* An incoming webhook request was received.
|
|
384
|
+
*/
|
|
385
|
+
webhook(): WebhookTrigger {
|
|
386
|
+
return {
|
|
387
|
+
type: "webhooks.webhook",
|
|
388
|
+
};
|
|
389
|
+
},
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Declare that a workflow can run on `googleDriveOauth.filesChanged` events.
|
|
393
|
+
*
|
|
394
|
+
* Files changed in a watched Google Drive folder or drive.
|
|
395
|
+
*/
|
|
396
|
+
googleDriveOauthFilesChanged(): GoogleDriveOauthFilesChangedTrigger {
|
|
397
|
+
return {
|
|
398
|
+
type: "googleDriveOauth.filesChanged",
|
|
399
|
+
};
|
|
400
|
+
},
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Declare that a workflow can run on `recurrence` events.
|
|
404
|
+
*
|
|
405
|
+
* A recurring schedule fired.
|
|
406
|
+
*/
|
|
407
|
+
recurrence(): RecurrenceTrigger {
|
|
408
|
+
return {
|
|
409
|
+
type: "recurrence",
|
|
410
|
+
};
|
|
411
|
+
},
|
|
412
|
+
} as const;
|
|
413
|
+
|
|
414
|
+
/** Event that can trigger a workflow. */
|
|
415
|
+
export type WorkflowTrigger =
|
|
416
|
+
| SlackMessageTrigger
|
|
417
|
+
| SlackReactionAddedTrigger
|
|
418
|
+
| SlackAppMentionTrigger
|
|
419
|
+
| DiscordInteractionTrigger
|
|
420
|
+
| MailEmailReceivedTrigger
|
|
421
|
+
| MailEmailSentTrigger
|
|
422
|
+
| MailLabelAppliedTrigger
|
|
423
|
+
| CalendarEventCreatedTrigger
|
|
424
|
+
| CalendarEventUpdatedTrigger
|
|
425
|
+
| CalendarEventCanceledTrigger
|
|
426
|
+
| NotionPageCreatedTrigger
|
|
427
|
+
| NotionPageUpdatedTrigger
|
|
428
|
+
| NotionPageDeletedTrigger
|
|
429
|
+
| NotionMeetingNoteSummaryCompletedTrigger
|
|
430
|
+
| NotionCommentAddedTrigger
|
|
431
|
+
| NotionAgentMentionedTrigger
|
|
432
|
+
| NotionButtonPressedTrigger
|
|
433
|
+
| NotionDatabaseAgentUpdatedTrigger
|
|
434
|
+
| WebhookTrigger
|
|
435
|
+
| GoogleDriveOauthFilesChangedTrigger
|
|
436
|
+
| RecurrenceTrigger;
|
|
437
|
+
|
|
438
|
+
/** All workflow trigger type strings. */
|
|
439
|
+
export const WORKFLOW_TRIGGER_TYPES = [
|
|
440
|
+
"slack.message",
|
|
441
|
+
"slack.reaction.added",
|
|
442
|
+
"slack.app.mention",
|
|
443
|
+
"discord.interaction",
|
|
444
|
+
"mail.email.received",
|
|
445
|
+
"mail.email.sent",
|
|
446
|
+
"mail.label.applied",
|
|
447
|
+
"calendar.event.created",
|
|
448
|
+
"calendar.event.updated",
|
|
449
|
+
"calendar.event.canceled",
|
|
450
|
+
"notion.page.created",
|
|
451
|
+
"notion.page.updated",
|
|
452
|
+
"notion.page.deleted",
|
|
453
|
+
"notion.meetingNote.summary.completed",
|
|
454
|
+
"notion.page.discussion.comment.added",
|
|
455
|
+
"notion.agent.mentioned",
|
|
456
|
+
"notion.button.pressed",
|
|
457
|
+
"notion.database.agent.updated",
|
|
458
|
+
"webhooks.webhook",
|
|
459
|
+
"googleDriveOauth.filesChanged",
|
|
460
|
+
"recurrence",
|
|
461
|
+
] as const;
|
|
462
|
+
|
|
463
|
+
/** A workflow trigger type string. */
|
|
464
|
+
export type WorkflowTriggerType = (typeof WORKFLOW_TRIGGER_TYPES)[number];
|
|
465
|
+
|
|
466
|
+
/** Maps each supported workflow trigger to the event its handler receives. */
|
|
467
|
+
export type WorkflowEventMap = {
|
|
468
|
+
"slack.message": SlackMessageEvent;
|
|
469
|
+
"slack.reaction.added": SlackReactionAddedEvent;
|
|
470
|
+
"slack.app.mention": SlackAppMentionEvent;
|
|
471
|
+
"discord.interaction": DiscordInteractionEvent;
|
|
472
|
+
"mail.email.received": MailEmailReceivedEvent;
|
|
473
|
+
"mail.email.sent": MailEmailSentEvent;
|
|
474
|
+
"mail.label.applied": MailLabelAppliedEvent;
|
|
475
|
+
"calendar.event.created": CalendarEventCreatedEvent;
|
|
476
|
+
"calendar.event.updated": CalendarEventUpdatedEvent;
|
|
477
|
+
"calendar.event.canceled": CalendarEventCanceledEvent;
|
|
478
|
+
"notion.page.created": NotionPageCreatedEvent;
|
|
479
|
+
"notion.page.updated": NotionPageUpdatedEvent;
|
|
480
|
+
"notion.page.deleted": NotionPageDeletedEvent;
|
|
481
|
+
"notion.meetingNote.summary.completed": NotionMeetingNoteSummaryCompletedEvent;
|
|
482
|
+
"notion.page.discussion.comment.added": NotionCommentAddedEvent;
|
|
483
|
+
"notion.agent.mentioned": NotionAgentMentionedEvent;
|
|
484
|
+
"notion.button.pressed": NotionButtonPressedEvent;
|
|
485
|
+
"notion.database.agent.updated": NotionDatabaseAgentUpdatedEvent;
|
|
486
|
+
"webhooks.webhook": WebhookEvent;
|
|
487
|
+
"googleDriveOauth.filesChanged": GoogleDriveOauthFilesChangedEvent;
|
|
488
|
+
recurrence: RecurrenceEvent;
|
|
489
|
+
};
|