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.
Files changed (230) hide show
  1. package/.pi/extensions/runline-context/index.ts +135 -0
  2. package/.pi/extensions/runline-context/package.json +17 -0
  3. package/README.md +273 -0
  4. package/dist/commands/actions.d.ts +3 -0
  5. package/dist/commands/actions.js +43 -0
  6. package/dist/commands/connection.d.ts +11 -0
  7. package/dist/commands/connection.js +56 -0
  8. package/dist/commands/exec.d.ts +5 -0
  9. package/dist/commands/exec.js +46 -0
  10. package/dist/commands/init.d.ts +4 -0
  11. package/dist/commands/init.js +26 -0
  12. package/dist/commands/plugin.d.ts +10 -0
  13. package/dist/commands/plugin.js +57 -0
  14. package/dist/config/index.d.ts +3 -0
  15. package/dist/config/index.js +2 -0
  16. package/dist/config/loader.d.ts +11 -0
  17. package/dist/config/loader.js +82 -0
  18. package/dist/config/types.d.ts +9 -0
  19. package/dist/config/types.js +5 -0
  20. package/dist/core/engine.d.ts +21 -0
  21. package/dist/core/engine.js +280 -0
  22. package/dist/index.d.ts +16 -0
  23. package/dist/index.js +9 -0
  24. package/dist/main.d.ts +2 -0
  25. package/dist/main.js +127 -0
  26. package/dist/plugin/api.d.ts +32 -0
  27. package/dist/plugin/api.js +68 -0
  28. package/dist/plugin/installer.d.ts +27 -0
  29. package/dist/plugin/installer.js +181 -0
  30. package/dist/plugin/loader.d.ts +13 -0
  31. package/dist/plugin/loader.js +164 -0
  32. package/dist/plugin/registry.d.ts +18 -0
  33. package/dist/plugin/registry.js +43 -0
  34. package/dist/plugin/types.d.ts +40 -0
  35. package/dist/plugin/types.js +1 -0
  36. package/dist/plugins/actionNetwork/src/index.js +353 -0
  37. package/dist/plugins/activeCampaign/src/index.js +711 -0
  38. package/dist/plugins/adalo/src/index.js +131 -0
  39. package/dist/plugins/affinity/src/index.js +279 -0
  40. package/dist/plugins/agileCrm/src/index.js +415 -0
  41. package/dist/plugins/airtable/src/index.js +280 -0
  42. package/dist/plugins/airtop/src/index.js +527 -0
  43. package/dist/plugins/apiTemplateIo/src/index.js +86 -0
  44. package/dist/plugins/asana/src/index.js +413 -0
  45. package/dist/plugins/autopilot/src/index.js +203 -0
  46. package/dist/plugins/bambooHr/src/index.js +252 -0
  47. package/dist/plugins/bannerbear/src/index.js +100 -0
  48. package/dist/plugins/baserow/src/index.js +180 -0
  49. package/dist/plugins/beeminder/src/index.js +298 -0
  50. package/dist/plugins/bitly/src/index.js +107 -0
  51. package/dist/plugins/bitwarden/src/index.js +383 -0
  52. package/dist/plugins/box/src/index.js +300 -0
  53. package/dist/plugins/brandfetch/src/index.js +80 -0
  54. package/dist/plugins/brevo/src/index.js +305 -0
  55. package/dist/plugins/bubble/src/index.js +181 -0
  56. package/dist/plugins/chargebee/src/index.js +126 -0
  57. package/dist/plugins/circleci/src/index.js +111 -0
  58. package/dist/plugins/ciscoWebex/src/index.js +245 -0
  59. package/dist/plugins/clearbit/src/index.js +103 -0
  60. package/dist/plugins/clickup/src/index.js +1043 -0
  61. package/dist/plugins/clockify/src/index.js +443 -0
  62. package/dist/plugins/cloudflare/src/index.js +93 -0
  63. package/dist/plugins/cockpit/src/index.js +131 -0
  64. package/dist/plugins/coda/src/index.js +327 -0
  65. package/dist/plugins/coingecko/src/index.js +244 -0
  66. package/dist/plugins/contentful/src/index.js +146 -0
  67. package/dist/plugins/convertkit/src/index.js +270 -0
  68. package/dist/plugins/copper/src/index.js +140 -0
  69. package/dist/plugins/cortex/src/index.js +147 -0
  70. package/dist/plugins/currents/src/index.js +405 -0
  71. package/dist/plugins/customerIo/src/index.js +184 -0
  72. package/dist/plugins/databricks/src/index.js +342 -0
  73. package/dist/plugins/deepl/src/index.js +87 -0
  74. package/dist/plugins/demio/src/index.js +111 -0
  75. package/dist/plugins/dhl/src/index.js +40 -0
  76. package/dist/plugins/discord/src/index.js +275 -0
  77. package/dist/plugins/discourse/src/index.js +273 -0
  78. package/dist/plugins/disqus/src/index.js +145 -0
  79. package/dist/plugins/docker/src/index.js +76 -0
  80. package/dist/plugins/drift/src/index.js +89 -0
  81. package/dist/plugins/dropbox/src/index.js +159 -0
  82. package/dist/plugins/dropcontact/src/index.js +59 -0
  83. package/dist/plugins/egoi/src/index.js +151 -0
  84. package/dist/plugins/elasticsearch/src/index.js +157 -0
  85. package/dist/plugins/emelia/src/index.js +174 -0
  86. package/dist/plugins/erpnext/src/index.js +121 -0
  87. package/dist/plugins/facebookGraph/src/index.js +57 -0
  88. package/dist/plugins/freshdesk/src/index.js +320 -0
  89. package/dist/plugins/freshservice/src/index.js +146 -0
  90. package/dist/plugins/freshworksCrm/src/index.js +149 -0
  91. package/dist/plugins/getresponse/src/index.js +140 -0
  92. package/dist/plugins/ghost/src/index.js +192 -0
  93. package/dist/plugins/github/src/index.js +630 -0
  94. package/dist/plugins/gitlab/src/index.js +358 -0
  95. package/dist/plugins/gong/src/index.js +126 -0
  96. package/dist/plugins/gotify/src/index.js +77 -0
  97. package/dist/plugins/gotowebinar/src/index.js +316 -0
  98. package/dist/plugins/grafana/src/index.js +250 -0
  99. package/dist/plugins/graphql/src/index.js +78 -0
  100. package/dist/plugins/grist/src/index.js +106 -0
  101. package/dist/plugins/hackernews/src/index.js +89 -0
  102. package/dist/plugins/halopsa/src/index.js +79 -0
  103. package/dist/plugins/harvest/src/index.js +163 -0
  104. package/dist/plugins/helpscout/src/index.js +176 -0
  105. package/dist/plugins/highlevel/src/index.js +172 -0
  106. package/dist/plugins/homeAssistant/src/index.js +148 -0
  107. package/dist/plugins/hubspot/src/index.js +176 -0
  108. package/dist/plugins/humanticAi/src/index.js +60 -0
  109. package/dist/plugins/hunter/src/index.js +59 -0
  110. package/dist/plugins/intercom/src/index.js +156 -0
  111. package/dist/plugins/iterable/src/index.js +139 -0
  112. package/dist/plugins/jenkins/src/index.js +132 -0
  113. package/dist/plugins/jira/src/index.js +229 -0
  114. package/dist/plugins/keap/src/index.js +502 -0
  115. package/dist/plugins/kobotoolbox/src/index.js +281 -0
  116. package/dist/plugins/lemlist/src/index.js +231 -0
  117. package/dist/plugins/linear/src/index.js +133 -0
  118. package/dist/plugins/lingvanex/src/index.js +31 -0
  119. package/dist/plugins/linkedin/src/index.js +80 -0
  120. package/dist/plugins/lonescale/src/index.js +119 -0
  121. package/dist/plugins/magento/src/index.js +300 -0
  122. package/dist/plugins/mailcheck/src/index.js +27 -0
  123. package/dist/plugins/mailchimp/src/index.js +321 -0
  124. package/dist/plugins/mailerlite/src/index.js +123 -0
  125. package/dist/plugins/mailgun/src/index.js +48 -0
  126. package/dist/plugins/mailjet/src/index.js +155 -0
  127. package/dist/plugins/mandrill/src/index.js +145 -0
  128. package/dist/plugins/marketstack/src/index.js +97 -0
  129. package/dist/plugins/matrix/src/index.js +194 -0
  130. package/dist/plugins/mattermost/src/index.js +331 -0
  131. package/dist/plugins/mautic/src/index.js +311 -0
  132. package/dist/plugins/medium/src/index.js +77 -0
  133. package/dist/plugins/messagebird/src/index.js +57 -0
  134. package/dist/plugins/metabase/src/index.js +130 -0
  135. package/dist/plugins/misp/src/index.js +476 -0
  136. package/dist/plugins/mocean/src/index.js +67 -0
  137. package/dist/plugins/monday/src/index.js +231 -0
  138. package/dist/plugins/monicaCrm/src/index.js +52 -0
  139. package/dist/plugins/msg91/src/index.js +31 -0
  140. package/dist/plugins/nasa/src/index.js +146 -0
  141. package/dist/plugins/netlify/src/index.js +151 -0
  142. package/dist/plugins/netscalerAdc/src/index.js +131 -0
  143. package/dist/plugins/nextcloud/src/index.js +263 -0
  144. package/dist/plugins/nocodb/src/index.js +130 -0
  145. package/dist/plugins/notion/src/index.js +112 -0
  146. package/dist/plugins/npm/src/index.js +104 -0
  147. package/dist/plugins/odoo/src/index.js +157 -0
  148. package/dist/plugins/okta/src/index.js +141 -0
  149. package/dist/plugins/oneSimpleApi/src/index.js +155 -0
  150. package/dist/plugins/onfleet/src/index.js +254 -0
  151. package/dist/plugins/openThesaurus/src/index.js +32 -0
  152. package/dist/plugins/openweathermap/src/index.js +60 -0
  153. package/dist/plugins/oura/src/index.js +62 -0
  154. package/dist/plugins/paddle/src/index.js +247 -0
  155. package/dist/plugins/pagerduty/src/index.js +201 -0
  156. package/dist/plugins/paypal/src/index.js +106 -0
  157. package/dist/plugins/peekalink/src/index.js +35 -0
  158. package/dist/plugins/phantombuster/src/index.js +94 -0
  159. package/dist/plugins/philipsHue/src/index.js +98 -0
  160. package/dist/plugins/pipedrive/src/index.js +169 -0
  161. package/dist/plugins/plivo/src/index.js +66 -0
  162. package/dist/plugins/postbin/src/index.js +93 -0
  163. package/dist/plugins/posthog/src/index.js +113 -0
  164. package/dist/plugins/profitwell/src/index.js +50 -0
  165. package/dist/plugins/pushbullet/src/index.js +102 -0
  166. package/dist/plugins/pushcut/src/index.js +39 -0
  167. package/dist/plugins/pushover/src/index.js +65 -0
  168. package/dist/plugins/quickbase/src/index.js +153 -0
  169. package/dist/plugins/quickbooks/src/index.js +73 -0
  170. package/dist/plugins/quickchart/src/index.js +36 -0
  171. package/dist/plugins/raindrop/src/index.js +209 -0
  172. package/dist/plugins/reddit/src/index.js +185 -0
  173. package/dist/plugins/rocketchat/src/index.js +53 -0
  174. package/dist/plugins/rundeck/src/index.js +62 -0
  175. package/dist/plugins/salesforce/src/index.js +94 -0
  176. package/dist/plugins/salesmate/src/index.js +83 -0
  177. package/dist/plugins/securityScorecard/src/index.js +200 -0
  178. package/dist/plugins/segment/src/index.js +125 -0
  179. package/dist/plugins/sendgrid/src/index.js +187 -0
  180. package/dist/plugins/sendy/src/index.js +138 -0
  181. package/dist/plugins/sentry/src/index.js +233 -0
  182. package/dist/plugins/servicenow/src/index.js +108 -0
  183. package/dist/plugins/shopify/src/index.js +222 -0
  184. package/dist/plugins/signl4/src/index.js +61 -0
  185. package/dist/plugins/slack/src/index.js +236 -0
  186. package/dist/plugins/sms77/src/index.js +63 -0
  187. package/dist/plugins/splunk/src/index.js +207 -0
  188. package/dist/plugins/spotify/src/index.js +188 -0
  189. package/dist/plugins/stackby/src/index.js +82 -0
  190. package/dist/plugins/storyblok/src/index.js +141 -0
  191. package/dist/plugins/strapi/src/index.js +152 -0
  192. package/dist/plugins/strava/src/index.js +137 -0
  193. package/dist/plugins/stripe/src/index.js +222 -0
  194. package/dist/plugins/supabase/src/index.js +121 -0
  195. package/dist/plugins/syncromsp/src/index.js +255 -0
  196. package/dist/plugins/tapfiliate/src/index.js +125 -0
  197. package/dist/plugins/telegram/src/index.js +233 -0
  198. package/dist/plugins/thehive/src/index.js +142 -0
  199. package/dist/plugins/thehiveProject/src/index.js +194 -0
  200. package/dist/plugins/todoist/src/index.js +244 -0
  201. package/dist/plugins/travisci/src/index.js +71 -0
  202. package/dist/plugins/trello/src/index.js +341 -0
  203. package/dist/plugins/twake/src/index.js +40 -0
  204. package/dist/plugins/twilio/src/index.js +75 -0
  205. package/dist/plugins/twist/src/index.js +90 -0
  206. package/dist/plugins/twitter/src/index.js +123 -0
  207. package/dist/plugins/unleashedSoftware/src/index.js +84 -0
  208. package/dist/plugins/uplead/src/index.js +59 -0
  209. package/dist/plugins/uproc/src/index.js +34 -0
  210. package/dist/plugins/uptimerobot/src/index.js +264 -0
  211. package/dist/plugins/urlscanio/src/index.js +64 -0
  212. package/dist/plugins/vero/src/index.js +80 -0
  213. package/dist/plugins/vonage/src/index.js +42 -0
  214. package/dist/plugins/wekan/src/index.js +91 -0
  215. package/dist/plugins/woocommerce/src/index.js +92 -0
  216. package/dist/plugins/wordpress/src/index.js +121 -0
  217. package/dist/plugins/xero/src/index.js +136 -0
  218. package/dist/plugins/yourls/src/index.js +56 -0
  219. package/dist/plugins/zammad/src/index.js +91 -0
  220. package/dist/plugins/zendesk/src/index.js +137 -0
  221. package/dist/plugins/zoho/src/index.js +85 -0
  222. package/dist/plugins/zoom/src/index.js +122 -0
  223. package/dist/plugins/zulip/src/index.js +170 -0
  224. package/dist/sdk.d.ts +38 -0
  225. package/dist/sdk.js +105 -0
  226. package/dist/utils/cli.d.ts +13 -0
  227. package/dist/utils/cli.js +32 -0
  228. package/dist/utils/output.d.ts +4 -0
  229. package/dist/utils/output.js +13 -0
  230. package/package.json +57 -0
