@action-llama/action-llama 0.18.4 → 0.18.6
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/agents/container-runner.d.ts +2 -2
- package/dist/agents/container-runner.d.ts.map +1 -1
- package/dist/agents/container-runner.js.map +1 -1
- package/dist/agents/credential-setup.d.ts.map +1 -1
- package/dist/agents/credential-setup.js +8 -3
- package/dist/agents/credential-setup.js.map +1 -1
- package/dist/build-info.json +1 -1
- package/dist/chat/container-launcher.d.ts +2 -2
- package/dist/chat/container-launcher.d.ts.map +1 -1
- package/dist/chat/container-launcher.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +116 -7
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/run-agent.d.ts +14 -0
- package/dist/cli/commands/run-agent.d.ts.map +1 -0
- package/dist/cli/commands/run-agent.js +344 -0
- package/dist/cli/commands/run-agent.js.map +1 -0
- package/dist/cli/main.js +10 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cloud/provider.d.ts +5 -5
- package/dist/cloud/provider.d.ts.map +1 -1
- package/dist/cloud/vps/provider.d.ts +3 -3
- package/dist/cloud/vps/provider.d.ts.map +1 -1
- package/dist/control/routes/stats.d.ts.map +1 -1
- package/dist/control/routes/stats.js +13 -0
- package/dist/control/routes/stats.js.map +1 -1
- package/dist/credentials/builtins/discord-bot.d.ts +4 -0
- package/dist/credentials/builtins/discord-bot.d.ts.map +1 -0
- package/dist/credentials/builtins/discord-bot.js +34 -0
- package/dist/credentials/builtins/discord-bot.js.map +1 -0
- package/dist/credentials/builtins/index.d.ts.map +1 -1
- package/dist/credentials/builtins/index.js +10 -0
- package/dist/credentials/builtins/index.js.map +1 -1
- package/dist/credentials/builtins/slack-bot-token.d.ts +4 -0
- package/dist/credentials/builtins/slack-bot-token.d.ts.map +1 -0
- package/dist/credentials/builtins/slack-bot-token.js +28 -0
- package/dist/credentials/builtins/slack-bot-token.js.map +1 -0
- package/dist/credentials/builtins/slack-signing-secret.d.ts +4 -0
- package/dist/credentials/builtins/slack-signing-secret.d.ts.map +1 -0
- package/dist/credentials/builtins/slack-signing-secret.js +19 -0
- package/dist/credentials/builtins/slack-signing-secret.js.map +1 -0
- package/dist/credentials/builtins/x-twitter-api.d.ts.map +1 -1
- package/dist/credentials/builtins/x-twitter-api.js +7 -11
- package/dist/credentials/builtins/x-twitter-api.js.map +1 -1
- package/dist/credentials/builtins/x-twitter-user-oauth1.d.ts +4 -0
- package/dist/credentials/builtins/x-twitter-user-oauth1.d.ts.map +1 -0
- package/dist/credentials/builtins/x-twitter-user-oauth1.js +17 -0
- package/dist/credentials/builtins/x-twitter-user-oauth1.js.map +1 -0
- package/dist/credentials/builtins/x-twitter-user-oauth2.d.ts +4 -0
- package/dist/credentials/builtins/x-twitter-user-oauth2.d.ts.map +1 -0
- package/dist/credentials/builtins/x-twitter-user-oauth2.js +195 -0
- package/dist/credentials/builtins/x-twitter-user-oauth2.js.map +1 -0
- package/dist/credentials/prompter.d.ts.map +1 -1
- package/dist/credentials/prompter.js +38 -9
- package/dist/credentials/prompter.js.map +1 -1
- package/dist/credentials/schema.d.ts +1 -0
- package/dist/credentials/schema.d.ts.map +1 -1
- package/dist/docker/host-user-runtime.d.ts +35 -0
- package/dist/docker/host-user-runtime.d.ts.map +1 -0
- package/dist/docker/host-user-runtime.js +292 -0
- package/dist/docker/host-user-runtime.js.map +1 -0
- package/dist/docker/local-runtime.d.ts +2 -2
- package/dist/docker/local-runtime.d.ts.map +1 -1
- package/dist/docker/runtime.d.ts +34 -24
- package/dist/docker/runtime.d.ts.map +1 -1
- package/dist/docker/runtime.js +4 -1
- package/dist/docker/runtime.js.map +1 -1
- package/dist/docker/ssh-docker-runtime.d.ts +2 -2
- package/dist/docker/ssh-docker-runtime.d.ts.map +1 -1
- package/dist/docker/ssh-docker-runtime.js.map +1 -1
- package/dist/events/routes/webhooks.d.ts.map +1 -1
- package/dist/events/routes/webhooks.js +57 -0
- package/dist/events/routes/webhooks.js.map +1 -1
- package/dist/events/webhook-setup.d.ts +11 -0
- package/dist/events/webhook-setup.d.ts.map +1 -1
- package/dist/events/webhook-setup.js +90 -9
- package/dist/events/webhook-setup.js.map +1 -1
- package/dist/execution/image-builder.d.ts +3 -3
- package/dist/execution/image-builder.d.ts.map +1 -1
- package/dist/execution/runner-setup.d.ts +3 -3
- package/dist/execution/runner-setup.d.ts.map +1 -1
- package/dist/execution/runtime-factory.d.ts +7 -6
- package/dist/execution/runtime-factory.d.ts.map +1 -1
- package/dist/execution/runtime-factory.js +18 -3
- package/dist/execution/runtime-factory.js.map +1 -1
- package/dist/extensions/loader.d.ts.map +1 -1
- package/dist/extensions/loader.js +2 -1
- package/dist/extensions/loader.js.map +1 -1
- package/dist/extensions/types.d.ts +2 -2
- package/dist/extensions/types.d.ts.map +1 -1
- package/dist/frontend/assets/index-D5QqK4BL.js +13 -0
- package/dist/frontend/assets/{index-B3IlFzCF.css → index-GJZXHhf1.css} +1 -1
- package/dist/frontend/index.html +2 -2
- package/dist/scheduler/gateway-setup.d.ts +2 -2
- package/dist/scheduler/gateway-setup.d.ts.map +1 -1
- package/dist/scheduler/gateway-setup.js.map +1 -1
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +11 -7
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/watcher.d.ts +3 -3
- package/dist/scheduler/watcher.d.ts.map +1 -1
- package/dist/scheduler/watcher.js +35 -26
- package/dist/scheduler/watcher.js.map +1 -1
- package/dist/setup/validators.d.ts +1 -5
- package/dist/setup/validators.d.ts.map +1 -1
- package/dist/setup/validators.js +4 -7
- package/dist/setup/validators.js.map +1 -1
- package/dist/shared/config.d.ts +11 -0
- package/dist/shared/config.d.ts.map +1 -1
- package/dist/shared/config.js +1 -0
- package/dist/shared/config.js.map +1 -1
- package/dist/shared/credential-refs.d.ts.map +1 -1
- package/dist/shared/credential-refs.js +15 -9
- package/dist/shared/credential-refs.js.map +1 -1
- package/dist/shared/oauth1.d.ts +17 -0
- package/dist/shared/oauth1.d.ts.map +1 -0
- package/dist/shared/oauth1.js +45 -0
- package/dist/shared/oauth1.js.map +1 -0
- package/dist/shared/validation.d.ts.map +1 -1
- package/dist/shared/validation.js +6 -1
- package/dist/shared/validation.js.map +1 -1
- package/dist/stats/store.d.ts +1 -0
- package/dist/stats/store.d.ts.map +1 -1
- package/dist/stats/store.js +8 -4
- package/dist/stats/store.js.map +1 -1
- package/dist/webhooks/definitions/discord.d.ts +3 -0
- package/dist/webhooks/definitions/discord.d.ts.map +1 -0
- package/dist/webhooks/definitions/discord.js +23 -0
- package/dist/webhooks/definitions/discord.js.map +1 -0
- package/dist/webhooks/definitions/registry.d.ts.map +1 -1
- package/dist/webhooks/definitions/registry.js +4 -1
- package/dist/webhooks/definitions/registry.js.map +1 -1
- package/dist/webhooks/definitions/slack.d.ts +3 -0
- package/dist/webhooks/definitions/slack.d.ts.map +1 -0
- package/dist/webhooks/definitions/slack.js +25 -0
- package/dist/webhooks/definitions/slack.js.map +1 -0
- package/dist/webhooks/definitions/twitter.d.ts +3 -0
- package/dist/webhooks/definitions/twitter.d.ts.map +1 -0
- package/dist/webhooks/definitions/twitter.js +30 -0
- package/dist/webhooks/definitions/twitter.js.map +1 -0
- package/dist/webhooks/providers/discord.d.ts +9 -0
- package/dist/webhooks/providers/discord.d.ts.map +1 -0
- package/dist/webhooks/providers/discord.js +112 -0
- package/dist/webhooks/providers/discord.js.map +1 -0
- package/dist/webhooks/providers/index.d.ts +12 -0
- package/dist/webhooks/providers/index.d.ts.map +1 -1
- package/dist/webhooks/providers/index.js +118 -0
- package/dist/webhooks/providers/index.js.map +1 -1
- package/dist/webhooks/providers/slack.d.ts +9 -0
- package/dist/webhooks/providers/slack.d.ts.map +1 -0
- package/dist/webhooks/providers/slack.js +120 -0
- package/dist/webhooks/providers/slack.js.map +1 -0
- package/dist/webhooks/providers/twitter-subscribe.d.ts +26 -0
- package/dist/webhooks/providers/twitter-subscribe.d.ts.map +1 -0
- package/dist/webhooks/providers/twitter-subscribe.js +158 -0
- package/dist/webhooks/providers/twitter-subscribe.js.map +1 -0
- package/dist/webhooks/providers/twitter.d.ts +13 -0
- package/dist/webhooks/providers/twitter.d.ts.map +1 -0
- package/dist/webhooks/providers/twitter.js +202 -0
- package/dist/webhooks/providers/twitter.js.map +1 -0
- package/dist/webhooks/types.d.ts +24 -1
- package/dist/webhooks/types.d.ts.map +1 -1
- package/dist/webhooks/validation.d.ts +11 -0
- package/dist/webhooks/validation.d.ts.map +1 -1
- package/dist/webhooks/validation.js +45 -1
- package/dist/webhooks/validation.js.map +1 -1
- package/package.json +1 -1
- package/dist/frontend/assets/index-BotTEisS.js +0 -13
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { truncateEventText as truncate, validateEd25519Signature } from "../validation.js";
|
|
2
|
+
// Discord interaction types
|
|
3
|
+
const INTERACTION_TYPE_PING = 1;
|
|
4
|
+
const INTERACTION_TYPE_APPLICATION_COMMAND = 2;
|
|
5
|
+
const INTERACTION_TYPE_MESSAGE_COMPONENT = 3;
|
|
6
|
+
const INTERACTION_TYPE_AUTOCOMPLETE = 4;
|
|
7
|
+
const INTERACTION_TYPE_MODAL_SUBMIT = 5;
|
|
8
|
+
const INTERACTION_TYPE_NAMES = {
|
|
9
|
+
[INTERACTION_TYPE_APPLICATION_COMMAND]: "application_command",
|
|
10
|
+
[INTERACTION_TYPE_MESSAGE_COMPONENT]: "message_component",
|
|
11
|
+
[INTERACTION_TYPE_AUTOCOMPLETE]: "autocomplete",
|
|
12
|
+
[INTERACTION_TYPE_MODAL_SUBMIT]: "modal_submit",
|
|
13
|
+
};
|
|
14
|
+
export class DiscordWebhookProvider {
|
|
15
|
+
source = "discord";
|
|
16
|
+
getDeliveryId(headers) {
|
|
17
|
+
return headers["x-interaction-id"] ?? null;
|
|
18
|
+
}
|
|
19
|
+
validateRequest(headers, rawBody, secrets, allowUnsigned) {
|
|
20
|
+
return validateEd25519Signature(rawBody, headers["x-signature-timestamp"], headers["x-signature-ed25519"], secrets, allowUnsigned);
|
|
21
|
+
}
|
|
22
|
+
parseEvent(headers, body) {
|
|
23
|
+
if (!body || typeof body !== "object")
|
|
24
|
+
return null;
|
|
25
|
+
const interactionType = body.type;
|
|
26
|
+
if (!interactionType || interactionType === INTERACTION_TYPE_PING)
|
|
27
|
+
return null;
|
|
28
|
+
const event = INTERACTION_TYPE_NAMES[interactionType];
|
|
29
|
+
if (!event)
|
|
30
|
+
return null;
|
|
31
|
+
const data = body.data;
|
|
32
|
+
const user = body.member?.user || body.user;
|
|
33
|
+
const guildId = body.guild_id || "";
|
|
34
|
+
const channelId = body.channel_id || "";
|
|
35
|
+
const base = {
|
|
36
|
+
source: "discord",
|
|
37
|
+
event,
|
|
38
|
+
repo: guildId,
|
|
39
|
+
branch: channelId,
|
|
40
|
+
sender: user?.username || "unknown",
|
|
41
|
+
timestamp: new Date().toISOString(),
|
|
42
|
+
};
|
|
43
|
+
switch (interactionType) {
|
|
44
|
+
case INTERACTION_TYPE_APPLICATION_COMMAND: {
|
|
45
|
+
const commandName = data?.name || "unknown";
|
|
46
|
+
const options = data?.options;
|
|
47
|
+
let bodyText;
|
|
48
|
+
if (options?.length) {
|
|
49
|
+
bodyText = options.map((o) => `${o.name}: ${o.value}`).join(", ");
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
...base,
|
|
53
|
+
action: commandName,
|
|
54
|
+
title: commandName,
|
|
55
|
+
body: truncate(bodyText),
|
|
56
|
+
number: undefined,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
case INTERACTION_TYPE_MESSAGE_COMPONENT: {
|
|
60
|
+
return {
|
|
61
|
+
...base,
|
|
62
|
+
action: String(data?.component_type || "unknown"),
|
|
63
|
+
title: data?.custom_id || "component",
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
case INTERACTION_TYPE_AUTOCOMPLETE: {
|
|
67
|
+
const commandName = data?.name || "unknown";
|
|
68
|
+
return {
|
|
69
|
+
...base,
|
|
70
|
+
action: commandName,
|
|
71
|
+
title: commandName,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
case INTERACTION_TYPE_MODAL_SUBMIT: {
|
|
75
|
+
return {
|
|
76
|
+
...base,
|
|
77
|
+
action: data?.custom_id || "modal",
|
|
78
|
+
title: data?.custom_id || "modal",
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
default:
|
|
82
|
+
return {
|
|
83
|
+
...base,
|
|
84
|
+
title: event,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
matchesFilter(context, filter) {
|
|
89
|
+
const f = filter;
|
|
90
|
+
if (f.events?.length && !f.events.includes(context.event)) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
if (f.guilds?.length && !f.guilds.includes(context.repo)) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
// channel_id is stored in context.branch
|
|
97
|
+
if (f.channels?.length && context.branch && !f.channels.includes(context.branch)) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
// commands filter: match against title (command name) for command-type events
|
|
101
|
+
if (f.commands?.length) {
|
|
102
|
+
if (context.event === "application_command" || context.event === "autocomplete") {
|
|
103
|
+
if (!context.title || !f.commands.includes(context.title)) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// For non-command events (components, modals), commands filter does not apply — pass through
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=discord.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discord.js","sourceRoot":"","sources":["../../../src/webhooks/providers/discord.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,8 +18,20 @@ export declare const mintlifyWebhookExtension: WebhookExtension;
|
|
|
18
18
|
* Sentry webhook provider extension
|
|
19
19
|
*/
|
|
20
20
|
export declare const sentryWebhookExtension: WebhookExtension;
|
|
21
|
+
/**
|
|
22
|
+
* Slack webhook provider extension
|
|
23
|
+
*/
|
|
24
|
+
export declare const slackWebhookExtension: WebhookExtension;
|
|
21
25
|
/**
|
|
22
26
|
* Test webhook provider extension
|
|
23
27
|
*/
|
|
24
28
|
export declare const testWebhookExtension: WebhookExtension;
|
|
29
|
+
/**
|
|
30
|
+
* Discord webhook provider extension
|
|
31
|
+
*/
|
|
32
|
+
export declare const discordWebhookExtension: WebhookExtension;
|
|
33
|
+
/**
|
|
34
|
+
* Twitter webhook provider extension
|
|
35
|
+
*/
|
|
36
|
+
export declare const twitterWebhookExtension: WebhookExtension;
|
|
25
37
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/webhooks/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/webhooks/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAUlE;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,gBAyBpC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,gBAyBpC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,gBAyBtC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,gBAyBpC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,gBAyBnC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,EAAE,gBAelC,CAAC;AACF;;GAEG;AACH,eAAO,MAAM,uBAAuB,EAAE,gBA6BrC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB,EAAE,gBAiDrC,CAAC"}
|
|
@@ -5,7 +5,10 @@ import { GitHubWebhookProvider } from "./github.js";
|
|
|
5
5
|
import { LinearWebhookProvider } from "./linear.js";
|
|
6
6
|
import { MintlifyWebhookProvider } from "./mintlify.js";
|
|
7
7
|
import { SentryWebhookProvider } from "./sentry.js";
|
|
8
|
+
import { DiscordWebhookProvider } from "./discord.js";
|
|
9
|
+
import { SlackWebhookProvider } from "./slack.js";
|
|
8
10
|
import { TestWebhookProvider } from "./test.js";
|
|
11
|
+
import { TwitterWebhookProvider } from "./twitter.js";
|
|
9
12
|
/**
|
|
10
13
|
* GitHub webhook provider extension
|
|
11
14
|
*/
|
|
@@ -122,6 +125,35 @@ export const sentryWebhookExtension = {
|
|
|
122
125
|
// No cleanup required
|
|
123
126
|
}
|
|
124
127
|
};
|
|
128
|
+
/**
|
|
129
|
+
* Slack webhook provider extension
|
|
130
|
+
*/
|
|
131
|
+
export const slackWebhookExtension = {
|
|
132
|
+
metadata: {
|
|
133
|
+
name: "slack",
|
|
134
|
+
version: "1.0.0",
|
|
135
|
+
description: "Slack Events API webhook provider",
|
|
136
|
+
type: "webhook",
|
|
137
|
+
requiredCredentials: [
|
|
138
|
+
{ type: "slack_signing_secret", description: "Slack signing secret for request verification", optional: true }
|
|
139
|
+
],
|
|
140
|
+
providesCredentialTypes: [
|
|
141
|
+
{
|
|
142
|
+
type: "slack_signing_secret",
|
|
143
|
+
fields: ["secret"],
|
|
144
|
+
description: "Slack signing secret",
|
|
145
|
+
envMapping: { secret: "SLACK_SIGNING_SECRET" }
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
provider: new SlackWebhookProvider(),
|
|
150
|
+
async init() {
|
|
151
|
+
// No special initialization required
|
|
152
|
+
},
|
|
153
|
+
async shutdown() {
|
|
154
|
+
// No cleanup required
|
|
155
|
+
}
|
|
156
|
+
};
|
|
125
157
|
/**
|
|
126
158
|
* Test webhook provider extension
|
|
127
159
|
*/
|
|
@@ -141,4 +173,90 @@ export const testWebhookExtension = {
|
|
|
141
173
|
// No cleanup required
|
|
142
174
|
}
|
|
143
175
|
};
|
|
176
|
+
/**
|
|
177
|
+
* Discord webhook provider extension
|
|
178
|
+
*/
|
|
179
|
+
export const discordWebhookExtension = {
|
|
180
|
+
metadata: {
|
|
181
|
+
name: "discord",
|
|
182
|
+
version: "1.0.0",
|
|
183
|
+
description: "Discord webhook provider (Interactions Endpoint)",
|
|
184
|
+
type: "webhook",
|
|
185
|
+
requiredCredentials: [
|
|
186
|
+
{ type: "discord_bot", description: "Discord bot credentials for Ed25519 signature validation", optional: true }
|
|
187
|
+
],
|
|
188
|
+
providesCredentialTypes: [
|
|
189
|
+
{
|
|
190
|
+
type: "discord_bot",
|
|
191
|
+
fields: ["application_id", "public_key", "bot_token"],
|
|
192
|
+
description: "Discord bot credentials",
|
|
193
|
+
envMapping: {
|
|
194
|
+
application_id: "DISCORD_APPLICATION_ID",
|
|
195
|
+
public_key: "DISCORD_PUBLIC_KEY",
|
|
196
|
+
bot_token: "DISCORD_BOT_TOKEN",
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
]
|
|
200
|
+
},
|
|
201
|
+
provider: new DiscordWebhookProvider(),
|
|
202
|
+
async init() {
|
|
203
|
+
// No special initialization required
|
|
204
|
+
},
|
|
205
|
+
async shutdown() {
|
|
206
|
+
// No cleanup required
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* Twitter webhook provider extension
|
|
211
|
+
*/
|
|
212
|
+
export const twitterWebhookExtension = {
|
|
213
|
+
metadata: {
|
|
214
|
+
name: "twitter",
|
|
215
|
+
version: "1.0.0",
|
|
216
|
+
description: "X (Twitter) webhook provider with CRC support",
|
|
217
|
+
type: "webhook",
|
|
218
|
+
requiredCredentials: [
|
|
219
|
+
{ type: "x_twitter_api", description: "X API credentials (consumer secret used for CRC handshake and HMAC validation)", optional: true }
|
|
220
|
+
],
|
|
221
|
+
providesCredentialTypes: [
|
|
222
|
+
{
|
|
223
|
+
type: "x_twitter_api",
|
|
224
|
+
fields: ["consumer_key", "consumer_secret", "bearer_token"],
|
|
225
|
+
description: "X (Twitter) app-level API credentials",
|
|
226
|
+
envMapping: {
|
|
227
|
+
consumer_key: "X_CONSUMER_KEY",
|
|
228
|
+
consumer_secret: "X_CONSUMER_SECRET",
|
|
229
|
+
bearer_token: "X_BEARER_TOKEN",
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
type: "x_twitter_user_oauth1",
|
|
234
|
+
fields: ["access_token", "access_token_secret"],
|
|
235
|
+
description: "X (Twitter) OAuth 1.0a user-context access tokens",
|
|
236
|
+
envMapping: {
|
|
237
|
+
access_token: "X_ACCESS_TOKEN",
|
|
238
|
+
access_token_secret: "X_ACCESS_TOKEN_SECRET",
|
|
239
|
+
}
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
type: "x_twitter_user_oauth2",
|
|
243
|
+
fields: ["client_id", "client_secret", "access_token", "refresh_token"],
|
|
244
|
+
description: "X (Twitter) OAuth 2.0 user-context credentials (PKCE flow, used for Account Activity subscriptions)",
|
|
245
|
+
envMapping: {
|
|
246
|
+
client_id: "X_OAUTH2_CLIENT_ID",
|
|
247
|
+
client_secret: "X_OAUTH2_CLIENT_SECRET",
|
|
248
|
+
access_token: "X_OAUTH2_ACCESS_TOKEN",
|
|
249
|
+
refresh_token: "X_OAUTH2_REFRESH_TOKEN",
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
]
|
|
253
|
+
},
|
|
254
|
+
provider: new TwitterWebhookProvider(),
|
|
255
|
+
async init() {
|
|
256
|
+
// No special initialization required
|
|
257
|
+
},
|
|
258
|
+
async shutdown() {
|
|
259
|
+
// No cleanup required
|
|
260
|
+
}
|
|
261
|
+
};
|
|
144
262
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/webhooks/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/webhooks/providers/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { WebhookProvider, WebhookContext, WebhookFilter } from "../types.js";
|
|
2
|
+
export declare class SlackWebhookProvider implements WebhookProvider {
|
|
3
|
+
source: string;
|
|
4
|
+
validateRequest(headers: Record<string, string | undefined>, rawBody: string, secrets?: Record<string, string>, allowUnsigned?: boolean): string | null;
|
|
5
|
+
parseEvent(headers: Record<string, string | undefined>, body: any): WebhookContext | null;
|
|
6
|
+
matchesFilter(context: WebhookContext, filter: WebhookFilter): boolean;
|
|
7
|
+
handleChallenge(headers: Record<string, string | undefined>, rawBody: string, secrets?: Record<string, string>, allowUnsigned?: boolean): object | null;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=slack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../../src/webhooks/providers/slack.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAsB,MAAM,aAAa,CAAC;AAKtG,qBAAa,oBAAqB,YAAW,eAAe;IAC1D,MAAM,SAAW;IAEjB,eAAe,CACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAC3C,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,aAAa,CAAC,EAAE,OAAO,GACtB,MAAM,GAAG,IAAI;IAgChB,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,GAAG,cAAc,GAAG,IAAI;IAyDzF,aAAa,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO;IAwBtE,eAAe,CACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAC3C,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,aAAa,CAAC,EAAE,OAAO,GACtB,MAAM,GAAG,IAAI;CAoBjB"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from "crypto";
|
|
2
|
+
import { truncateEventText as truncate } from "../validation.js";
|
|
3
|
+
const MAX_TIMESTAMP_AGE_SECONDS = 5 * 60; // 5 minutes
|
|
4
|
+
export class SlackWebhookProvider {
|
|
5
|
+
source = "slack";
|
|
6
|
+
validateRequest(headers, rawBody, secrets, allowUnsigned) {
|
|
7
|
+
// If no secrets configured, check allowUnsigned policy
|
|
8
|
+
if (!secrets || Object.keys(secrets).length === 0) {
|
|
9
|
+
return allowUnsigned ? "_unsigned" : null;
|
|
10
|
+
}
|
|
11
|
+
const timestamp = headers["x-slack-request-timestamp"];
|
|
12
|
+
const signature = headers["x-slack-signature"];
|
|
13
|
+
if (!timestamp || !signature)
|
|
14
|
+
return null;
|
|
15
|
+
// Replay protection: reject if timestamp is older than 5 minutes
|
|
16
|
+
const now = Math.floor(Date.now() / 1000);
|
|
17
|
+
if (Math.abs(now - parseInt(timestamp, 10)) > MAX_TIMESTAMP_AGE_SECONDS) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const signingBase = `v0:${timestamp}:${rawBody}`;
|
|
21
|
+
for (const [instanceName, secret] of Object.entries(secrets)) {
|
|
22
|
+
const expected = "v0=" + createHmac("sha256", secret).update(signingBase).digest("hex");
|
|
23
|
+
if (signature.length === expected.length &&
|
|
24
|
+
timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
|
|
25
|
+
return instanceName;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
parseEvent(headers, body) {
|
|
31
|
+
// URL verification challenges are handled by handleChallenge, not dispatched
|
|
32
|
+
if (body.type === "url_verification") {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
if (body.type !== "event_callback") {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const event = body.event;
|
|
39
|
+
if (!event)
|
|
40
|
+
return null;
|
|
41
|
+
const eventType = event.type;
|
|
42
|
+
const teamId = body.team_id;
|
|
43
|
+
const sender = event.user || event.bot_id || "unknown";
|
|
44
|
+
const base = {
|
|
45
|
+
source: "slack",
|
|
46
|
+
event: eventType,
|
|
47
|
+
repo: teamId,
|
|
48
|
+
sender,
|
|
49
|
+
timestamp: new Date().toISOString(),
|
|
50
|
+
};
|
|
51
|
+
switch (eventType) {
|
|
52
|
+
case "message":
|
|
53
|
+
return {
|
|
54
|
+
...base,
|
|
55
|
+
body: truncate(event.text),
|
|
56
|
+
comment: event.channel ? `channel:${event.channel}` : undefined,
|
|
57
|
+
};
|
|
58
|
+
case "app_mention":
|
|
59
|
+
return {
|
|
60
|
+
...base,
|
|
61
|
+
body: truncate(event.text),
|
|
62
|
+
comment: event.channel ? `channel:${event.channel}` : undefined,
|
|
63
|
+
};
|
|
64
|
+
case "reaction_added":
|
|
65
|
+
case "reaction_removed":
|
|
66
|
+
return {
|
|
67
|
+
...base,
|
|
68
|
+
title: event.reaction,
|
|
69
|
+
comment: event.item ? `${event.item.type}:${event.item.channel || ""}` : undefined,
|
|
70
|
+
};
|
|
71
|
+
default:
|
|
72
|
+
return {
|
|
73
|
+
...base,
|
|
74
|
+
title: eventType,
|
|
75
|
+
body: truncate(event.text),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
matchesFilter(context, filter) {
|
|
80
|
+
const f = filter;
|
|
81
|
+
if (f.events?.length && !f.events.includes(context.event)) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
if (f.team_ids?.length && !f.team_ids.includes(context.repo)) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
// Channel matching: stored as comment field with "channel:<id>" format
|
|
88
|
+
if (f.channels?.length) {
|
|
89
|
+
const channelComment = context.comment;
|
|
90
|
+
if (!channelComment)
|
|
91
|
+
return false;
|
|
92
|
+
const match = channelComment.match(/^channel:(.+)$/);
|
|
93
|
+
if (!match)
|
|
94
|
+
return false;
|
|
95
|
+
const channelId = match[1];
|
|
96
|
+
if (!f.channels.includes(channelId))
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
handleChallenge(headers, rawBody, secrets, allowUnsigned) {
|
|
102
|
+
let body;
|
|
103
|
+
try {
|
|
104
|
+
body = JSON.parse(rawBody);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
if (body.type !== "url_verification" || !body.challenge) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
// Validate the request signature before responding
|
|
113
|
+
const validationResult = this.validateRequest(headers, rawBody, secrets, allowUnsigned);
|
|
114
|
+
if (!validationResult) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
return { challenge: body.challenge };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=slack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../../../src/webhooks/providers/slack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Twitter Account Activity API v2 auto-subscribe.
|
|
3
|
+
*
|
|
4
|
+
* On gateway startup, checks if a webhook URL is registered and the bot user
|
|
5
|
+
* is subscribed. Warns if no webhook URL exists; subscribes if needed.
|
|
6
|
+
*
|
|
7
|
+
* Uses OAuth 2.0 user tokens for subscription management (per API reference).
|
|
8
|
+
* Uses app-only Bearer token for webhook listing.
|
|
9
|
+
*/
|
|
10
|
+
import type { Logger } from "../../shared/logger.js";
|
|
11
|
+
export interface TwitterSubscribeOpts {
|
|
12
|
+
bearerToken: string;
|
|
13
|
+
oauth2AccessToken: string;
|
|
14
|
+
oauth2RefreshToken: string;
|
|
15
|
+
oauth2ClientId: string;
|
|
16
|
+
oauth2ClientSecret: string;
|
|
17
|
+
/** Credential instance name for persisting refreshed tokens */
|
|
18
|
+
credentialInstance: string;
|
|
19
|
+
logger: Logger;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Check webhook registration and auto-subscribe the bot user.
|
|
23
|
+
* Never throws — all errors are logged as warnings.
|
|
24
|
+
*/
|
|
25
|
+
export declare function twitterAutoSubscribe(opts: TwitterSubscribeOpts): Promise<void>;
|
|
26
|
+
//# sourceMappingURL=twitter-subscribe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"twitter-subscribe.d.ts","sourceRoot":"","sources":["../../../src/webhooks/providers/twitter-subscribe.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGrD,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB;AA+FD;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqEpF"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Twitter Account Activity API v2 auto-subscribe.
|
|
3
|
+
*
|
|
4
|
+
* On gateway startup, checks if a webhook URL is registered and the bot user
|
|
5
|
+
* is subscribed. Warns if no webhook URL exists; subscribes if needed.
|
|
6
|
+
*
|
|
7
|
+
* Uses OAuth 2.0 user tokens for subscription management (per API reference).
|
|
8
|
+
* Uses app-only Bearer token for webhook listing.
|
|
9
|
+
*/
|
|
10
|
+
import { writeCredentialField } from "../../shared/credentials.js";
|
|
11
|
+
const TOKEN_URL = "https://api.x.com/2/oauth2/token";
|
|
12
|
+
/**
|
|
13
|
+
* Refresh the OAuth 2.0 access token using the refresh token.
|
|
14
|
+
* Returns the new access token and refresh token, and persists them to disk.
|
|
15
|
+
*/
|
|
16
|
+
async function refreshOAuth2Token(opts) {
|
|
17
|
+
const { oauth2ClientId, oauth2ClientSecret, oauth2RefreshToken, credentialInstance, logger } = opts;
|
|
18
|
+
if (!oauth2RefreshToken) {
|
|
19
|
+
logger.warn("no OAuth 2.0 refresh token available — cannot refresh access token");
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const basicAuth = Buffer.from(`${oauth2ClientId}:${oauth2ClientSecret}`).toString("base64");
|
|
23
|
+
const res = await fetch(TOKEN_URL, {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: {
|
|
26
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
27
|
+
Authorization: `Basic ${basicAuth}`,
|
|
28
|
+
},
|
|
29
|
+
body: new URLSearchParams({
|
|
30
|
+
grant_type: "refresh_token",
|
|
31
|
+
refresh_token: oauth2RefreshToken,
|
|
32
|
+
client_id: oauth2ClientId,
|
|
33
|
+
}),
|
|
34
|
+
});
|
|
35
|
+
if (!res.ok) {
|
|
36
|
+
const body = await res.text();
|
|
37
|
+
logger.warn({ status: res.status, body }, "failed to refresh OAuth 2.0 token");
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const data = (await res.json());
|
|
41
|
+
if (!data.access_token) {
|
|
42
|
+
logger.warn("refresh response missing access_token");
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
// Persist new tokens to disk
|
|
46
|
+
try {
|
|
47
|
+
await writeCredentialField("x_twitter_user_oauth2", credentialInstance, "access_token", data.access_token);
|
|
48
|
+
if (data.refresh_token) {
|
|
49
|
+
await writeCredentialField("x_twitter_user_oauth2", credentialInstance, "refresh_token", data.refresh_token);
|
|
50
|
+
}
|
|
51
|
+
logger.info("refreshed and persisted OAuth 2.0 tokens");
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
logger.warn({ err }, "refreshed OAuth 2.0 token but failed to persist — token will expire");
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
accessToken: data.access_token,
|
|
58
|
+
refreshToken: data.refresh_token ?? oauth2RefreshToken,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Make an authenticated request with OAuth 2.0 user token, retrying once with
|
|
63
|
+
* a refreshed token on 401.
|
|
64
|
+
*/
|
|
65
|
+
async function oauth2Fetch(url, method, opts) {
|
|
66
|
+
const res = await fetch(url, {
|
|
67
|
+
method,
|
|
68
|
+
headers: {
|
|
69
|
+
Authorization: `Bearer ${opts.oauth2AccessToken}`,
|
|
70
|
+
"Content-Type": "application/json",
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
if (res.status === 401) {
|
|
74
|
+
opts.logger.info("OAuth 2.0 access token expired, attempting refresh...");
|
|
75
|
+
const refreshed = await refreshOAuth2Token(opts);
|
|
76
|
+
if (refreshed) {
|
|
77
|
+
opts.oauth2AccessToken = refreshed.accessToken;
|
|
78
|
+
opts.oauth2RefreshToken = refreshed.refreshToken;
|
|
79
|
+
return fetch(url, {
|
|
80
|
+
method,
|
|
81
|
+
headers: {
|
|
82
|
+
Authorization: `Bearer ${refreshed.accessToken}`,
|
|
83
|
+
"Content-Type": "application/json",
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return res;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Check webhook registration and auto-subscribe the bot user.
|
|
92
|
+
* Never throws — all errors are logged as warnings.
|
|
93
|
+
*/
|
|
94
|
+
export async function twitterAutoSubscribe(opts) {
|
|
95
|
+
const { logger, bearerToken } = opts;
|
|
96
|
+
// Step 1: List webhooks to find webhook_id (uses app-only Bearer Token)
|
|
97
|
+
let webhookId;
|
|
98
|
+
try {
|
|
99
|
+
const listUrl = "https://api.x.com/2/webhooks";
|
|
100
|
+
const res = await fetch(listUrl, {
|
|
101
|
+
headers: { Authorization: `Bearer ${bearerToken}` },
|
|
102
|
+
});
|
|
103
|
+
if (!res.ok) {
|
|
104
|
+
const body = await res.text();
|
|
105
|
+
logger.warn({ status: res.status, body }, "failed to check Twitter webhook registration");
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const data = (await res.json());
|
|
109
|
+
const webhooks = data.data ?? [];
|
|
110
|
+
if (webhooks.length === 0) {
|
|
111
|
+
logger.warn("no webhook URL registered with Twitter — register one in the X Developer Portal or via the API");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const webhook = webhooks[0];
|
|
115
|
+
webhookId = webhook.id;
|
|
116
|
+
logger.info({ webhookId, url: webhook.url, valid: webhook.valid }, "Twitter webhook URL registered");
|
|
117
|
+
if (!webhook.valid) {
|
|
118
|
+
logger.warn({ url: webhook.url }, "Twitter webhook URL is marked as invalid — CRC challenge may be failing");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
logger.warn({ err }, "failed to check Twitter webhook registration");
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
// Step 2: Check if bot user is already subscribed (uses OAuth 2.0 user token)
|
|
126
|
+
try {
|
|
127
|
+
const subUrl = `https://api.x.com/2/account_activity/webhooks/${webhookId}/subscriptions/all`;
|
|
128
|
+
const res = await oauth2Fetch(subUrl, "GET", opts);
|
|
129
|
+
if (res.ok) {
|
|
130
|
+
const body = (await res.json());
|
|
131
|
+
if (body.data?.subscribed) {
|
|
132
|
+
logger.info("Twitter bot user already subscribed to Account Activity API");
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Not subscribed or error — proceed to subscribe
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
logger.warn({ err }, "failed to check Twitter subscription status");
|
|
140
|
+
// Proceed to attempt subscribe anyway
|
|
141
|
+
}
|
|
142
|
+
// Step 3: Subscribe bot user (uses OAuth 2.0 user token)
|
|
143
|
+
try {
|
|
144
|
+
const subUrl = `https://api.x.com/2/account_activity/webhooks/${webhookId}/subscriptions/all`;
|
|
145
|
+
const res = await oauth2Fetch(subUrl, "POST", opts);
|
|
146
|
+
if (res.ok) {
|
|
147
|
+
logger.info("Twitter bot user subscribed to Account Activity API");
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const body = await res.text();
|
|
151
|
+
logger.warn({ status: res.status, body }, "failed to subscribe Twitter bot user to Account Activity API");
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
logger.warn({ err }, "failed to subscribe Twitter bot user");
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=twitter-subscribe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"twitter-subscribe.js","sourceRoot":"","sources":["../../../src/webhooks/providers/twitter-subscribe.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAanE,MAAM,SAAS,GAAG,kCAAkC,CAAC;AAErD;;;GAGG;AACH,KAAK,UAAU,kBAAkB,CAAC,IAA0B;IAC1D,MAAM,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAEpG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,cAAc,IAAI,kBAAkB,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC5F,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;QACjC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,mCAAmC;YACnD,aAAa,EAAE,SAAS,SAAS,EAAE;SACpC;QACD,IAAI,EAAE,IAAI,eAAe,CAAC;YACxB,UAAU,EAAE,eAAe;YAC3B,aAAa,EAAE,kBAAkB;YACjC,SAAS,EAAE,cAAc;SAC1B,CAAC;KACH,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,mCAAmC,CAAC,CAAC;QAC/E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsD,CAAC;IACrF,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6BAA6B;IAC7B,IAAI,CAAC;QACH,MAAM,oBAAoB,CAAC,uBAAuB,EAAE,kBAAkB,EAAE,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3G,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,oBAAoB,CAAC,uBAAuB,EAAE,kBAAkB,EAAE,eAAe,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC/G,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IAC1D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,qEAAqE,CAAC,CAAC;IAC9F,CAAC;IAED,OAAO;QACL,WAAW,EAAE,IAAI,CAAC,YAAY;QAC9B,YAAY,EAAE,IAAI,CAAC,aAAa,IAAI,kBAAkB;KACvD,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,WAAW,CACxB,GAAW,EACX,MAAc,EACd,IAA0B;IAE1B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC3B,MAAM;QACN,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,IAAI,CAAC,iBAAiB,EAAE;YACjD,cAAc,EAAE,kBAAkB;SACnC;KACF,CAAC,CAAC;IAEH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;QAC1E,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC,WAAW,CAAC;YAC/C,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC,YAAY,CAAC;YACjD,OAAO,KAAK,CAAC,GAAG,EAAE;gBAChB,MAAM;gBACN,OAAO,EAAE;oBACP,aAAa,EAAE,UAAU,SAAS,CAAC,WAAW,EAAE;oBAChD,cAAc,EAAE,kBAAkB;iBACnC;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAA0B;IACnE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IAErC,wEAAwE;IACxE,IAAI,SAA6B,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,8BAA8B,CAAC;QAC/C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE;YAC/B,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,WAAW,EAAE,EAAE;SACpD,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,8CAA8C,CAAC,CAAC;YAC1F,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAkE,CAAC;QACjG,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QAEjC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,gGAAgG,CAAC,CAAC;YAC9G,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5B,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,gCAAgC,CAAC,CAAC;QAErG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,yEAAyE,CAAC,CAAC;QAC/G,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,8CAA8C,CAAC,CAAC;QACrE,OAAO;IACT,CAAC;IAED,8EAA8E;IAC9E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,iDAAiD,SAAS,oBAAoB,CAAC;QAC9F,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAEnD,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAwC,CAAC;YACvE,IAAI,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC;gBAC1B,MAAM,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;gBAC3E,OAAO;YACT,CAAC;QACH,CAAC;QACD,iDAAiD;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,6CAA6C,CAAC,CAAC;QACpE,sCAAsC;IACxC,CAAC;IAED,yDAAyD;IACzD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,iDAAiD,SAAS,oBAAoB,CAAC;QAC9F,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAEpD,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;QACrE,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,8DAA8D,CAAC,CAAC;QAC5G,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,sCAAsC,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC"}
|