patchwork-os 0.2.0-alpha.26 → 0.2.0-alpha.28
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/deploy/bootstrap-vps.sh +1 -1
- package/deploy/deploy-dashboard.sh +166 -0
- package/deploy/deploy-landing.sh +79 -0
- package/dist/automation.js +19 -1
- package/dist/automation.js.map +1 -1
- package/dist/ccPermissions.js +6 -4
- package/dist/ccPermissions.js.map +1 -1
- package/dist/commands/recipe.js +1 -1
- package/dist/commands/recipe.js.map +1 -1
- package/dist/commands/recipeInstall.d.ts +72 -0
- package/dist/commands/recipeInstall.js +339 -0
- package/dist/commands/recipeInstall.js.map +1 -0
- package/dist/connectors/datadog.d.ts +116 -0
- package/dist/connectors/datadog.js +385 -0
- package/dist/connectors/datadog.js.map +1 -0
- package/dist/connectors/hubspot.d.ts +112 -0
- package/dist/connectors/hubspot.js +408 -0
- package/dist/connectors/hubspot.js.map +1 -0
- package/dist/connectors/intercom.d.ts +102 -0
- package/dist/connectors/intercom.js +402 -0
- package/dist/connectors/intercom.js.map +1 -0
- package/dist/connectors/stripe.d.ts +116 -0
- package/dist/connectors/stripe.js +379 -0
- package/dist/connectors/stripe.js.map +1 -0
- package/dist/index.js +33 -26
- package/dist/index.js.map +1 -1
- package/dist/recipes/manifest.d.ts +47 -0
- package/dist/recipes/manifest.js +141 -0
- package/dist/recipes/manifest.js.map +1 -0
- package/dist/recipes/schemaGenerator.js +3 -3
- package/dist/recipes/schemaGenerator.js.map +1 -1
- package/dist/recipes/tools/datadog.d.ts +6 -0
- package/dist/recipes/tools/datadog.js +239 -0
- package/dist/recipes/tools/datadog.js.map +1 -0
- package/dist/recipes/tools/hubspot.d.ts +6 -0
- package/dist/recipes/tools/hubspot.js +232 -0
- package/dist/recipes/tools/hubspot.js.map +1 -0
- package/dist/recipes/tools/index.d.ts +4 -0
- package/dist/recipes/tools/index.js +4 -0
- package/dist/recipes/tools/index.js.map +1 -1
- package/dist/recipes/tools/intercom.d.ts +6 -0
- package/dist/recipes/tools/intercom.js +226 -0
- package/dist/recipes/tools/intercom.js.map +1 -0
- package/dist/recipes/tools/stripe.d.ts +6 -0
- package/dist/recipes/tools/stripe.js +265 -0
- package/dist/recipes/tools/stripe.js.map +1 -0
- package/dist/recipes/yamlRunner.js +28 -0
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/schemas/dry-run-plan.v1.json +1 -1
- package/dist/schemas/recipe.v1.json +1 -1
- package/dist/server.js +155 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/searchTools.js +1 -1
- package/dist/tools/searchTools.js.map +1 -1
- package/dist/tools/testTraceToSource.js +2 -2
- package/dist/tools/testTraceToSource.js.map +1 -1
- package/package.json +2 -1
- package/templates/recipes/morning-brief.yaml +2 -1
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Datadog connector — query metrics, monitors, alerts, and incidents.
|
|
3
|
+
*
|
|
4
|
+
* Auth: API key + Application key.
|
|
5
|
+
* - Env vars: DATADOG_API_KEY, DATADOG_APP_KEY, DATADOG_SITE (optional)
|
|
6
|
+
* - Stored: getSecretJsonSync("datadog") → DatadogTokens
|
|
7
|
+
* - Headers: DD-API-KEY + DD-APPLICATION-KEY
|
|
8
|
+
*
|
|
9
|
+
* Tools: queryMetrics, listMonitors, getMonitor, listActiveAlerts, muteMonitor, listIncidents
|
|
10
|
+
*
|
|
11
|
+
* Extends BaseConnector for unified auth, retry, rate-limit, error handling.
|
|
12
|
+
*/
|
|
13
|
+
import { type AuthContext, BaseConnector, type ConnectorError, type ConnectorStatus } from "./baseConnector.js";
|
|
14
|
+
export interface DatadogTokens {
|
|
15
|
+
apiKey: string;
|
|
16
|
+
appKey: string;
|
|
17
|
+
site?: string;
|
|
18
|
+
orgName?: string;
|
|
19
|
+
connected_at: string;
|
|
20
|
+
}
|
|
21
|
+
export interface DatadogSeries {
|
|
22
|
+
metric: string;
|
|
23
|
+
display_name: string;
|
|
24
|
+
unit: Array<{
|
|
25
|
+
family: string;
|
|
26
|
+
name: string;
|
|
27
|
+
short_name: string;
|
|
28
|
+
}> | null;
|
|
29
|
+
pointlist: Array<[number, number | null]>;
|
|
30
|
+
start: number;
|
|
31
|
+
end: number;
|
|
32
|
+
interval: number;
|
|
33
|
+
length: number;
|
|
34
|
+
aggr: string | null;
|
|
35
|
+
scope: string;
|
|
36
|
+
}
|
|
37
|
+
export interface DatadogMonitor {
|
|
38
|
+
id: number;
|
|
39
|
+
name: string;
|
|
40
|
+
type: string;
|
|
41
|
+
query: string;
|
|
42
|
+
message: string;
|
|
43
|
+
status: string;
|
|
44
|
+
state: string;
|
|
45
|
+
tags: string[];
|
|
46
|
+
created: string;
|
|
47
|
+
modified: string;
|
|
48
|
+
overall_state: string;
|
|
49
|
+
}
|
|
50
|
+
export interface DatadogIncident {
|
|
51
|
+
id: string;
|
|
52
|
+
type: string;
|
|
53
|
+
attributes: {
|
|
54
|
+
title: string;
|
|
55
|
+
status: string;
|
|
56
|
+
severity: string;
|
|
57
|
+
created: string;
|
|
58
|
+
modified: string;
|
|
59
|
+
customer_impact_scope?: string;
|
|
60
|
+
customer_impacted: boolean;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export declare class DatadogConnector extends BaseConnector {
|
|
64
|
+
readonly providerName = "datadog";
|
|
65
|
+
private tokens;
|
|
66
|
+
protected getOAuthConfig(): null;
|
|
67
|
+
authenticate(): Promise<AuthContext>;
|
|
68
|
+
healthCheck(): Promise<{
|
|
69
|
+
ok: boolean;
|
|
70
|
+
error?: ConnectorError;
|
|
71
|
+
}>;
|
|
72
|
+
normalizeError(error: unknown): ConnectorError;
|
|
73
|
+
getStatus(): ConnectorStatus;
|
|
74
|
+
queryMetrics(query: string, from: number, to: number): Promise<{
|
|
75
|
+
series: DatadogSeries[];
|
|
76
|
+
}>;
|
|
77
|
+
listMonitors(params?: {
|
|
78
|
+
groupStates?: string[];
|
|
79
|
+
tags?: string[];
|
|
80
|
+
perPage?: number;
|
|
81
|
+
}): Promise<DatadogMonitor[]>;
|
|
82
|
+
getMonitor(monitorId: number): Promise<DatadogMonitor>;
|
|
83
|
+
listActiveAlerts(params?: {
|
|
84
|
+
priority?: number;
|
|
85
|
+
}): Promise<DatadogMonitor[]>;
|
|
86
|
+
muteMonitor(monitorId: number, end?: number): Promise<DatadogMonitor>;
|
|
87
|
+
listIncidents(params?: {
|
|
88
|
+
perPage?: number;
|
|
89
|
+
}): Promise<{
|
|
90
|
+
data: DatadogIncident[];
|
|
91
|
+
}>;
|
|
92
|
+
private baseUrl;
|
|
93
|
+
private buildHeaders;
|
|
94
|
+
}
|
|
95
|
+
export declare function loadTokens(): DatadogTokens | null;
|
|
96
|
+
export declare function saveTokens(tokens: DatadogTokens): void;
|
|
97
|
+
export declare function clearTokens(): void;
|
|
98
|
+
export declare function getDatadogConnector(): DatadogConnector;
|
|
99
|
+
export { getDatadogConnector as datadog };
|
|
100
|
+
export interface ConnectorHandlerResult {
|
|
101
|
+
status: number;
|
|
102
|
+
body: string;
|
|
103
|
+
contentType?: string;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* POST /connections/datadog/connect { apiKey, appKey, site? }
|
|
107
|
+
*/
|
|
108
|
+
export declare function handleDatadogConnect(body: string): Promise<ConnectorHandlerResult>;
|
|
109
|
+
/**
|
|
110
|
+
* POST /connections/datadog/test
|
|
111
|
+
*/
|
|
112
|
+
export declare function handleDatadogTest(): Promise<ConnectorHandlerResult>;
|
|
113
|
+
/**
|
|
114
|
+
* DELETE /connections/datadog
|
|
115
|
+
*/
|
|
116
|
+
export declare function handleDatadogDisconnect(): ConnectorHandlerResult;
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Datadog connector — query metrics, monitors, alerts, and incidents.
|
|
3
|
+
*
|
|
4
|
+
* Auth: API key + Application key.
|
|
5
|
+
* - Env vars: DATADOG_API_KEY, DATADOG_APP_KEY, DATADOG_SITE (optional)
|
|
6
|
+
* - Stored: getSecretJsonSync("datadog") → DatadogTokens
|
|
7
|
+
* - Headers: DD-API-KEY + DD-APPLICATION-KEY
|
|
8
|
+
*
|
|
9
|
+
* Tools: queryMetrics, listMonitors, getMonitor, listActiveAlerts, muteMonitor, listIncidents
|
|
10
|
+
*
|
|
11
|
+
* Extends BaseConnector for unified auth, retry, rate-limit, error handling.
|
|
12
|
+
*/
|
|
13
|
+
import { BaseConnector, } from "./baseConnector.js";
|
|
14
|
+
import { deleteSecretJsonSync, getSecretJsonSync, storeSecretJsonSync, } from "./tokenStorage.js";
|
|
15
|
+
export class DatadogConnector extends BaseConnector {
|
|
16
|
+
providerName = "datadog";
|
|
17
|
+
tokens = null;
|
|
18
|
+
getOAuthConfig() {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
async authenticate() {
|
|
22
|
+
const tokens = loadTokens();
|
|
23
|
+
if (!tokens) {
|
|
24
|
+
throw new Error("Datadog not connected. Run: patchwork-os connect datadog or set DATADOG_API_KEY");
|
|
25
|
+
}
|
|
26
|
+
this.tokens = tokens;
|
|
27
|
+
return {
|
|
28
|
+
token: tokens.apiKey,
|
|
29
|
+
scopes: ["read", "write"],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
async healthCheck() {
|
|
33
|
+
try {
|
|
34
|
+
const result = await this.apiCall(async () => {
|
|
35
|
+
const res = await fetch(`${this.baseUrl()}/api/v1/validate`, {
|
|
36
|
+
headers: this.buildHeaders(),
|
|
37
|
+
});
|
|
38
|
+
if (!res.ok)
|
|
39
|
+
throw new Error(`HTTP ${res.status}`);
|
|
40
|
+
return res.json();
|
|
41
|
+
});
|
|
42
|
+
if ("error" in result)
|
|
43
|
+
return { ok: false, error: result.error };
|
|
44
|
+
return { ok: true };
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
return { ok: false, error: this.normalizeError(err) };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
normalizeError(error) {
|
|
51
|
+
if (error instanceof Response) {
|
|
52
|
+
const s = error.status;
|
|
53
|
+
if (s === 401 || s === 403)
|
|
54
|
+
return {
|
|
55
|
+
code: "auth_expired",
|
|
56
|
+
message: "Datadog authentication failed — check API key and App key",
|
|
57
|
+
retryable: false,
|
|
58
|
+
suggestedAction: "patchwork-os connect datadog",
|
|
59
|
+
};
|
|
60
|
+
if (s === 404)
|
|
61
|
+
return {
|
|
62
|
+
code: "not_found",
|
|
63
|
+
message: "Datadog resource not found",
|
|
64
|
+
retryable: false,
|
|
65
|
+
};
|
|
66
|
+
if (s === 429)
|
|
67
|
+
return {
|
|
68
|
+
code: "rate_limited",
|
|
69
|
+
message: "Datadog API rate limit exceeded",
|
|
70
|
+
retryable: true,
|
|
71
|
+
suggestedAction: "Wait and retry",
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
code: "provider_error",
|
|
75
|
+
message: `Datadog API error: HTTP ${s}`,
|
|
76
|
+
retryable: s >= 500,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (error instanceof Error) {
|
|
80
|
+
if (error.message.includes("ENOTFOUND") ||
|
|
81
|
+
error.message.includes("ECONNREFUSED")) {
|
|
82
|
+
return {
|
|
83
|
+
code: "network_error",
|
|
84
|
+
message: `Cannot connect to Datadog: ${error.message}`,
|
|
85
|
+
retryable: true,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
code: "provider_error",
|
|
91
|
+
message: error instanceof Error ? error.message : String(error),
|
|
92
|
+
retryable: false,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
getStatus() {
|
|
96
|
+
const tokens = loadTokens();
|
|
97
|
+
return {
|
|
98
|
+
id: "datadog",
|
|
99
|
+
status: tokens ? "connected" : "disconnected",
|
|
100
|
+
lastSync: tokens?.connected_at,
|
|
101
|
+
workspace: tokens?.orgName ?? tokens?.site ?? undefined,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// ── API Methods ────────────────────────────────────────────────────────────
|
|
105
|
+
async queryMetrics(query, from, to) {
|
|
106
|
+
const result = await this.apiCall(async () => {
|
|
107
|
+
const q = encodeURIComponent(query);
|
|
108
|
+
const url = `${this.baseUrl()}/api/v1/query?query=${q}&from=${from}&to=${to}`;
|
|
109
|
+
const res = await fetch(url, { headers: this.buildHeaders() });
|
|
110
|
+
this.updateRateLimitFromHeaders({
|
|
111
|
+
"x-ratelimit-remaining": res.headers.get("x-ratelimit-remaining") ?? undefined,
|
|
112
|
+
"retry-after": res.headers.get("retry-after") ?? undefined,
|
|
113
|
+
});
|
|
114
|
+
if (!res.ok)
|
|
115
|
+
throw res;
|
|
116
|
+
return res.json();
|
|
117
|
+
});
|
|
118
|
+
if ("error" in result)
|
|
119
|
+
throw new Error(result.error.message);
|
|
120
|
+
return result.data;
|
|
121
|
+
}
|
|
122
|
+
async listMonitors(params = {}) {
|
|
123
|
+
const result = await this.apiCall(async () => {
|
|
124
|
+
const qs = new URLSearchParams({ group_states: "all" });
|
|
125
|
+
if (params.tags?.length)
|
|
126
|
+
qs.set("tags", params.tags.join(","));
|
|
127
|
+
if (params.perPage)
|
|
128
|
+
qs.set("per_page", String(params.perPage));
|
|
129
|
+
const res = await fetch(`${this.baseUrl()}/api/v1/monitor?${qs}`, {
|
|
130
|
+
headers: this.buildHeaders(),
|
|
131
|
+
});
|
|
132
|
+
if (!res.ok)
|
|
133
|
+
throw res;
|
|
134
|
+
return res.json();
|
|
135
|
+
});
|
|
136
|
+
if ("error" in result)
|
|
137
|
+
throw new Error(result.error.message);
|
|
138
|
+
return result.data;
|
|
139
|
+
}
|
|
140
|
+
async getMonitor(monitorId) {
|
|
141
|
+
const result = await this.apiCall(async () => {
|
|
142
|
+
const res = await fetch(`${this.baseUrl()}/api/v1/monitor/${monitorId}`, {
|
|
143
|
+
headers: this.buildHeaders(),
|
|
144
|
+
});
|
|
145
|
+
if (!res.ok)
|
|
146
|
+
throw res;
|
|
147
|
+
return res.json();
|
|
148
|
+
});
|
|
149
|
+
if ("error" in result)
|
|
150
|
+
throw new Error(result.error.message);
|
|
151
|
+
return result.data;
|
|
152
|
+
}
|
|
153
|
+
async listActiveAlerts(params = {}) {
|
|
154
|
+
const result = await this.apiCall(async () => {
|
|
155
|
+
const qs = new URLSearchParams({
|
|
156
|
+
monitor_tags: "*",
|
|
157
|
+
group_states: "Alert,Warn",
|
|
158
|
+
with_downtimes: "false",
|
|
159
|
+
});
|
|
160
|
+
if (params.priority !== undefined)
|
|
161
|
+
qs.set("priority", String(params.priority));
|
|
162
|
+
const res = await fetch(`${this.baseUrl()}/api/v1/monitor?${qs}`, {
|
|
163
|
+
headers: this.buildHeaders(),
|
|
164
|
+
});
|
|
165
|
+
if (!res.ok)
|
|
166
|
+
throw res;
|
|
167
|
+
const monitors = (await res.json());
|
|
168
|
+
return monitors.filter((m) => m.overall_state === "Alert" || m.overall_state === "Warn");
|
|
169
|
+
});
|
|
170
|
+
if ("error" in result)
|
|
171
|
+
throw new Error(result.error.message);
|
|
172
|
+
return result.data;
|
|
173
|
+
}
|
|
174
|
+
async muteMonitor(monitorId, end) {
|
|
175
|
+
const result = await this.apiCall(async () => {
|
|
176
|
+
const body = {};
|
|
177
|
+
if (end !== undefined)
|
|
178
|
+
body.end = end;
|
|
179
|
+
const res = await fetch(`${this.baseUrl()}/api/v1/monitor/${monitorId}/mute`, {
|
|
180
|
+
method: "POST",
|
|
181
|
+
headers: this.buildHeaders(),
|
|
182
|
+
body: JSON.stringify(body),
|
|
183
|
+
});
|
|
184
|
+
if (!res.ok)
|
|
185
|
+
throw res;
|
|
186
|
+
return res.json();
|
|
187
|
+
});
|
|
188
|
+
if ("error" in result)
|
|
189
|
+
throw new Error(result.error.message);
|
|
190
|
+
return result.data;
|
|
191
|
+
}
|
|
192
|
+
async listIncidents(params = {}) {
|
|
193
|
+
const result = await this.apiCall(async () => {
|
|
194
|
+
const qs = new URLSearchParams();
|
|
195
|
+
if (params.perPage)
|
|
196
|
+
qs.set("page[size]", String(params.perPage));
|
|
197
|
+
const url = `${this.baseUrl()}/api/v2/incidents${qs.toString() ? `?${qs}` : ""}`;
|
|
198
|
+
const res = await fetch(url, { headers: this.buildHeaders() });
|
|
199
|
+
if (!res.ok)
|
|
200
|
+
throw res;
|
|
201
|
+
return res.json();
|
|
202
|
+
});
|
|
203
|
+
if ("error" in result)
|
|
204
|
+
throw new Error(result.error.message);
|
|
205
|
+
return result.data;
|
|
206
|
+
}
|
|
207
|
+
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
208
|
+
baseUrl() {
|
|
209
|
+
return `https://api.${this.tokens?.site ?? "datadoghq.com"}`;
|
|
210
|
+
}
|
|
211
|
+
buildHeaders() {
|
|
212
|
+
return {
|
|
213
|
+
"DD-API-KEY": this.tokens?.apiKey ?? "",
|
|
214
|
+
"DD-APPLICATION-KEY": this.tokens?.appKey ?? "",
|
|
215
|
+
"Content-Type": "application/json",
|
|
216
|
+
Accept: "application/json",
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
// ── Token persistence ────────────────────────────────────────────────────────
|
|
221
|
+
export function loadTokens() {
|
|
222
|
+
const envApiKey = process.env.DATADOG_API_KEY;
|
|
223
|
+
const envAppKey = process.env.DATADOG_APP_KEY;
|
|
224
|
+
if (envApiKey && envAppKey) {
|
|
225
|
+
return {
|
|
226
|
+
apiKey: envApiKey,
|
|
227
|
+
appKey: envAppKey,
|
|
228
|
+
site: process.env.DATADOG_SITE ?? "datadoghq.com",
|
|
229
|
+
connected_at: new Date().toISOString(),
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
return getSecretJsonSync("datadog");
|
|
233
|
+
}
|
|
234
|
+
export function saveTokens(tokens) {
|
|
235
|
+
storeSecretJsonSync("datadog", tokens);
|
|
236
|
+
}
|
|
237
|
+
export function clearTokens() {
|
|
238
|
+
try {
|
|
239
|
+
deleteSecretJsonSync("datadog");
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
// ignore
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// ── Singleton instance ───────────────────────────────────────────────────────
|
|
246
|
+
let _instance = null;
|
|
247
|
+
function resetDatadogConnector() {
|
|
248
|
+
_instance = null;
|
|
249
|
+
}
|
|
250
|
+
export function getDatadogConnector() {
|
|
251
|
+
if (!_instance) {
|
|
252
|
+
_instance = new DatadogConnector();
|
|
253
|
+
}
|
|
254
|
+
return _instance;
|
|
255
|
+
}
|
|
256
|
+
export { getDatadogConnector as datadog };
|
|
257
|
+
/**
|
|
258
|
+
* POST /connections/datadog/connect { apiKey, appKey, site? }
|
|
259
|
+
*/
|
|
260
|
+
export async function handleDatadogConnect(body) {
|
|
261
|
+
let apiKey;
|
|
262
|
+
let appKey;
|
|
263
|
+
let site;
|
|
264
|
+
try {
|
|
265
|
+
const parsed = JSON.parse(body);
|
|
266
|
+
if (typeof parsed.apiKey !== "string" || !parsed.apiKey) {
|
|
267
|
+
return {
|
|
268
|
+
status: 400,
|
|
269
|
+
contentType: "application/json",
|
|
270
|
+
body: JSON.stringify({ ok: false, error: "apiKey is required" }),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
if (typeof parsed.appKey !== "string" || !parsed.appKey) {
|
|
274
|
+
return {
|
|
275
|
+
status: 400,
|
|
276
|
+
contentType: "application/json",
|
|
277
|
+
body: JSON.stringify({ ok: false, error: "appKey is required" }),
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
apiKey = parsed.apiKey;
|
|
281
|
+
appKey = parsed.appKey;
|
|
282
|
+
site =
|
|
283
|
+
typeof parsed.site === "string" && parsed.site
|
|
284
|
+
? parsed.site
|
|
285
|
+
: "datadoghq.com";
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
return {
|
|
289
|
+
status: 400,
|
|
290
|
+
contentType: "application/json",
|
|
291
|
+
body: JSON.stringify({ ok: false, error: "Invalid JSON body" }),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
try {
|
|
295
|
+
const res = await fetch(`https://api.${site}/api/v1/validate`, {
|
|
296
|
+
headers: {
|
|
297
|
+
"DD-API-KEY": apiKey,
|
|
298
|
+
"DD-APPLICATION-KEY": appKey,
|
|
299
|
+
Accept: "application/json",
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
if (!res.ok) {
|
|
303
|
+
return {
|
|
304
|
+
status: 401,
|
|
305
|
+
contentType: "application/json",
|
|
306
|
+
body: JSON.stringify({
|
|
307
|
+
ok: false,
|
|
308
|
+
error: `Credentials rejected by Datadog (HTTP ${res.status}) — check apiKey and appKey`,
|
|
309
|
+
}),
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
const tokens = {
|
|
313
|
+
apiKey,
|
|
314
|
+
appKey,
|
|
315
|
+
site,
|
|
316
|
+
connected_at: new Date().toISOString(),
|
|
317
|
+
};
|
|
318
|
+
saveTokens(tokens);
|
|
319
|
+
resetDatadogConnector();
|
|
320
|
+
return {
|
|
321
|
+
status: 200,
|
|
322
|
+
contentType: "application/json",
|
|
323
|
+
body: JSON.stringify({
|
|
324
|
+
ok: true,
|
|
325
|
+
site,
|
|
326
|
+
connectedAt: tokens.connected_at,
|
|
327
|
+
}),
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
catch (err) {
|
|
331
|
+
return {
|
|
332
|
+
status: 500,
|
|
333
|
+
contentType: "application/json",
|
|
334
|
+
body: JSON.stringify({
|
|
335
|
+
ok: false,
|
|
336
|
+
error: err instanceof Error ? err.message : String(err),
|
|
337
|
+
}),
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* POST /connections/datadog/test
|
|
343
|
+
*/
|
|
344
|
+
export async function handleDatadogTest() {
|
|
345
|
+
const tokens = loadTokens();
|
|
346
|
+
if (!tokens) {
|
|
347
|
+
return {
|
|
348
|
+
status: 400,
|
|
349
|
+
contentType: "application/json",
|
|
350
|
+
body: JSON.stringify({ ok: false, error: "Datadog not connected" }),
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
try {
|
|
354
|
+
const connector = getDatadogConnector();
|
|
355
|
+
const check = await connector.healthCheck();
|
|
356
|
+
return {
|
|
357
|
+
status: check.ok ? 200 : 401,
|
|
358
|
+
contentType: "application/json",
|
|
359
|
+
body: JSON.stringify(check.ok ? { ok: true } : { ok: false, error: check.error?.message }),
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
catch (err) {
|
|
363
|
+
return {
|
|
364
|
+
status: 500,
|
|
365
|
+
contentType: "application/json",
|
|
366
|
+
body: JSON.stringify({
|
|
367
|
+
ok: false,
|
|
368
|
+
error: err instanceof Error ? err.message : String(err),
|
|
369
|
+
}),
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* DELETE /connections/datadog
|
|
375
|
+
*/
|
|
376
|
+
export function handleDatadogDisconnect() {
|
|
377
|
+
clearTokens();
|
|
378
|
+
resetDatadogConnector();
|
|
379
|
+
return {
|
|
380
|
+
status: 200,
|
|
381
|
+
contentType: "application/json",
|
|
382
|
+
body: JSON.stringify({ ok: true }),
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
//# sourceMappingURL=datadog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datadog.js","sourceRoot":"","sources":["../../src/connectors/datadog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HubSpot connector — read/write HubSpot CRM via the HubSpot REST API v3.
|
|
3
|
+
*
|
|
4
|
+
* Auth: Private App access token (Bearer).
|
|
5
|
+
* - Env var: HUBSPOT_ACCESS_TOKEN
|
|
6
|
+
* - Stored: getSecretJsonSync("hubspot") → HubSpotTokens
|
|
7
|
+
*
|
|
8
|
+
* Tools: listContacts, getContact, listDeals, getDeal, createNote, searchContacts
|
|
9
|
+
*
|
|
10
|
+
* Extends BaseConnector for unified auth, retry, rate-limit, error handling.
|
|
11
|
+
*/
|
|
12
|
+
import { type AuthContext, BaseConnector, type ConnectorError, type ConnectorStatus } from "./baseConnector.js";
|
|
13
|
+
export interface HubSpotTokens {
|
|
14
|
+
accessToken: string;
|
|
15
|
+
hubId?: number;
|
|
16
|
+
portalName?: string;
|
|
17
|
+
connected_at: string;
|
|
18
|
+
}
|
|
19
|
+
export interface HubSpotContact {
|
|
20
|
+
id: string;
|
|
21
|
+
properties: {
|
|
22
|
+
firstname?: string;
|
|
23
|
+
lastname?: string;
|
|
24
|
+
email?: string;
|
|
25
|
+
phone?: string;
|
|
26
|
+
company?: string;
|
|
27
|
+
lifecyclestage?: string;
|
|
28
|
+
[key: string]: string | undefined;
|
|
29
|
+
};
|
|
30
|
+
createdAt: string;
|
|
31
|
+
updatedAt: string;
|
|
32
|
+
}
|
|
33
|
+
export interface HubSpotDeal {
|
|
34
|
+
id: string;
|
|
35
|
+
properties: {
|
|
36
|
+
dealname?: string;
|
|
37
|
+
amount?: string;
|
|
38
|
+
dealstage?: string;
|
|
39
|
+
closedate?: string;
|
|
40
|
+
pipeline?: string;
|
|
41
|
+
hs_deal_stage_probability?: string;
|
|
42
|
+
[key: string]: string | undefined;
|
|
43
|
+
};
|
|
44
|
+
createdAt: string;
|
|
45
|
+
updatedAt: string;
|
|
46
|
+
}
|
|
47
|
+
export interface HubSpotNote {
|
|
48
|
+
id: string;
|
|
49
|
+
properties: {
|
|
50
|
+
hs_note_body?: string;
|
|
51
|
+
hs_timestamp?: string;
|
|
52
|
+
[key: string]: string | undefined;
|
|
53
|
+
};
|
|
54
|
+
createdAt: string;
|
|
55
|
+
updatedAt: string;
|
|
56
|
+
}
|
|
57
|
+
export interface HubSpotPaging {
|
|
58
|
+
next?: {
|
|
59
|
+
after: string;
|
|
60
|
+
link?: string;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export interface HubSpotListResult<T> {
|
|
64
|
+
results: T[];
|
|
65
|
+
paging?: HubSpotPaging;
|
|
66
|
+
}
|
|
67
|
+
export declare class HubSpotConnector extends BaseConnector {
|
|
68
|
+
readonly providerName = "hubspot";
|
|
69
|
+
protected getOAuthConfig(): null;
|
|
70
|
+
authenticate(): Promise<AuthContext>;
|
|
71
|
+
healthCheck(): Promise<{
|
|
72
|
+
ok: boolean;
|
|
73
|
+
error?: ConnectorError;
|
|
74
|
+
}>;
|
|
75
|
+
normalizeError(error: unknown): ConnectorError;
|
|
76
|
+
getStatus(): ConnectorStatus;
|
|
77
|
+
listContacts(params?: {
|
|
78
|
+
limit?: number;
|
|
79
|
+
after?: string;
|
|
80
|
+
}): Promise<HubSpotListResult<HubSpotContact>>;
|
|
81
|
+
getContact(contactId: string): Promise<HubSpotContact | null>;
|
|
82
|
+
listDeals(params?: {
|
|
83
|
+
limit?: number;
|
|
84
|
+
stage?: string;
|
|
85
|
+
}): Promise<HubSpotListResult<HubSpotDeal>>;
|
|
86
|
+
getDeal(dealId: string): Promise<HubSpotDeal | null>;
|
|
87
|
+
createNote(body: string, contactId?: string, dealId?: string): Promise<HubSpotNote>;
|
|
88
|
+
searchContacts(query: string): Promise<HubSpotContact[]>;
|
|
89
|
+
private buildHeaders;
|
|
90
|
+
}
|
|
91
|
+
export declare function loadTokens(): HubSpotTokens | null;
|
|
92
|
+
export declare function saveTokens(tokens: HubSpotTokens): void;
|
|
93
|
+
export declare function clearTokens(): void;
|
|
94
|
+
export declare function getHubSpotConnector(): HubSpotConnector;
|
|
95
|
+
export { getHubSpotConnector as hubspot };
|
|
96
|
+
export interface ConnectorHandlerResult {
|
|
97
|
+
status: number;
|
|
98
|
+
body: string;
|
|
99
|
+
contentType?: string;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* POST /connections/hubspot/connect { accessToken }
|
|
103
|
+
*/
|
|
104
|
+
export declare function handleHubSpotConnect(body: string): Promise<ConnectorHandlerResult>;
|
|
105
|
+
/**
|
|
106
|
+
* POST /connections/hubspot/test
|
|
107
|
+
*/
|
|
108
|
+
export declare function handleHubSpotTest(): Promise<ConnectorHandlerResult>;
|
|
109
|
+
/**
|
|
110
|
+
* DELETE /connections/hubspot
|
|
111
|
+
*/
|
|
112
|
+
export declare function handleHubSpotDisconnect(): ConnectorHandlerResult;
|