@@ -0,0 +1,185 @@
1
+ async function apiRequest(token, method, endpoint, qs) {
2
+ const base = token ? "https://oauth.reddit.com" : "https://www.reddit.com";
3
+ const url = new URL(`${base}/${endpoint}`);
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
+ url.searchParams.set("api_type", "json");
11
+ const headers = { "User-Agent": "runline" };
12
+ if (token)
13
+ headers.Authorization = `Bearer ${token}`;
14
+ const init = { method, headers };
15
+ const res = await fetch(url.toString(), init);
16
+ if (!res.ok)
17
+ throw new Error(`Reddit error ${res.status}: ${await res.text()}`);
18
+ return res.json();
19
+ }
20
+ function getToken(ctx) {
21
+ return ctx.connection.config.accessToken;
22
+ }
23
+ export default function reddit(rl) {
24
+ rl.setName("reddit");
25
+ rl.setVersion("0.1.0");
26
+ rl.setConnectionSchema({
27
+ accessToken: { type: "string", required: false, description: "Reddit OAuth2 access token (required for post/comment/profile actions)", env: "REDDIT_ACCESS_TOKEN" },
28
+ });
29
+ // ── Post ────────────────────────────────────────────
30
+ rl.registerAction("post.create", {
31
+ description: "Submit a new post to a subreddit (requires auth)",
32
+ inputSchema: {
33
+ subreddit: { type: "string", required: true },
34
+ title: { type: "string", required: true },
35
+ kind: { type: "string", required: true, description: "self (text) or link" },
36
+ text: { type: "string", required: false, description: "Post body (for self posts)" },
37
+ url: { type: "string", required: false, description: "URL (for link posts)" },
38
+ resubmit: { type: "boolean", required: false },
39
+ },
40
+ async execute(input, ctx) {
41
+ const p = input;
42
+ const qs = { title: p.title, sr: p.subreddit, kind: p.kind };
43
+ if (p.kind === "self")
44
+ qs.text = p.text;
45
+ else
46
+ qs.url = p.url;
47
+ if (p.resubmit)
48
+ qs.resubmit = "true";
49
+ const data = (await apiRequest(getToken(ctx), "POST", "api/submit", qs));
50
+ return data.json?.data;
51
+ },
52
+ });
53
+ rl.registerAction("post.get", {
54
+ description: "Get a post by ID",
55
+ inputSchema: {
56
+ subreddit: { type: "string", required: true },
57
+ postId: { type: "string", required: true },
58
+ },
59
+ async execute(input, ctx) {
60
+ const { subreddit, postId } = input;
61
+ const data = (await apiRequest(getToken(ctx), "GET", `r/${subreddit}/comments/${postId}.json`));
62
+ const listing = data[0];
63
+ const ld = listing.data;
64
+ const children = ld.children;
65
+ return children[0]?.data;
66
+ },
67
+ });
68
+ rl.registerAction("post.list", {
69
+ description: "List posts from a subreddit (no auth required for public subreddits)",
70
+ inputSchema: {
71
+ subreddit: { type: "string", required: true },
72
+ category: { type: "string", required: false, description: "hot (default), new, rising, top, controversial" },
73
+ limit: { type: "number", required: false, description: "Max results (default 25)" },
74
+ },
75
+ async execute(input, ctx) {
76
+ const p = (input ?? {});
77
+ const cat = p.category ?? "";
78
+ const endpoint = cat ? `r/${p.subreddit}/${cat}.json` : `r/${p.subreddit}.json`;
79
+ const qs = {};
80
+ if (p.limit)
81
+ qs.limit = p.limit;
82
+ const data = (await apiRequest(getToken(ctx), "GET", endpoint, qs));
83
+ const ld = data.data;
84
+ return ld.children.map(c => c.data);
85
+ },
86
+ });
87
+ rl.registerAction("post.delete", {
88
+ description: "Delete a post (requires auth)",
89
+ inputSchema: { postId: { type: "string", required: true } },
90
+ async execute(input, ctx) {
91
+ const { postId } = input;
92
+ await apiRequest(getToken(ctx), "POST", "api/del", { id: `t3_${postId}` });
93
+ return { success: true };
94
+ },
95
+ });
96
+ rl.registerAction("post.search", {
97
+ description: "Search posts",
98
+ inputSchema: {
99
+ keyword: { type: "string", required: true },
100
+ subreddit: { type: "string", required: false, description: "Limit search to subreddit" },
101
+ sort: { type: "string", required: false, description: "relevance, hot, top, new, comments" },
102
+ limit: { type: "number", required: false },
103
+ },
104
+ async execute(input, ctx) {
105
+ const p = (input ?? {});
106
+ const qs = { q: p.keyword };
107
+ if (p.sort)
108
+ qs.sort = p.sort;
109
+ if (p.limit)
110
+ qs.limit = p.limit;
111
+ const endpoint = p.subreddit ? `r/${p.subreddit}/search.json` : "search.json";
112
+ if (p.subreddit)
113
+ qs.restrict_sr = "true";
114
+ const data = (await apiRequest(getToken(ctx), "GET", endpoint, qs));
115
+ const ld = data.data;
116
+ return ld.children.map(c => c.data);
117
+ },
118
+ });
119
+ // ── Comment ─────────────────────────────────────────
120
+ rl.registerAction("comment.create", {
121
+ description: "Add a comment to a post (requires auth)",
122
+ inputSchema: {
123
+ postId: { type: "string", required: true },
124
+ text: { type: "string", required: true },
125
+ },
126
+ async execute(input, ctx) {
127
+ const { postId, text } = input;
128
+ const data = (await apiRequest(getToken(ctx), "POST", "api/comment", { thing_id: `t3_${postId}`, text }));
129
+ const json = data.json;
130
+ const jd = json.data;
131
+ const things = jd.things;
132
+ return things[0]?.data;
133
+ },
134
+ });
135
+ rl.registerAction("comment.reply", {
136
+ description: "Reply to a comment (requires auth)",
137
+ inputSchema: {
138
+ commentId: { type: "string", required: true },
139
+ text: { type: "string", required: true },
140
+ },
141
+ async execute(input, ctx) {
142
+ const { commentId, text } = input;
143
+ const data = (await apiRequest(getToken(ctx), "POST", "api/comment", { thing_id: `t1_${commentId}`, text }));
144
+ const json = data.json;
145
+ const jd = json.data;
146
+ const things = jd.things;
147
+ return things[0]?.data;
148
+ },
149
+ });
150
+ rl.registerAction("comment.delete", {
151
+ description: "Delete a comment (requires auth)",
152
+ inputSchema: { commentId: { type: "string", required: true } },
153
+ async execute(input, ctx) {
154
+ const { commentId } = input;
155
+ await apiRequest(getToken(ctx), "POST", "api/del", { id: `t1_${commentId}` });
156
+ return { success: true };
157
+ },
158
+ });
159
+ // ── Subreddit ───────────────────────────────────────
160
+ rl.registerAction("subreddit.get", {
161
+ description: "Get subreddit info or rules (no auth required)",
162
+ inputSchema: {
163
+ subreddit: { type: "string", required: true },
164
+ content: { type: "string", required: false, description: "about (default) or rules" },
165
+ },
166
+ async execute(input, ctx) {
167
+ const p = input;
168
+ const content = p.content ?? "about";
169
+ const data = (await apiRequest(getToken(ctx), "GET", `r/${p.subreddit}/about/${content}.json`));
170
+ if (content === "rules")
171
+ return data.rules;
172
+ return data.data;
173
+ },
174
+ });
175
+ // ── User ────────────────────────────────────────────
176
+ rl.registerAction("user.get", {
177
+ description: "Get user profile info (no auth required)",
178
+ inputSchema: { username: { type: "string", required: true } },
179
+ async execute(input, ctx) {
180
+ const { username } = input;
181
+ const data = (await apiRequest(getToken(ctx), "GET", `user/${username}/about.json`));
182
+ return data.data;
183
+ },
184
+ });
185
+ }
@@ -0,0 +1,53 @@
1
+ function getConn(ctx) {
2
+ const c = ctx.connection.config;
3
+ return {
4
+ domain: c.domain.replace(/\/$/, ""),
5
+ userId: c.userId,
6
+ authToken: c.authToken,
7
+ };
8
+ }
9
+ export default function rocketchat(rl) {
10
+ rl.setName("rocketchat");
11
+ rl.setVersion("0.1.0");
12
+ rl.setConnectionSchema({
13
+ domain: { type: "string", required: true, description: "Rocket.Chat server URL (e.g. https://chat.example.com)", env: "ROCKETCHAT_DOMAIN" },
14
+ userId: { type: "string", required: true, description: "User ID", env: "ROCKETCHAT_USER_ID" },
15
+ authToken: { type: "string", required: true, description: "Auth token", env: "ROCKETCHAT_AUTH_TOKEN" },
16
+ });
17
+ rl.registerAction("chat.postMessage", {
18
+ description: "Post a message to a Rocket.Chat channel or DM",
19
+ inputSchema: {
20
+ channel: { type: "string", required: true, description: "Channel name with prefix (e.g. #general or @username)" },
21
+ text: { type: "string", required: true },
22
+ alias: { type: "string", required: false, description: "Display name alias" },
23
+ emoji: { type: "string", required: false, description: "Emoji avatar (e.g. :smile:)" },
24
+ avatar: { type: "string", required: false, description: "Avatar image URL" },
25
+ attachments: { type: "object", required: false, description: "Array of attachment objects" },
26
+ },
27
+ async execute(input, ctx) {
28
+ const p = input;
29
+ const conn = getConn(ctx);
30
+ const body = { channel: p.channel, text: p.text };
31
+ if (p.alias)
32
+ body.alias = p.alias;
33
+ if (p.emoji)
34
+ body.emoji = p.emoji;
35
+ if (p.avatar)
36
+ body.avatar = p.avatar;
37
+ if (p.attachments)
38
+ body.attachments = p.attachments;
39
+ const res = await fetch(`${conn.domain}/api/v1/chat.postMessage`, {
40
+ method: "POST",
41
+ headers: {
42
+ "Content-Type": "application/json",
43
+ "X-Auth-Token": conn.authToken,
44
+ "X-User-Id": conn.userId,
45
+ },
46
+ body: JSON.stringify(body),
47
+ });
48
+ if (!res.ok)
49
+ throw new Error(`Rocket.Chat error ${res.status}: ${await res.text()}`);
50
+ return res.json();
51
+ },
52
+ });
53
+ }
@@ -0,0 +1,62 @@
1
+ function getConn(ctx) {
2
+ const c = ctx.connection.config;
3
+ return { url: c.url.replace(/\/$/, ""), token: c.token };
4
+ }
5
+ async function apiRequest(conn, method, endpoint, body, qs) {
6
+ const url = new URL(`${conn.url}${endpoint}`);
7
+ url.searchParams.set("authtoken", conn.token);
8
+ if (qs) {
9
+ for (const [k, v] of Object.entries(qs)) {
10
+ if (v !== undefined && v !== null)
11
+ url.searchParams.set(k, String(v));
12
+ }
13
+ }
14
+ const init = {
15
+ method,
16
+ headers: { Accept: "application/json", "Content-Type": "application/json" },
17
+ };
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(`Rundeck error ${res.status}: ${await res.text()}`);
23
+ return res.json();
24
+ }
25
+ export default function rundeck(rl) {
26
+ rl.setName("rundeck");
27
+ rl.setVersion("0.1.0");
28
+ rl.setConnectionSchema({
29
+ url: { type: "string", required: true, description: "Rundeck server URL (e.g. https://rundeck.example.com)", env: "RUNDECK_URL" },
30
+ token: { type: "string", required: true, description: "Rundeck API token", env: "RUNDECK_TOKEN" },
31
+ });
32
+ rl.registerAction("job.execute", {
33
+ description: "Execute a Rundeck job",
34
+ inputSchema: {
35
+ jobId: { type: "string", required: true },
36
+ arguments: { type: "object", required: false, description: "Array of {name, value} argument pairs" },
37
+ filter: { type: "string", required: false, description: "Node filter string" },
38
+ },
39
+ async execute(input, ctx) {
40
+ const p = input;
41
+ const conn = getConn(ctx);
42
+ let argString = "";
43
+ if (p.arguments) {
44
+ for (const arg of p.arguments) {
45
+ argString += `-${arg.name} ${arg.value} `;
46
+ }
47
+ }
48
+ const qs = {};
49
+ if (p.filter)
50
+ qs.filter = p.filter;
51
+ return apiRequest(conn, "POST", `/api/14/job/${p.jobId}/run`, { argString: argString.trim() }, qs);
52
+ },
53
+ });
54
+ rl.registerAction("job.getMetadata", {
55
+ description: "Get metadata for a Rundeck job",
56
+ inputSchema: { jobId: { type: "string", required: true } },
57
+ async execute(input, ctx) {
58
+ const { jobId } = input;
59
+ return apiRequest(getConn(ctx), "GET", `/api/18/job/${jobId}/info`);
60
+ },
61
+ });
62
+ }
@@ -0,0 +1,94 @@
1
+ const API_VERSION = "v59.0";
2
+ function getConn(ctx) {
3
+ const c = ctx.connection.config;
4
+ return { instanceUrl: c.instanceUrl.replace(/\/$/, ""), accessToken: c.accessToken };
5
+ }
6
+ async function api(conn, method, endpoint, body, qs) {
7
+ const url = new URL(`${conn.instanceUrl}/services/data/${API_VERSION}${endpoint}`);
8
+ if (qs) {
9
+ for (const [k, v] of Object.entries(qs)) {
10
+ if (v !== undefined && v !== null)
11
+ url.searchParams.set(k, String(v));
12
+ }
13
+ }
14
+ const init = { method, headers: { Authorization: `Bearer ${conn.accessToken}`, "Content-Type": "application/json" } };
15
+ if (body && Object.keys(body).length > 0)
16
+ init.body = JSON.stringify(body);
17
+ const res = await fetch(url.toString(), init);
18
+ if (res.status === 204)
19
+ return { success: true };
20
+ if (!res.ok)
21
+ throw new Error(`Salesforce error ${res.status}: ${await res.text()}`);
22
+ return res.json();
23
+ }
24
+ const SOBJECTS = ["Account", "Contact", "Lead", "Opportunity", "Case", "Task", "User"];
25
+ const DEFAULT_FIELDS = {
26
+ Account: "Id,Name,Type",
27
+ Contact: "Id,FirstName,LastName,Email",
28
+ Lead: "Id,Company,FirstName,LastName,Email,Status",
29
+ Opportunity: "Id,AccountId,Amount,Probability,StageName",
30
+ Case: "Id,AccountId,ContactId,Priority,Status,Subject",
31
+ Task: "Id,Subject,Status,Priority",
32
+ User: "Id,Name,Email",
33
+ };
34
+ function registerSObject(rl, sObject, conn) {
35
+ const lower = sObject.toLowerCase();
36
+ rl.registerAction(`${lower}.create`, { description: `Create a ${sObject}`, inputSchema: { data: { type: "object", required: true, description: `${sObject} field values` } },
37
+ async execute(input, ctx) { return api(conn(ctx), "POST", `/sobjects/${sObject}`, input.data); } });
38
+ rl.registerAction(`${lower}.get`, { description: `Get a ${sObject} by ID`, inputSchema: { id: { type: "string", required: true } },
39
+ async execute(input, ctx) { return api(conn(ctx), "GET", `/sobjects/${sObject}/${input.id}`); } });
40
+ rl.registerAction(`${lower}.update`, { description: `Update a ${sObject}`, inputSchema: { id: { type: "string", required: true }, data: { type: "object", required: true } },
41
+ async execute(input, ctx) {
42
+ const p = input;
43
+ await api(conn(ctx), "PATCH", `/sobjects/${sObject}/${p.id}`, p.data);
44
+ return { success: true, id: p.id };
45
+ } });
46
+ rl.registerAction(`${lower}.delete`, { description: `Delete a ${sObject}`, inputSchema: { id: { type: "string", required: true } },
47
+ async execute(input, ctx) { await api(conn(ctx), "DELETE", `/sobjects/${sObject}/${input.id}`); return { success: true }; } });
48
+ rl.registerAction(`${lower}.query`, { description: `Query ${sObject}s with SOQL`, inputSchema: { fields: { type: "string", required: false, description: `Comma-separated (default: ${DEFAULT_FIELDS[sObject] ?? "Id"})` }, where: { type: "string", required: false, description: "SOQL WHERE clause" }, limit: { type: "number", required: false } },
49
+ async execute(input, ctx) {
50
+ const p = (input ?? {});
51
+ const fields = p.fields || DEFAULT_FIELDS[sObject] || "Id";
52
+ let q = `SELECT ${fields} FROM ${sObject}`;
53
+ if (p.where)
54
+ q += ` WHERE ${p.where}`;
55
+ if (p.limit)
56
+ q += ` LIMIT ${p.limit}`;
57
+ const data = (await api(conn(ctx), "GET", "/query", undefined, { q }));
58
+ return data.records;
59
+ } });
60
+ rl.registerAction(`${lower}.upsert`, { description: `Upsert a ${sObject} by external ID`, inputSchema: { externalIdField: { type: "string", required: true }, externalIdValue: { type: "string", required: true }, data: { type: "object", required: true } },
61
+ async execute(input, ctx) {
62
+ const p = input;
63
+ return api(conn(ctx), "PATCH", `/sobjects/${sObject}/${p.externalIdField}/${p.externalIdValue}`, p.data);
64
+ } });
65
+ }
66
+ export default function salesforce(rl) {
67
+ rl.setName("salesforce");
68
+ rl.setVersion("0.1.0");
69
+ rl.setConnectionSchema({
70
+ instanceUrl: { type: "string", required: true, description: "Salesforce instance URL (e.g. https://yourorg.my.salesforce.com)", env: "SALESFORCE_INSTANCE_URL" },
71
+ accessToken: { type: "string", required: true, description: "Salesforce OAuth2 access token", env: "SALESFORCE_ACCESS_TOKEN" },
72
+ });
73
+ for (const sObject of SOBJECTS) {
74
+ registerSObject(rl, sObject, getConn);
75
+ }
76
+ // ── Generic sObject ─────────────────────────────────
77
+ rl.registerAction("sobject.create", { description: "Create any sObject record", inputSchema: { sObject: { type: "string", required: true }, data: { type: "object", required: true } },
78
+ async execute(input, ctx) { const p = input; return api(getConn(ctx), "POST", `/sobjects/${p.sObject}`, p.data); } });
79
+ rl.registerAction("sobject.get", { description: "Get any sObject record", inputSchema: { sObject: { type: "string", required: true }, id: { type: "string", required: true } },
80
+ async execute(input, ctx) { const p = input; return api(getConn(ctx), "GET", `/sobjects/${p.sObject}/${p.id}`); } });
81
+ rl.registerAction("sobject.update", { description: "Update any sObject record", inputSchema: { sObject: { type: "string", required: true }, id: { type: "string", required: true }, data: { type: "object", required: true } },
82
+ async execute(input, ctx) { const p = input; await api(getConn(ctx), "PATCH", `/sobjects/${p.sObject}/${p.id}`, p.data); return { success: true }; } });
83
+ rl.registerAction("sobject.delete", { description: "Delete any sObject record", inputSchema: { sObject: { type: "string", required: true }, id: { type: "string", required: true } },
84
+ async execute(input, ctx) { const p = input; await api(getConn(ctx), "DELETE", `/sobjects/${p.sObject}/${p.id}`); return { success: true }; } });
85
+ // ── SOQL Query ──────────────────────────────────────
86
+ rl.registerAction("soql.query", { description: "Execute a raw SOQL query", inputSchema: { query: { type: "string", required: true, description: "Full SOQL query" } },
87
+ async execute(input, ctx) {
88
+ const data = (await api(getConn(ctx), "GET", "/query", undefined, { q: input.query }));
89
+ return data.records;
90
+ } });
91
+ // ── Describe ────────────────────────────────────────
92
+ rl.registerAction("sobject.describe", { description: "Describe an sObject's metadata/fields", inputSchema: { sObject: { type: "string", required: true } },
93
+ async execute(input, ctx) { return api(getConn(ctx), "GET", `/sobjects/${input.sObject}/describe`); } });
94
+ }
@@ -0,0 +1,83 @@
1
+ const BASE = "https://apis.salesmate.io";
2
+ function getConn(ctx) {
3
+ return { sessionToken: ctx.connection.config.sessionToken, linkname: ctx.connection.config.linkname };
4
+ }
5
+ async function api(conn, method, endpoint, body, qs) {
6
+ const url = new URL(`${BASE}${endpoint}`);
7
+ if (qs) {
8
+ for (const [k, v] of Object.entries(qs)) {
9
+ if (v !== undefined && v !== null)
10
+ url.searchParams.set(k, String(v));
11
+ }
12
+ }
13
+ const init = { method, headers: { sessionToken: conn.sessionToken, "x-linkname": conn.linkname, "Content-Type": "application/json" } };
14
+ if (body && Object.keys(body).length > 0)
15
+ init.body = JSON.stringify(body);
16
+ const res = await fetch(url.toString(), init);
17
+ if (!res.ok)
18
+ throw new Error(`Salesmate error ${res.status}: ${await res.text()}`);
19
+ return res.json();
20
+ }
21
+ function registerCrud(rl, resource, plural, conn, createSchema) {
22
+ rl.registerAction(`${resource}.create`, { description: `Create a ${resource}`, inputSchema: createSchema,
23
+ async execute(input, ctx) {
24
+ const data = (await api(conn(ctx), "POST", `/v1/${plural}`, input));
25
+ return data.Data;
26
+ } });
27
+ rl.registerAction(`${resource}.get`, { description: `Get a ${resource} by ID`, inputSchema: { id: { type: "string", required: true } },
28
+ async execute(input, ctx) {
29
+ const data = (await api(conn(ctx), "GET", `/v1/${plural}/${input.id}`));
30
+ return data.Data;
31
+ } });
32
+ rl.registerAction(`${resource}.list`, { description: `Search/list ${plural}`, inputSchema: { limit: { type: "number", required: false }, fields: { type: "object", required: false, description: "Array of field names to return" }, query: { type: "object", required: false, description: "Search query object" } },
33
+ async execute(input, ctx) {
34
+ const p = (input ?? {});
35
+ const body = { fields: p.fields ?? ["name", "id"], query: p.query ?? {} };
36
+ const qs = {};
37
+ if (p.limit)
38
+ qs.rows = p.limit;
39
+ const data = (await api(conn(ctx), "POST", `/v2/${plural}/search`, body, qs));
40
+ return data.Data.data;
41
+ } });
42
+ rl.registerAction(`${resource}.update`, { description: `Update a ${resource}`, inputSchema: { id: { type: "string", required: true }, data: { type: "object", required: true } },
43
+ async execute(input, ctx) {
44
+ const p = input;
45
+ const data = (await api(conn(ctx), "PUT", `/v1/${plural}/${p.id}`, p.data));
46
+ return data.Data;
47
+ } });
48
+ rl.registerAction(`${resource}.delete`, { description: `Delete a ${resource}`, inputSchema: { id: { type: "string", required: true } },
49
+ async execute(input, ctx) { return api(conn(ctx), "DELETE", `/v1/${plural}/${input.id}`); } });
50
+ }
51
+ export default function salesmate(rl) {
52
+ rl.setName("salesmate");
53
+ rl.setVersion("0.1.0");
54
+ rl.setConnectionSchema({
55
+ sessionToken: { type: "string", required: true, description: "Salesmate session token", env: "SALESMATE_SESSION_TOKEN" },
56
+ linkname: { type: "string", required: true, description: "Salesmate workspace linkname (subdomain)", env: "SALESMATE_LINKNAME" },
57
+ });
58
+ registerCrud(rl, "company", "companies", getConn, {
59
+ name: { type: "string", required: true },
60
+ owner: { type: "number", required: true },
61
+ website: { type: "string", required: false },
62
+ phone: { type: "string", required: false },
63
+ description: { type: "string", required: false },
64
+ });
65
+ registerCrud(rl, "activity", "activities", getConn, {
66
+ title: { type: "string", required: true },
67
+ owner: { type: "number", required: true },
68
+ type: { type: "string", required: true, description: "e.g. call, email, task" },
69
+ description: { type: "string", required: false },
70
+ dueDate: { type: "string", required: false },
71
+ });
72
+ registerCrud(rl, "deal", "deals", getConn, {
73
+ title: { type: "string", required: true },
74
+ owner: { type: "number", required: true },
75
+ primaryContact: { type: "number", required: true },
76
+ pipeline: { type: "string", required: true },
77
+ status: { type: "string", required: true },
78
+ stage: { type: "string", required: true },
79
+ currency: { type: "string", required: true },
80
+ dealValue: { type: "number", required: false },
81
+ description: { type: "string", required: false },
82
+ });
83
+ }