runline 0.1.0
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/.pi/extensions/runline-context/index.ts +135 -0
- package/.pi/extensions/runline-context/package.json +17 -0
- package/README.md +273 -0
- package/dist/commands/actions.d.ts +3 -0
- package/dist/commands/actions.js +43 -0
- package/dist/commands/connection.d.ts +11 -0
- package/dist/commands/connection.js +56 -0
- package/dist/commands/exec.d.ts +5 -0
- package/dist/commands/exec.js +46 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.js +26 -0
- package/dist/commands/plugin.d.ts +10 -0
- package/dist/commands/plugin.js +57 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.js +2 -0
- package/dist/config/loader.d.ts +11 -0
- package/dist/config/loader.js +82 -0
- package/dist/config/types.d.ts +9 -0
- package/dist/config/types.js +5 -0
- package/dist/core/engine.d.ts +21 -0
- package/dist/core/engine.js +280 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +9 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +127 -0
- package/dist/plugin/api.d.ts +32 -0
- package/dist/plugin/api.js +68 -0
- package/dist/plugin/installer.d.ts +27 -0
- package/dist/plugin/installer.js +181 -0
- package/dist/plugin/loader.d.ts +13 -0
- package/dist/plugin/loader.js +164 -0
- package/dist/plugin/registry.d.ts +18 -0
- package/dist/plugin/registry.js +43 -0
- package/dist/plugin/types.d.ts +40 -0
- package/dist/plugin/types.js +1 -0
- package/dist/plugins/actionNetwork/src/index.js +353 -0
- package/dist/plugins/activeCampaign/src/index.js +711 -0
- package/dist/plugins/adalo/src/index.js +131 -0
- package/dist/plugins/affinity/src/index.js +279 -0
- package/dist/plugins/agileCrm/src/index.js +415 -0
- package/dist/plugins/airtable/src/index.js +280 -0
- package/dist/plugins/airtop/src/index.js +527 -0
- package/dist/plugins/apiTemplateIo/src/index.js +86 -0
- package/dist/plugins/asana/src/index.js +413 -0
- package/dist/plugins/autopilot/src/index.js +203 -0
- package/dist/plugins/bambooHr/src/index.js +252 -0
- package/dist/plugins/bannerbear/src/index.js +100 -0
- package/dist/plugins/baserow/src/index.js +180 -0
- package/dist/plugins/beeminder/src/index.js +298 -0
- package/dist/plugins/bitly/src/index.js +107 -0
- package/dist/plugins/bitwarden/src/index.js +383 -0
- package/dist/plugins/box/src/index.js +300 -0
- package/dist/plugins/brandfetch/src/index.js +80 -0
- package/dist/plugins/brevo/src/index.js +305 -0
- package/dist/plugins/bubble/src/index.js +181 -0
- package/dist/plugins/chargebee/src/index.js +126 -0
- package/dist/plugins/circleci/src/index.js +111 -0
- package/dist/plugins/ciscoWebex/src/index.js +245 -0
- package/dist/plugins/clearbit/src/index.js +103 -0
- package/dist/plugins/clickup/src/index.js +1043 -0
- package/dist/plugins/clockify/src/index.js +443 -0
- package/dist/plugins/cloudflare/src/index.js +93 -0
- package/dist/plugins/cockpit/src/index.js +131 -0
- package/dist/plugins/coda/src/index.js +327 -0
- package/dist/plugins/coingecko/src/index.js +244 -0
- package/dist/plugins/contentful/src/index.js +146 -0
- package/dist/plugins/convertkit/src/index.js +270 -0
- package/dist/plugins/copper/src/index.js +140 -0
- package/dist/plugins/cortex/src/index.js +147 -0
- package/dist/plugins/currents/src/index.js +405 -0
- package/dist/plugins/customerIo/src/index.js +184 -0
- package/dist/plugins/databricks/src/index.js +342 -0
- package/dist/plugins/deepl/src/index.js +87 -0
- package/dist/plugins/demio/src/index.js +111 -0
- package/dist/plugins/dhl/src/index.js +40 -0
- package/dist/plugins/discord/src/index.js +275 -0
- package/dist/plugins/discourse/src/index.js +273 -0
- package/dist/plugins/disqus/src/index.js +145 -0
- package/dist/plugins/docker/src/index.js +76 -0
- package/dist/plugins/drift/src/index.js +89 -0
- package/dist/plugins/dropbox/src/index.js +159 -0
- package/dist/plugins/dropcontact/src/index.js +59 -0
- package/dist/plugins/egoi/src/index.js +151 -0
- package/dist/plugins/elasticsearch/src/index.js +157 -0
- package/dist/plugins/emelia/src/index.js +174 -0
- package/dist/plugins/erpnext/src/index.js +121 -0
- package/dist/plugins/facebookGraph/src/index.js +57 -0
- package/dist/plugins/freshdesk/src/index.js +320 -0
- package/dist/plugins/freshservice/src/index.js +146 -0
- package/dist/plugins/freshworksCrm/src/index.js +149 -0
- package/dist/plugins/getresponse/src/index.js +140 -0
- package/dist/plugins/ghost/src/index.js +192 -0
- package/dist/plugins/github/src/index.js +630 -0
- package/dist/plugins/gitlab/src/index.js +358 -0
- package/dist/plugins/gong/src/index.js +126 -0
- package/dist/plugins/gotify/src/index.js +77 -0
- package/dist/plugins/gotowebinar/src/index.js +316 -0
- package/dist/plugins/grafana/src/index.js +250 -0
- package/dist/plugins/graphql/src/index.js +78 -0
- package/dist/plugins/grist/src/index.js +106 -0
- package/dist/plugins/hackernews/src/index.js +89 -0
- package/dist/plugins/halopsa/src/index.js +79 -0
- package/dist/plugins/harvest/src/index.js +163 -0
- package/dist/plugins/helpscout/src/index.js +176 -0
- package/dist/plugins/highlevel/src/index.js +172 -0
- package/dist/plugins/homeAssistant/src/index.js +148 -0
- package/dist/plugins/hubspot/src/index.js +176 -0
- package/dist/plugins/humanticAi/src/index.js +60 -0
- package/dist/plugins/hunter/src/index.js +59 -0
- package/dist/plugins/intercom/src/index.js +156 -0
- package/dist/plugins/iterable/src/index.js +139 -0
- package/dist/plugins/jenkins/src/index.js +132 -0
- package/dist/plugins/jira/src/index.js +229 -0
- package/dist/plugins/keap/src/index.js +502 -0
- package/dist/plugins/kobotoolbox/src/index.js +281 -0
- package/dist/plugins/lemlist/src/index.js +231 -0
- package/dist/plugins/linear/src/index.js +133 -0
- package/dist/plugins/lingvanex/src/index.js +31 -0
- package/dist/plugins/linkedin/src/index.js +80 -0
- package/dist/plugins/lonescale/src/index.js +119 -0
- package/dist/plugins/magento/src/index.js +300 -0
- package/dist/plugins/mailcheck/src/index.js +27 -0
- package/dist/plugins/mailchimp/src/index.js +321 -0
- package/dist/plugins/mailerlite/src/index.js +123 -0
- package/dist/plugins/mailgun/src/index.js +48 -0
- package/dist/plugins/mailjet/src/index.js +155 -0
- package/dist/plugins/mandrill/src/index.js +145 -0
- package/dist/plugins/marketstack/src/index.js +97 -0
- package/dist/plugins/matrix/src/index.js +194 -0
- package/dist/plugins/mattermost/src/index.js +331 -0
- package/dist/plugins/mautic/src/index.js +311 -0
- package/dist/plugins/medium/src/index.js +77 -0
- package/dist/plugins/messagebird/src/index.js +57 -0
- package/dist/plugins/metabase/src/index.js +130 -0
- package/dist/plugins/misp/src/index.js +476 -0
- package/dist/plugins/mocean/src/index.js +67 -0
- package/dist/plugins/monday/src/index.js +231 -0
- package/dist/plugins/monicaCrm/src/index.js +52 -0
- package/dist/plugins/msg91/src/index.js +31 -0
- package/dist/plugins/nasa/src/index.js +146 -0
- package/dist/plugins/netlify/src/index.js +151 -0
- package/dist/plugins/netscalerAdc/src/index.js +131 -0
- package/dist/plugins/nextcloud/src/index.js +263 -0
- package/dist/plugins/nocodb/src/index.js +130 -0
- package/dist/plugins/notion/src/index.js +112 -0
- package/dist/plugins/npm/src/index.js +104 -0
- package/dist/plugins/odoo/src/index.js +157 -0
- package/dist/plugins/okta/src/index.js +141 -0
- package/dist/plugins/oneSimpleApi/src/index.js +155 -0
- package/dist/plugins/onfleet/src/index.js +254 -0
- package/dist/plugins/openThesaurus/src/index.js +32 -0
- package/dist/plugins/openweathermap/src/index.js +60 -0
- package/dist/plugins/oura/src/index.js +62 -0
- package/dist/plugins/paddle/src/index.js +247 -0
- package/dist/plugins/pagerduty/src/index.js +201 -0
- package/dist/plugins/paypal/src/index.js +106 -0
- package/dist/plugins/peekalink/src/index.js +35 -0
- package/dist/plugins/phantombuster/src/index.js +94 -0
- package/dist/plugins/philipsHue/src/index.js +98 -0
- package/dist/plugins/pipedrive/src/index.js +169 -0
- package/dist/plugins/plivo/src/index.js +66 -0
- package/dist/plugins/postbin/src/index.js +93 -0
- package/dist/plugins/posthog/src/index.js +113 -0
- package/dist/plugins/profitwell/src/index.js +50 -0
- package/dist/plugins/pushbullet/src/index.js +102 -0
- package/dist/plugins/pushcut/src/index.js +39 -0
- package/dist/plugins/pushover/src/index.js +65 -0
- package/dist/plugins/quickbase/src/index.js +153 -0
- package/dist/plugins/quickbooks/src/index.js +73 -0
- package/dist/plugins/quickchart/src/index.js +36 -0
- package/dist/plugins/raindrop/src/index.js +209 -0
- package/dist/plugins/reddit/src/index.js +185 -0
- package/dist/plugins/rocketchat/src/index.js +53 -0
- package/dist/plugins/rundeck/src/index.js +62 -0
- package/dist/plugins/salesforce/src/index.js +94 -0
- package/dist/plugins/salesmate/src/index.js +83 -0
- package/dist/plugins/securityScorecard/src/index.js +200 -0
- package/dist/plugins/segment/src/index.js +125 -0
- package/dist/plugins/sendgrid/src/index.js +187 -0
- package/dist/plugins/sendy/src/index.js +138 -0
- package/dist/plugins/sentry/src/index.js +233 -0
- package/dist/plugins/servicenow/src/index.js +108 -0
- package/dist/plugins/shopify/src/index.js +222 -0
- package/dist/plugins/signl4/src/index.js +61 -0
- package/dist/plugins/slack/src/index.js +236 -0
- package/dist/plugins/sms77/src/index.js +63 -0
- package/dist/plugins/splunk/src/index.js +207 -0
- package/dist/plugins/spotify/src/index.js +188 -0
- package/dist/plugins/stackby/src/index.js +82 -0
- package/dist/plugins/storyblok/src/index.js +141 -0
- package/dist/plugins/strapi/src/index.js +152 -0
- package/dist/plugins/strava/src/index.js +137 -0
- package/dist/plugins/stripe/src/index.js +222 -0
- package/dist/plugins/supabase/src/index.js +121 -0
- package/dist/plugins/syncromsp/src/index.js +255 -0
- package/dist/plugins/tapfiliate/src/index.js +125 -0
- package/dist/plugins/telegram/src/index.js +233 -0
- package/dist/plugins/thehive/src/index.js +142 -0
- package/dist/plugins/thehiveProject/src/index.js +194 -0
- package/dist/plugins/todoist/src/index.js +244 -0
- package/dist/plugins/travisci/src/index.js +71 -0
- package/dist/plugins/trello/src/index.js +341 -0
- package/dist/plugins/twake/src/index.js +40 -0
- package/dist/plugins/twilio/src/index.js +75 -0
- package/dist/plugins/twist/src/index.js +90 -0
- package/dist/plugins/twitter/src/index.js +123 -0
- package/dist/plugins/unleashedSoftware/src/index.js +84 -0
- package/dist/plugins/uplead/src/index.js +59 -0
- package/dist/plugins/uproc/src/index.js +34 -0
- package/dist/plugins/uptimerobot/src/index.js +264 -0
- package/dist/plugins/urlscanio/src/index.js +64 -0
- package/dist/plugins/vero/src/index.js +80 -0
- package/dist/plugins/vonage/src/index.js +42 -0
- package/dist/plugins/wekan/src/index.js +91 -0
- package/dist/plugins/woocommerce/src/index.js +92 -0
- package/dist/plugins/wordpress/src/index.js +121 -0
- package/dist/plugins/xero/src/index.js +136 -0
- package/dist/plugins/yourls/src/index.js +56 -0
- package/dist/plugins/zammad/src/index.js +91 -0
- package/dist/plugins/zendesk/src/index.js +137 -0
- package/dist/plugins/zoho/src/index.js +85 -0
- package/dist/plugins/zoom/src/index.js +122 -0
- package/dist/plugins/zulip/src/index.js +170 -0
- package/dist/sdk.d.ts +38 -0
- package/dist/sdk.js +105 -0
- package/dist/utils/cli.d.ts +13 -0
- package/dist/utils/cli.js +32 -0
- package/dist/utils/output.d.ts +4 -0
- package/dist/utils/output.js +13 -0
- package/package.json +57 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
const BASE = "https://api.pagerduty.com";
|
|
2
|
+
function getToken(ctx) { return ctx.connection.config.apiToken; }
|
|
3
|
+
async function apiRequest(token, method, endpoint, body, qs, extraHeaders) {
|
|
4
|
+
const url = new URL(`${BASE}${endpoint}`);
|
|
5
|
+
if (qs) {
|
|
6
|
+
for (const [k, v] of Object.entries(qs)) {
|
|
7
|
+
if (v !== undefined && v !== null)
|
|
8
|
+
url.searchParams.set(k, String(v));
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const headers = {
|
|
12
|
+
Authorization: `Token token=${token}`,
|
|
13
|
+
Accept: "application/vnd.pagerduty+json;version=2",
|
|
14
|
+
"Content-Type": "application/json",
|
|
15
|
+
...extraHeaders,
|
|
16
|
+
};
|
|
17
|
+
const init = { method, headers };
|
|
18
|
+
if (body && Object.keys(body).length > 0)
|
|
19
|
+
init.body = JSON.stringify(body);
|
|
20
|
+
const res = await fetch(url.toString(), init);
|
|
21
|
+
if (!res.ok)
|
|
22
|
+
throw new Error(`PagerDuty API error ${res.status}: ${await res.text()}`);
|
|
23
|
+
const text = await res.text();
|
|
24
|
+
return text ? JSON.parse(text) : {};
|
|
25
|
+
}
|
|
26
|
+
async function paginate(token, endpoint, propertyName, qs = {}) {
|
|
27
|
+
const all = [];
|
|
28
|
+
qs.limit = 100;
|
|
29
|
+
qs.offset = 0;
|
|
30
|
+
let hasMore = true;
|
|
31
|
+
while (hasMore) {
|
|
32
|
+
const data = (await apiRequest(token, "GET", endpoint, undefined, qs));
|
|
33
|
+
const items = (data[propertyName] ?? []);
|
|
34
|
+
all.push(...items);
|
|
35
|
+
hasMore = data.more === true;
|
|
36
|
+
qs.offset = qs.offset + qs.limit;
|
|
37
|
+
}
|
|
38
|
+
return all;
|
|
39
|
+
}
|
|
40
|
+
export default function pagerduty(rl) {
|
|
41
|
+
rl.setName("pagerduty");
|
|
42
|
+
rl.setVersion("0.1.0");
|
|
43
|
+
rl.setConnectionSchema({
|
|
44
|
+
apiToken: { type: "string", required: true, description: "PagerDuty API token", env: "PAGERDUTY_API_TOKEN" },
|
|
45
|
+
});
|
|
46
|
+
// ── Incident ────────────────────────────────────────
|
|
47
|
+
rl.registerAction("incident.create", {
|
|
48
|
+
description: "Create a new incident",
|
|
49
|
+
inputSchema: {
|
|
50
|
+
title: { type: "string", required: true },
|
|
51
|
+
serviceId: { type: "string", required: true, description: "Service ID" },
|
|
52
|
+
from: { type: "string", required: true, description: "Email of the user creating the incident" },
|
|
53
|
+
urgency: { type: "string", required: false, description: "high or low" },
|
|
54
|
+
details: { type: "string", required: false, description: "Incident body details" },
|
|
55
|
+
priorityId: { type: "string", required: false },
|
|
56
|
+
escalationPolicyId: { type: "string", required: false },
|
|
57
|
+
incidentKey: { type: "string", required: false },
|
|
58
|
+
},
|
|
59
|
+
async execute(input, ctx) {
|
|
60
|
+
const p = input;
|
|
61
|
+
const incident = {
|
|
62
|
+
type: "incident", title: p.title,
|
|
63
|
+
service: { id: p.serviceId, type: "service_reference" },
|
|
64
|
+
};
|
|
65
|
+
if (p.urgency)
|
|
66
|
+
incident.urgency = p.urgency;
|
|
67
|
+
if (p.details)
|
|
68
|
+
incident.body = { type: "incident_body", details: p.details };
|
|
69
|
+
if (p.priorityId)
|
|
70
|
+
incident.priority = { id: p.priorityId, type: "priority_reference" };
|
|
71
|
+
if (p.escalationPolicyId)
|
|
72
|
+
incident.escalation_policy = { id: p.escalationPolicyId, type: "escalation_policy_reference" };
|
|
73
|
+
if (p.incidentKey)
|
|
74
|
+
incident.incident_key = p.incidentKey;
|
|
75
|
+
const data = (await apiRequest(getToken(ctx), "POST", "/incidents", { incident }, undefined, { From: p.from }));
|
|
76
|
+
return data.incident;
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
rl.registerAction("incident.get", {
|
|
80
|
+
description: "Get an incident by ID",
|
|
81
|
+
inputSchema: { incidentId: { type: "string", required: true } },
|
|
82
|
+
async execute(input, ctx) {
|
|
83
|
+
const { incidentId } = input;
|
|
84
|
+
const data = (await apiRequest(getToken(ctx), "GET", `/incidents/${incidentId}`));
|
|
85
|
+
return data.incident;
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
rl.registerAction("incident.list", {
|
|
89
|
+
description: "List incidents",
|
|
90
|
+
inputSchema: {
|
|
91
|
+
limit: { type: "number", required: false },
|
|
92
|
+
statuses: { type: "string", required: false, description: "Comma-separated: triggered,acknowledged,resolved" },
|
|
93
|
+
sortBy: { type: "string", required: false },
|
|
94
|
+
},
|
|
95
|
+
async execute(input, ctx) {
|
|
96
|
+
const p = (input ?? {});
|
|
97
|
+
const qs = {};
|
|
98
|
+
if (p.statuses)
|
|
99
|
+
qs["statuses[]"] = p.statuses;
|
|
100
|
+
if (p.sortBy)
|
|
101
|
+
qs.sort_by = p.sortBy;
|
|
102
|
+
if (p.limit) {
|
|
103
|
+
qs.limit = p.limit;
|
|
104
|
+
const d = (await apiRequest(getToken(ctx), "GET", "/incidents", undefined, qs));
|
|
105
|
+
return d.incidents;
|
|
106
|
+
}
|
|
107
|
+
return paginate(getToken(ctx), "/incidents", "incidents", qs);
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
rl.registerAction("incident.update", {
|
|
111
|
+
description: "Update an incident",
|
|
112
|
+
inputSchema: {
|
|
113
|
+
incidentId: { type: "string", required: true },
|
|
114
|
+
from: { type: "string", required: true, description: "Email of the user updating" },
|
|
115
|
+
title: { type: "string", required: false },
|
|
116
|
+
status: { type: "string", required: false, description: "acknowledged, resolved" },
|
|
117
|
+
urgency: { type: "string", required: false },
|
|
118
|
+
resolution: { type: "string", required: false },
|
|
119
|
+
escalationLevel: { type: "number", required: false },
|
|
120
|
+
priorityId: { type: "string", required: false },
|
|
121
|
+
escalationPolicyId: { type: "string", required: false },
|
|
122
|
+
},
|
|
123
|
+
async execute(input, ctx) {
|
|
124
|
+
const p = input;
|
|
125
|
+
const incident = { type: "incident" };
|
|
126
|
+
if (p.title)
|
|
127
|
+
incident.title = p.title;
|
|
128
|
+
if (p.status)
|
|
129
|
+
incident.status = p.status;
|
|
130
|
+
if (p.urgency)
|
|
131
|
+
incident.urgency = p.urgency;
|
|
132
|
+
if (p.resolution)
|
|
133
|
+
incident.resolution = p.resolution;
|
|
134
|
+
if (p.escalationLevel)
|
|
135
|
+
incident.escalation_level = p.escalationLevel;
|
|
136
|
+
if (p.priorityId)
|
|
137
|
+
incident.priority = { id: p.priorityId, type: "priority_reference" };
|
|
138
|
+
if (p.escalationPolicyId)
|
|
139
|
+
incident.escalation_policy = { id: p.escalationPolicyId, type: "escalation_policy_reference" };
|
|
140
|
+
const data = (await apiRequest(getToken(ctx), "PUT", `/incidents/${p.incidentId}`, { incident }, undefined, { From: p.from }));
|
|
141
|
+
return data.incident;
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
// ── Incident Note ───────────────────────────────────
|
|
145
|
+
rl.registerAction("incidentNote.create", {
|
|
146
|
+
description: "Add a note to an incident",
|
|
147
|
+
inputSchema: {
|
|
148
|
+
incidentId: { type: "string", required: true },
|
|
149
|
+
from: { type: "string", required: true, description: "Email of the user" },
|
|
150
|
+
content: { type: "string", required: true },
|
|
151
|
+
},
|
|
152
|
+
async execute(input, ctx) {
|
|
153
|
+
const { incidentId, from, content } = input;
|
|
154
|
+
return apiRequest(getToken(ctx), "POST", `/incidents/${incidentId}/notes`, { note: { content } }, undefined, { From: from });
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
rl.registerAction("incidentNote.list", {
|
|
158
|
+
description: "List notes for an incident",
|
|
159
|
+
inputSchema: { incidentId: { type: "string", required: true }, limit: { type: "number", required: false } },
|
|
160
|
+
async execute(input, ctx) {
|
|
161
|
+
const p = input;
|
|
162
|
+
const qs = {};
|
|
163
|
+
if (p.limit)
|
|
164
|
+
qs.limit = p.limit;
|
|
165
|
+
const data = (await apiRequest(getToken(ctx), "GET", `/incidents/${p.incidentId}/notes`, undefined, qs));
|
|
166
|
+
return data.notes;
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
// ── Log Entry ───────────────────────────────────────
|
|
170
|
+
rl.registerAction("logEntry.get", {
|
|
171
|
+
description: "Get a log entry by ID",
|
|
172
|
+
inputSchema: { logEntryId: { type: "string", required: true } },
|
|
173
|
+
async execute(input, ctx) {
|
|
174
|
+
const { logEntryId } = input;
|
|
175
|
+
const data = (await apiRequest(getToken(ctx), "GET", `/log_entries/${logEntryId}`));
|
|
176
|
+
return data.log_entry;
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
rl.registerAction("logEntry.list", {
|
|
180
|
+
description: "List log entries",
|
|
181
|
+
inputSchema: { limit: { type: "number", required: false } },
|
|
182
|
+
async execute(input, ctx) {
|
|
183
|
+
const p = (input ?? {});
|
|
184
|
+
if (p.limit) {
|
|
185
|
+
const data = (await apiRequest(getToken(ctx), "GET", "/log_entries", undefined, { limit: p.limit }));
|
|
186
|
+
return data.log_entries;
|
|
187
|
+
}
|
|
188
|
+
return paginate(getToken(ctx), "/log_entries", "log_entries");
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
// ── User ────────────────────────────────────────────
|
|
192
|
+
rl.registerAction("user.get", {
|
|
193
|
+
description: "Get a user by ID",
|
|
194
|
+
inputSchema: { userId: { type: "string", required: true } },
|
|
195
|
+
async execute(input, ctx) {
|
|
196
|
+
const { userId } = input;
|
|
197
|
+
const data = (await apiRequest(getToken(ctx), "GET", `/users/${userId}`));
|
|
198
|
+
return data.user;
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
let cachedToken = null;
|
|
2
|
+
function getConn(ctx) {
|
|
3
|
+
const c = ctx.connection.config;
|
|
4
|
+
const env = c.env ?? "sandbox";
|
|
5
|
+
const base = env === "live" ? "https://api-m.paypal.com" : "https://api-m.sandbox.paypal.com";
|
|
6
|
+
return { base, clientId: c.clientId, secret: c.secret };
|
|
7
|
+
}
|
|
8
|
+
async function getAccessToken(conn) {
|
|
9
|
+
if (cachedToken && Date.now() < cachedToken.expiresAt)
|
|
10
|
+
return cachedToken.token;
|
|
11
|
+
const res = await fetch(`${conn.base}/v1/oauth2/token`, {
|
|
12
|
+
method: "POST",
|
|
13
|
+
headers: {
|
|
14
|
+
Authorization: "Basic " + btoa(`${conn.clientId}:${conn.secret}`),
|
|
15
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
16
|
+
},
|
|
17
|
+
body: "grant_type=client_credentials",
|
|
18
|
+
});
|
|
19
|
+
if (!res.ok)
|
|
20
|
+
throw new Error(`PayPal auth error ${res.status}: ${await res.text()}`);
|
|
21
|
+
const data = (await res.json());
|
|
22
|
+
cachedToken = { token: data.access_token, expiresAt: Date.now() + (data.expires_in - 60) * 1000 };
|
|
23
|
+
return cachedToken.token;
|
|
24
|
+
}
|
|
25
|
+
async function apiRequest(conn, method, endpoint, body, qs) {
|
|
26
|
+
const token = await getAccessToken(conn);
|
|
27
|
+
const url = new URL(`${conn.base}/v1${endpoint}`);
|
|
28
|
+
if (qs) {
|
|
29
|
+
for (const [k, v] of Object.entries(qs)) {
|
|
30
|
+
if (v !== undefined && v !== null)
|
|
31
|
+
url.searchParams.set(k, String(v));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const init = {
|
|
35
|
+
method,
|
|
36
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
37
|
+
};
|
|
38
|
+
if (body !== undefined)
|
|
39
|
+
init.body = JSON.stringify(body);
|
|
40
|
+
const res = await fetch(url.toString(), init);
|
|
41
|
+
if (!res.ok)
|
|
42
|
+
throw new Error(`PayPal API error ${res.status}: ${await res.text()}`);
|
|
43
|
+
const text = await res.text();
|
|
44
|
+
return text ? JSON.parse(text) : {};
|
|
45
|
+
}
|
|
46
|
+
export default function paypal(rl) {
|
|
47
|
+
rl.setName("paypal");
|
|
48
|
+
rl.setVersion("0.1.0");
|
|
49
|
+
rl.setConnectionSchema({
|
|
50
|
+
clientId: { type: "string", required: true, description: "PayPal client ID", env: "PAYPAL_CLIENT_ID" },
|
|
51
|
+
secret: { type: "string", required: true, description: "PayPal secret", env: "PAYPAL_SECRET" },
|
|
52
|
+
env: { type: "string", required: false, description: "live or sandbox (default sandbox)", env: "PAYPAL_ENV" },
|
|
53
|
+
});
|
|
54
|
+
rl.registerAction("payout.create", {
|
|
55
|
+
description: "Create a batch payout",
|
|
56
|
+
inputSchema: {
|
|
57
|
+
senderBatchId: { type: "string", required: true, description: "Unique batch ID" },
|
|
58
|
+
items: { type: "object", required: true, description: "Array of payout items [{receiver, amount: {value, currency}, recipient_type, note}]" },
|
|
59
|
+
emailSubject: { type: "string", required: false },
|
|
60
|
+
emailMessage: { type: "string", required: false },
|
|
61
|
+
note: { type: "string", required: false },
|
|
62
|
+
},
|
|
63
|
+
async execute(input, ctx) {
|
|
64
|
+
const p = input;
|
|
65
|
+
const header = { sender_batch_id: p.senderBatchId };
|
|
66
|
+
if (p.emailSubject)
|
|
67
|
+
header.email_subject = p.emailSubject;
|
|
68
|
+
if (p.emailMessage)
|
|
69
|
+
header.email_message = p.emailMessage;
|
|
70
|
+
if (p.note)
|
|
71
|
+
header.note = p.note;
|
|
72
|
+
return apiRequest(getConn(ctx), "POST", "/payments/payouts", { sender_batch_header: header, items: p.items });
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
rl.registerAction("payout.get", {
|
|
76
|
+
description: "Get a batch payout by ID (returns items)",
|
|
77
|
+
inputSchema: {
|
|
78
|
+
payoutBatchId: { type: "string", required: true },
|
|
79
|
+
limit: { type: "number", required: false, description: "Max items to return" },
|
|
80
|
+
},
|
|
81
|
+
async execute(input, ctx) {
|
|
82
|
+
const p = input;
|
|
83
|
+
const qs = {};
|
|
84
|
+
if (p.limit)
|
|
85
|
+
qs.page_size = p.limit;
|
|
86
|
+
const data = (await apiRequest(getConn(ctx), "GET", `/payments/payouts/${p.payoutBatchId}`, undefined, qs));
|
|
87
|
+
return data.items;
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
rl.registerAction("payoutItem.get", {
|
|
91
|
+
description: "Get a payout item by ID",
|
|
92
|
+
inputSchema: { payoutItemId: { type: "string", required: true } },
|
|
93
|
+
async execute(input, ctx) {
|
|
94
|
+
const { payoutItemId } = input;
|
|
95
|
+
return apiRequest(getConn(ctx), "GET", `/payments/payouts-item/${payoutItemId}`);
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
rl.registerAction("payoutItem.cancel", {
|
|
99
|
+
description: "Cancel an unclaimed payout item",
|
|
100
|
+
inputSchema: { payoutItemId: { type: "string", required: true } },
|
|
101
|
+
async execute(input, ctx) {
|
|
102
|
+
const { payoutItemId } = input;
|
|
103
|
+
return apiRequest(getConn(ctx), "POST", `/payments/payouts-item/${payoutItemId}/cancel`);
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const BASE = "https://api.peekalink.io";
|
|
2
|
+
async function apiRequest(apiKey, endpoint, body) {
|
|
3
|
+
const res = await fetch(`${BASE}${endpoint}`, {
|
|
4
|
+
method: "POST",
|
|
5
|
+
headers: { "X-API-Key": apiKey, "Content-Type": "application/json" },
|
|
6
|
+
body: JSON.stringify(body),
|
|
7
|
+
});
|
|
8
|
+
if (!res.ok)
|
|
9
|
+
throw new Error(`Peekalink error ${res.status}: ${await res.text()}`);
|
|
10
|
+
return res.json();
|
|
11
|
+
}
|
|
12
|
+
export default function peekalink(rl) {
|
|
13
|
+
rl.setName("peekalink");
|
|
14
|
+
rl.setVersion("0.1.0");
|
|
15
|
+
rl.setConnectionSchema({
|
|
16
|
+
apiKey: { type: "string", required: true, description: "Peekalink API key", env: "PEEKALINK_API_KEY" },
|
|
17
|
+
});
|
|
18
|
+
const key = (ctx) => ctx.connection.config.apiKey;
|
|
19
|
+
rl.registerAction("link.preview", {
|
|
20
|
+
description: "Get a rich preview for a URL",
|
|
21
|
+
inputSchema: { url: { type: "string", required: true, description: "URL to preview" } },
|
|
22
|
+
async execute(input, ctx) {
|
|
23
|
+
const { url } = input;
|
|
24
|
+
return apiRequest(key(ctx), "", { link: url });
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
rl.registerAction("link.isAvailable", {
|
|
28
|
+
description: "Check whether a preview is available for a URL",
|
|
29
|
+
inputSchema: { url: { type: "string", required: true, description: "URL to check" } },
|
|
30
|
+
async execute(input, ctx) {
|
|
31
|
+
const { url } = input;
|
|
32
|
+
return apiRequest(key(ctx), "/is-available/", { link: url });
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const BASE = "https://api.phantombuster.com/api/v2";
|
|
2
|
+
async function apiRequest(apiKey, method, path, body, qs) {
|
|
3
|
+
const url = new URL(`${BASE}${path}`);
|
|
4
|
+
if (qs) {
|
|
5
|
+
for (const [k, v] of Object.entries(qs)) {
|
|
6
|
+
if (v !== undefined && v !== null)
|
|
7
|
+
url.searchParams.set(k, String(v));
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
const init = { method, headers: { "X-Phantombuster-Key": apiKey, "Content-Type": "application/json" } };
|
|
11
|
+
if (body && Object.keys(body).length > 0)
|
|
12
|
+
init.body = JSON.stringify(body);
|
|
13
|
+
const res = await fetch(url.toString(), init);
|
|
14
|
+
if (!res.ok)
|
|
15
|
+
throw new Error(`Phantombuster error ${res.status}: ${await res.text()}`);
|
|
16
|
+
const text = await res.text();
|
|
17
|
+
return text ? JSON.parse(text) : {};
|
|
18
|
+
}
|
|
19
|
+
export default function phantombuster(rl) {
|
|
20
|
+
rl.setName("phantombuster");
|
|
21
|
+
rl.setVersion("0.1.0");
|
|
22
|
+
rl.setConnectionSchema({
|
|
23
|
+
apiKey: { type: "string", required: true, description: "Phantombuster API key", env: "PHANTOMBUSTER_API_KEY" },
|
|
24
|
+
});
|
|
25
|
+
const key = (ctx) => ctx.connection.config.apiKey;
|
|
26
|
+
rl.registerAction("agent.delete", {
|
|
27
|
+
description: "Delete an agent",
|
|
28
|
+
inputSchema: { agentId: { type: "string", required: true } },
|
|
29
|
+
async execute(input, ctx) {
|
|
30
|
+
const { agentId } = input;
|
|
31
|
+
await apiRequest(key(ctx), "POST", "/agents/delete", { id: agentId });
|
|
32
|
+
return { success: true };
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
rl.registerAction("agent.get", {
|
|
36
|
+
description: "Get agent details",
|
|
37
|
+
inputSchema: { agentId: { type: "string", required: true } },
|
|
38
|
+
async execute(input, ctx) {
|
|
39
|
+
const { agentId } = input;
|
|
40
|
+
return apiRequest(key(ctx), "GET", "/agents/fetch", undefined, { id: agentId });
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
rl.registerAction("agent.getOutput", {
|
|
44
|
+
description: "Get the output of the last agent run",
|
|
45
|
+
inputSchema: {
|
|
46
|
+
agentId: { type: "string", required: true },
|
|
47
|
+
resolveData: { type: "boolean", required: false, description: "Resolve the result object (default false)" },
|
|
48
|
+
},
|
|
49
|
+
async execute(input, ctx) {
|
|
50
|
+
const p = input;
|
|
51
|
+
const data = (await apiRequest(key(ctx), "GET", "/agents/fetch-output", undefined, { id: p.agentId }));
|
|
52
|
+
if (p.resolveData) {
|
|
53
|
+
const result = (await apiRequest(key(ctx), "GET", "/containers/fetch-result-object", undefined, { id: data.containerId }));
|
|
54
|
+
if (!result.resultObject)
|
|
55
|
+
return {};
|
|
56
|
+
return JSON.parse(result.resultObject);
|
|
57
|
+
}
|
|
58
|
+
return data;
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
rl.registerAction("agent.list", {
|
|
62
|
+
description: "List all agents",
|
|
63
|
+
inputSchema: { limit: { type: "number", required: false } },
|
|
64
|
+
async execute(input, ctx) {
|
|
65
|
+
const agents = (await apiRequest(key(ctx), "GET", "/agents/fetch-all"));
|
|
66
|
+
const limit = input?.limit;
|
|
67
|
+
if (limit)
|
|
68
|
+
return agents.slice(0, limit);
|
|
69
|
+
return agents;
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
rl.registerAction("agent.launch", {
|
|
73
|
+
description: "Launch an agent",
|
|
74
|
+
inputSchema: {
|
|
75
|
+
agentId: { type: "string", required: true },
|
|
76
|
+
arguments: { type: "object", required: false, description: "Arguments object to pass to the agent" },
|
|
77
|
+
bonusArgument: { type: "object", required: false, description: "Bonus argument object" },
|
|
78
|
+
resolveData: { type: "boolean", required: false, description: "Wait and return the container data (default false)" },
|
|
79
|
+
},
|
|
80
|
+
async execute(input, ctx) {
|
|
81
|
+
const p = input;
|
|
82
|
+
const body = { id: p.agentId };
|
|
83
|
+
if (p.arguments)
|
|
84
|
+
body.arguments = p.arguments;
|
|
85
|
+
if (p.bonusArgument)
|
|
86
|
+
body.bonusArgument = p.bonusArgument;
|
|
87
|
+
const data = (await apiRequest(key(ctx), "POST", "/agents/launch", body));
|
|
88
|
+
if (p.resolveData) {
|
|
89
|
+
return apiRequest(key(ctx), "GET", "/containers/fetch", undefined, { id: data.containerId });
|
|
90
|
+
}
|
|
91
|
+
return data;
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const BASE = "https://api.meethue.com/route";
|
|
2
|
+
async function apiRequest(accessToken, method, path, body) {
|
|
3
|
+
const init = {
|
|
4
|
+
method,
|
|
5
|
+
headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" },
|
|
6
|
+
};
|
|
7
|
+
if (body && Object.keys(body).length > 0)
|
|
8
|
+
init.body = JSON.stringify(body);
|
|
9
|
+
const res = await fetch(`${BASE}${path}`, init);
|
|
10
|
+
if (!res.ok)
|
|
11
|
+
throw new Error(`Philips Hue error ${res.status}: ${await res.text()}`);
|
|
12
|
+
return res.json();
|
|
13
|
+
}
|
|
14
|
+
export default function philipsHue(rl) {
|
|
15
|
+
rl.setName("philipsHue");
|
|
16
|
+
rl.setVersion("0.1.0");
|
|
17
|
+
rl.setConnectionSchema({
|
|
18
|
+
accessToken: { type: "string", required: true, description: "Philips Hue OAuth2 access token", env: "PHILIPS_HUE_ACCESS_TOKEN" },
|
|
19
|
+
username: { type: "string", required: true, description: "Bridge username (whitelisted user ID)", env: "PHILIPS_HUE_USERNAME" },
|
|
20
|
+
});
|
|
21
|
+
function conn(ctx) {
|
|
22
|
+
return { token: ctx.connection.config.accessToken, user: ctx.connection.config.username };
|
|
23
|
+
}
|
|
24
|
+
rl.registerAction("light.get", {
|
|
25
|
+
description: "Get a light by ID",
|
|
26
|
+
inputSchema: { lightId: { type: "string", required: true } },
|
|
27
|
+
async execute(input, ctx) {
|
|
28
|
+
const { lightId } = input;
|
|
29
|
+
const c = conn(ctx);
|
|
30
|
+
return apiRequest(c.token, "GET", `/api/${c.user}/lights/${lightId}`);
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
rl.registerAction("light.list", {
|
|
34
|
+
description: "List all lights",
|
|
35
|
+
inputSchema: { limit: { type: "number", required: false } },
|
|
36
|
+
async execute(input, ctx) {
|
|
37
|
+
const c = conn(ctx);
|
|
38
|
+
const data = (await apiRequest(c.token, "GET", `/api/${c.user}/lights`));
|
|
39
|
+
const lights = Object.entries(data).map(([id, v]) => ({ id, ...v }));
|
|
40
|
+
const limit = input?.limit;
|
|
41
|
+
if (limit)
|
|
42
|
+
return lights.slice(0, limit);
|
|
43
|
+
return lights;
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
rl.registerAction("light.update", {
|
|
47
|
+
description: "Update a light's state (on/off, brightness, color, etc.)",
|
|
48
|
+
inputSchema: {
|
|
49
|
+
lightId: { type: "string", required: true },
|
|
50
|
+
on: { type: "boolean", required: true, description: "Turn light on or off" },
|
|
51
|
+
bri: { type: "number", required: false, description: "Brightness (1-254)" },
|
|
52
|
+
hue: { type: "number", required: false, description: "Hue (0-65535)" },
|
|
53
|
+
sat: { type: "number", required: false, description: "Saturation (0-254)" },
|
|
54
|
+
ct: { type: "number", required: false, description: "Color temperature (153-500 mirek)" },
|
|
55
|
+
xy: { type: "string", required: false, description: "CIE color as 'x,y' (e.g. 0.5,0.5)" },
|
|
56
|
+
transitiontime: { type: "number", required: false, description: "Transition time in seconds" },
|
|
57
|
+
alert: { type: "string", required: false, description: "none, select, or lselect" },
|
|
58
|
+
effect: { type: "string", required: false, description: "none or colorloop" },
|
|
59
|
+
},
|
|
60
|
+
async execute(input, ctx) {
|
|
61
|
+
const p = input;
|
|
62
|
+
const c = conn(ctx);
|
|
63
|
+
const body = { on: p.on };
|
|
64
|
+
if (p.bri !== undefined)
|
|
65
|
+
body.bri = p.bri;
|
|
66
|
+
if (p.hue !== undefined)
|
|
67
|
+
body.hue = p.hue;
|
|
68
|
+
if (p.sat !== undefined)
|
|
69
|
+
body.sat = p.sat;
|
|
70
|
+
if (p.ct !== undefined)
|
|
71
|
+
body.ct = p.ct;
|
|
72
|
+
if (p.xy)
|
|
73
|
+
body.xy = p.xy.split(",").map(Number);
|
|
74
|
+
if (p.transitiontime !== undefined)
|
|
75
|
+
body.transitiontime = p.transitiontime * 100;
|
|
76
|
+
if (p.alert)
|
|
77
|
+
body.alert = p.alert;
|
|
78
|
+
if (p.effect)
|
|
79
|
+
body.effect = p.effect;
|
|
80
|
+
const data = (await apiRequest(c.token, "PUT", `/api/${c.user}/lights/${p.lightId}/state`, body));
|
|
81
|
+
const result = {};
|
|
82
|
+
for (const item of data) {
|
|
83
|
+
if (item.success)
|
|
84
|
+
Object.assign(result, item.success);
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
rl.registerAction("light.delete", {
|
|
90
|
+
description: "Delete a light from the bridge",
|
|
91
|
+
inputSchema: { lightId: { type: "string", required: true } },
|
|
92
|
+
async execute(input, ctx) {
|
|
93
|
+
const { lightId } = input;
|
|
94
|
+
const c = conn(ctx);
|
|
95
|
+
return apiRequest(c.token, "DELETE", `/api/${c.user}/lights/${lightId}`);
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
}
|