devcodes-webhook 1.0.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/README.md ADDED
@@ -0,0 +1,239 @@
1
+ # devcodes-webhook
2
+
3
+ Send Discord and Slack webhooks with a clean, typed API — no boilerplate, built-in retries, full TypeScript support.
4
+
5
+ Built on top of [devcodes-http-tool](https://www.npmjs.com/package/devcodes-http-tool).
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install devcodes-webhook
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```js
16
+ const { sendWebhook } = require('devcodes-webhook');
17
+
18
+ await sendWebhook('https://discord.com/api/webhooks/...', {
19
+ content: 'Hello from devcodes-webhook!'
20
+ });
21
+ ```
22
+
23
+ ---
24
+
25
+ ## Discord
26
+
27
+ ### Basic message
28
+
29
+ ```js
30
+ const { DiscordWebhook } = require('devcodes-webhook');
31
+
32
+ const hook = new DiscordWebhook('https://discord.com/api/webhooks/ID/TOKEN');
33
+
34
+ await hook.sendText('Server is back online ✅');
35
+ ```
36
+
37
+ ### Send an embed
38
+
39
+ ```js
40
+ await hook.sendEmbed({
41
+ title: '🚀 Deployment Complete',
42
+ description: 'Version **1.4.2** is now live.',
43
+ color: 0x57F287, // green
44
+ timestamp: new Date().toISOString(),
45
+ footer: { text: 'Dev Codes CI' },
46
+ });
47
+ ```
48
+
49
+ ### Send multiple embeds
50
+
51
+ ```js
52
+ await hook.sendEmbeds([
53
+ { title: 'Service A', description: '✅ Healthy', color: 0x57F287 },
54
+ { title: 'Service B', description: '⚠️ Degraded', color: 0xFEE75C },
55
+ { title: 'Service C', description: '❌ Down', color: 0xED4245 },
56
+ ]);
57
+ ```
58
+
59
+ ### Override webhook name & avatar
60
+
61
+ ```js
62
+ await hook.send({
63
+ content: 'Ping!',
64
+ username: 'Alert Bot',
65
+ avatar_url: 'https://example.com/avatar.png',
66
+ });
67
+ ```
68
+
69
+ ### Full embed example
70
+
71
+ ```js
72
+ await hook.sendEmbed({
73
+ author: {
74
+ name: 'azaresw',
75
+ url: 'https://github.com/azaresw',
76
+ icon_url: 'https://github.com/azaresw.png',
77
+ },
78
+ title: 'New Pull Request',
79
+ url: 'https://github.com/azaresw/repo/pull/42',
80
+ description: 'Fix memory leak in cache layer',
81
+ color: 0x5865F2,
82
+ fields: [
83
+ { name: 'Branch', value: '`fix/cache-leak`', inline: true },
84
+ { name: 'Status', value: 'Open', inline: true },
85
+ { name: 'Changed', value: '3 files', inline: true },
86
+ ],
87
+ thumbnail: { url: 'https://github.com/azaresw.png' },
88
+ footer: { text: 'GitHub • devcodes-webhook' },
89
+ timestamp: new Date().toISOString(),
90
+ });
91
+ ```
92
+
93
+ ---
94
+
95
+ ## Slack
96
+
97
+ ### Plain text
98
+
99
+ ```js
100
+ const { SlackWebhook } = require('devcodes-webhook');
101
+
102
+ const hook = new SlackWebhook('https://hooks.slack.com/services/...');
103
+
104
+ await hook.sendText('Deployment finished successfully!');
105
+ ```
106
+
107
+ ### Block Kit
108
+
109
+ ```js
110
+ await hook.sendBlocks([
111
+ {
112
+ type: 'header',
113
+ text: { type: 'plain_text', text: '🚨 Alert' },
114
+ },
115
+ {
116
+ type: 'section',
117
+ text: { type: 'mrkdwn', text: '*Service:* API Gateway\n*Status:* Down' },
118
+ },
119
+ ]);
120
+ ```
121
+
122
+ ### Send to a specific channel
123
+
124
+ ```js
125
+ await hook.send({
126
+ text: 'Hello #dev!',
127
+ channel: '#dev',
128
+ icon_emoji: ':rocket:',
129
+ });
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Generic `sendWebhook`
135
+
136
+ Works with any service that accepts a JSON webhook body.
137
+
138
+ ```js
139
+ const { sendWebhook } = require('devcodes-webhook');
140
+
141
+ await sendWebhook('https://your-endpoint.com/hook', {
142
+ event: 'user.signup',
143
+ userId: '123',
144
+ });
145
+ ```
146
+
147
+ ---
148
+
149
+ ## TypeScript
150
+
151
+ Full type support out of the box.
152
+
153
+ ```ts
154
+ import { DiscordWebhook, DiscordEmbed, WebhookConfig } from 'devcodes-webhook';
155
+
156
+ const config: WebhookConfig = { timeout: 5000, retries: 3 };
157
+ const hook = new DiscordWebhook('https://discord.com/api/webhooks/...', config);
158
+
159
+ const embed: DiscordEmbed = {
160
+ title: 'Alert',
161
+ description: 'Something happened.',
162
+ color: 0xED4245,
163
+ };
164
+
165
+ await hook.sendEmbed(embed);
166
+ ```
167
+
168
+ ---
169
+
170
+ ## API Reference
171
+
172
+ ### `new DiscordWebhook(url, config?)`
173
+
174
+ | Method | Signature | Description |
175
+ |--------|-----------|-------------|
176
+ | `send` | `(payload: DiscordWebhookPayload) => Promise<WebhookResponse>` | Send a raw payload |
177
+ | `sendText` | `(content: string, extras?) => Promise<WebhookResponse>` | Send a plain text message |
178
+ | `sendEmbed` | `(embed: DiscordEmbed, extras?) => Promise<WebhookResponse>` | Send a single embed |
179
+ | `sendEmbeds` | `(embeds: DiscordEmbed[], extras?) => Promise<WebhookResponse>` | Send up to 10 embeds |
180
+
181
+ ### `new SlackWebhook(url, config?)`
182
+
183
+ | Method | Signature | Description |
184
+ |--------|-----------|-------------|
185
+ | `send` | `(payload: SlackWebhookPayload) => Promise<WebhookResponse>` | Send a raw payload |
186
+ | `sendText` | `(text: string, extras?) => Promise<WebhookResponse>` | Send a plain text message |
187
+ | `sendBlocks` | `(blocks: unknown[], extras?) => Promise<WebhookResponse>` | Send Block Kit blocks |
188
+
189
+ ### `sendWebhook(url, payload, config?)`
190
+
191
+ Generic function that POSTs any JSON payload to a URL.
192
+
193
+ ### `WebhookConfig`
194
+
195
+ | Option | Type | Default | Description |
196
+ |--------|------|---------|-------------|
197
+ | `timeout` | `number` | `10000` | Request timeout in ms |
198
+ | `retries` | `number` | `2` | Retry attempts on failure |
199
+ | `retryDelay` | `number` | `500` | Delay between retries in ms |
200
+
201
+ ### `WebhookResponse`
202
+
203
+ ```ts
204
+ interface WebhookResponse {
205
+ ok: boolean; // true if status 2xx
206
+ status: number; // HTTP status code
207
+ }
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Discord bot integration example
213
+
214
+ ```js
215
+ const { DiscordWebhook } = require('devcodes-webhook');
216
+
217
+ const logs = new DiscordWebhook(process.env.LOG_WEBHOOK_URL);
218
+
219
+ client.on('guildMemberAdd', async (member) => {
220
+ await logs.sendEmbed({
221
+ title: '👋 New Member',
222
+ description: `${member.user.tag} joined **${member.guild.name}**`,
223
+ color: 0x57F287,
224
+ thumbnail: { url: member.user.displayAvatarURL() },
225
+ timestamp: new Date().toISOString(),
226
+ footer: { text: `Members: ${member.guild.memberCount}` },
227
+ });
228
+ });
229
+ ```
230
+
231
+ ---
232
+
233
+ ## License
234
+
235
+ MIT © [azaresw](https://github.com/azaresw)
236
+
237
+ ## Support
238
+
239
+ Join our Discord for help and updates: [discord.gg/ESh2Dp2xX9](https://discord.gg/ESh2Dp2xX9)
@@ -0,0 +1,19 @@
1
+ import type { DiscordWebhookPayload, DiscordEmbed, WebhookConfig, WebhookResponse } from './types';
2
+ export declare class DiscordWebhook {
3
+ private readonly url;
4
+ private readonly http;
5
+ /**
6
+ * @param url Your Discord webhook URL
7
+ * @param config Optional timeout/retry settings
8
+ */
9
+ constructor(url: string, config?: WebhookConfig);
10
+ /** Send a raw Discord webhook payload */
11
+ send(payload: DiscordWebhookPayload): Promise<WebhookResponse>;
12
+ /** Send a single embed, with optional extras (content, username, …) */
13
+ sendEmbed(embed: DiscordEmbed, extras?: Omit<DiscordWebhookPayload, 'embeds'>): Promise<WebhookResponse>;
14
+ /** Send multiple embeds at once (max 10 per Discord limits) */
15
+ sendEmbeds(embeds: DiscordEmbed[], extras?: Omit<DiscordWebhookPayload, 'embeds'>): Promise<WebhookResponse>;
16
+ /** Send a plain text message */
17
+ sendText(content: string, extras?: Omit<DiscordWebhookPayload, 'content'>): Promise<WebhookResponse>;
18
+ }
19
+ //# sourceMappingURL=discord.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discord.d.ts","sourceRoot":"","sources":["../src/discord.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,eAAe,EAChB,MAAM,SAAS,CAAC;AAEjB,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IAEjD;;;OAGG;gBACS,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,aAAkB;IASnD,yCAAyC;IACnC,IAAI,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC;IAKpE,uEAAuE;IACjE,SAAS,CACb,KAAK,EAAE,YAAY,EACnB,MAAM,CAAC,EAAE,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC,GAC7C,OAAO,CAAC,eAAe,CAAC;IAI3B,+DAA+D;IACzD,UAAU,CACd,MAAM,EAAE,YAAY,EAAE,EACtB,MAAM,CAAC,EAAE,IAAI,CAAC,qBAAqB,EAAE,QAAQ,CAAC,GAC7C,OAAO,CAAC,eAAe,CAAC;IAI3B,gCAAgC;IAC1B,QAAQ,CACZ,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,IAAI,CAAC,qBAAqB,EAAE,SAAS,CAAC,GAC9C,OAAO,CAAC,eAAe,CAAC;CAG5B"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DiscordWebhook = void 0;
4
+ const devcodes_http_tool_1 = require("devcodes-http-tool");
5
+ class DiscordWebhook {
6
+ /**
7
+ * @param url Your Discord webhook URL
8
+ * @param config Optional timeout/retry settings
9
+ */
10
+ constructor(url, config = {}) {
11
+ this.url = url;
12
+ this.http = (0, devcodes_http_tool_1.create)({
13
+ timeout: config.timeout ?? 10000,
14
+ retries: config.retries ?? 2,
15
+ retryDelay: config.retryDelay ?? 500,
16
+ });
17
+ }
18
+ /** Send a raw Discord webhook payload */
19
+ async send(payload) {
20
+ const res = await this.http.post(this.url, payload);
21
+ return { ok: res.status >= 200 && res.status < 300, status: res.status };
22
+ }
23
+ /** Send a single embed, with optional extras (content, username, …) */
24
+ async sendEmbed(embed, extras) {
25
+ return this.send({ ...extras, embeds: [embed] });
26
+ }
27
+ /** Send multiple embeds at once (max 10 per Discord limits) */
28
+ async sendEmbeds(embeds, extras) {
29
+ return this.send({ ...extras, embeds });
30
+ }
31
+ /** Send a plain text message */
32
+ async sendText(content, extras) {
33
+ return this.send({ ...extras, content });
34
+ }
35
+ }
36
+ exports.DiscordWebhook = DiscordWebhook;
37
+ //# sourceMappingURL=discord.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discord.js","sourceRoot":"","sources":["../src/discord.ts"],"names":[],"mappings":";;;AAAA,2DAA4C;AAQ5C,MAAa,cAAc;IAIzB;;;OAGG;IACH,YAAY,GAAW,EAAE,SAAwB,EAAE;QACjD,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAA,2BAAM,EAAC;YACjB,OAAO,EAAK,MAAM,CAAC,OAAO,IAAO,KAAM;YACvC,OAAO,EAAK,MAAM,CAAC,OAAO,IAAO,CAAC;YAClC,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,GAAG;SACrC,CAAC,CAAC;IACL,CAAC;IAED,yCAAyC;IACzC,KAAK,CAAC,IAAI,CAAC,OAA8B;QACvC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACpD,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;IAC3E,CAAC;IAED,uEAAuE;IACvE,KAAK,CAAC,SAAS,CACb,KAAmB,EACnB,MAA8C;QAE9C,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,+DAA+D;IAC/D,KAAK,CAAC,UAAU,CACd,MAAsB,EACtB,MAA8C;QAE9C,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,gCAAgC;IAChC,KAAK,CAAC,QAAQ,CACZ,OAAe,EACf,MAA+C;QAE/C,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;CACF;AA9CD,wCA8CC"}
@@ -0,0 +1,5 @@
1
+ export { DiscordWebhook } from './discord';
2
+ export { SlackWebhook } from './slack';
3
+ export { sendWebhook } from './utils';
4
+ export type { WebhookConfig, WebhookResponse, DiscordWebhookPayload, DiscordEmbed, DiscordEmbedFooter, DiscordEmbedImage, DiscordEmbedThumbnail, DiscordEmbedAuthor, DiscordEmbedField, DiscordAllowedMentions, SlackWebhookPayload, } from './types';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAQ,SAAS,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAS,SAAS,CAAC;AAEzC,YAAY,EACV,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendWebhook = exports.SlackWebhook = exports.DiscordWebhook = void 0;
4
+ var discord_1 = require("./discord");
5
+ Object.defineProperty(exports, "DiscordWebhook", { enumerable: true, get: function () { return discord_1.DiscordWebhook; } });
6
+ var slack_1 = require("./slack");
7
+ Object.defineProperty(exports, "SlackWebhook", { enumerable: true, get: function () { return slack_1.SlackWebhook; } });
8
+ var utils_1 = require("./utils");
9
+ Object.defineProperty(exports, "sendWebhook", { enumerable: true, get: function () { return utils_1.sendWebhook; } });
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qCAA2C;AAAlC,yGAAA,cAAc,OAAA;AACvB,iCAAyC;AAAhC,qGAAA,YAAY,OAAA;AACrB,iCAAyC;AAAhC,oGAAA,WAAW,OAAA"}
@@ -0,0 +1,17 @@
1
+ import type { SlackWebhookPayload, WebhookConfig, WebhookResponse } from './types';
2
+ export declare class SlackWebhook {
3
+ private readonly url;
4
+ private readonly http;
5
+ /**
6
+ * @param url Your Slack incoming webhook URL
7
+ * @param config Optional timeout/retry settings
8
+ */
9
+ constructor(url: string, config?: WebhookConfig);
10
+ /** Send a raw Slack webhook payload */
11
+ send(payload: SlackWebhookPayload): Promise<WebhookResponse>;
12
+ /** Send a plain text message */
13
+ sendText(text: string, extras?: Omit<SlackWebhookPayload, 'text'>): Promise<WebhookResponse>;
14
+ /** Send a Block Kit payload */
15
+ sendBlocks(blocks: unknown[], extras?: Omit<SlackWebhookPayload, 'blocks'>): Promise<WebhookResponse>;
16
+ }
17
+ //# sourceMappingURL=slack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../src/slack.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEnF,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IAEjD;;;OAGG;gBACS,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,aAAkB;IASnD,uCAAuC;IACjC,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,eAAe,CAAC;IAKlE,gCAAgC;IAC1B,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,GACzC,OAAO,CAAC,eAAe,CAAC;IAI3B,+BAA+B;IACzB,UAAU,CACd,MAAM,EAAE,OAAO,EAAE,EACjB,MAAM,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,QAAQ,CAAC,GAC3C,OAAO,CAAC,eAAe,CAAC;CAG5B"}
package/dist/slack.js ADDED
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SlackWebhook = void 0;
4
+ const devcodes_http_tool_1 = require("devcodes-http-tool");
5
+ class SlackWebhook {
6
+ /**
7
+ * @param url Your Slack incoming webhook URL
8
+ * @param config Optional timeout/retry settings
9
+ */
10
+ constructor(url, config = {}) {
11
+ this.url = url;
12
+ this.http = (0, devcodes_http_tool_1.create)({
13
+ timeout: config.timeout ?? 10000,
14
+ retries: config.retries ?? 2,
15
+ retryDelay: config.retryDelay ?? 500,
16
+ });
17
+ }
18
+ /** Send a raw Slack webhook payload */
19
+ async send(payload) {
20
+ const res = await this.http.post(this.url, payload);
21
+ return { ok: res.status >= 200 && res.status < 300, status: res.status };
22
+ }
23
+ /** Send a plain text message */
24
+ async sendText(text, extras) {
25
+ return this.send({ ...extras, text });
26
+ }
27
+ /** Send a Block Kit payload */
28
+ async sendBlocks(blocks, extras) {
29
+ return this.send({ ...extras, blocks });
30
+ }
31
+ }
32
+ exports.SlackWebhook = SlackWebhook;
33
+ //# sourceMappingURL=slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.js","sourceRoot":"","sources":["../src/slack.ts"],"names":[],"mappings":";;;AAAA,2DAA4C;AAG5C,MAAa,YAAY;IAIvB;;;OAGG;IACH,YAAY,GAAW,EAAE,SAAwB,EAAE;QACjD,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAA,2BAAM,EAAC;YACjB,OAAO,EAAK,MAAM,CAAC,OAAO,IAAO,KAAM;YACvC,OAAO,EAAK,MAAM,CAAC,OAAO,IAAO,CAAC;YAClC,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,GAAG;SACrC,CAAC,CAAC;IACL,CAAC;IAED,uCAAuC;IACvC,KAAK,CAAC,IAAI,CAAC,OAA4B;QACrC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACpD,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;IAC3E,CAAC;IAED,gCAAgC;IAChC,KAAK,CAAC,QAAQ,CACZ,IAAY,EACZ,MAA0C;QAE1C,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,+BAA+B;IAC/B,KAAK,CAAC,UAAU,CACd,MAAiB,EACjB,MAA4C;QAE5C,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;CACF;AAtCD,oCAsCC"}
@@ -0,0 +1,82 @@
1
+ export interface WebhookConfig {
2
+ /** Request timeout in ms. Default: 10000 */
3
+ timeout?: number;
4
+ /** Number of retries on failure. Default: 2 */
5
+ retries?: number;
6
+ /** Delay between retries in ms. Default: 500 */
7
+ retryDelay?: number;
8
+ }
9
+ export interface WebhookResponse {
10
+ /** Whether the request was successful (2xx) */
11
+ ok: boolean;
12
+ /** HTTP status code */
13
+ status: number;
14
+ }
15
+ export interface DiscordEmbedFooter {
16
+ text: string;
17
+ icon_url?: string;
18
+ }
19
+ export interface DiscordEmbedImage {
20
+ url: string;
21
+ }
22
+ export interface DiscordEmbedThumbnail {
23
+ url: string;
24
+ }
25
+ export interface DiscordEmbedAuthor {
26
+ name: string;
27
+ url?: string;
28
+ icon_url?: string;
29
+ }
30
+ export interface DiscordEmbedField {
31
+ name: string;
32
+ value: string;
33
+ inline?: boolean;
34
+ }
35
+ export interface DiscordEmbed {
36
+ title?: string;
37
+ description?: string;
38
+ url?: string;
39
+ /** ISO8601 timestamp */
40
+ timestamp?: string;
41
+ /** Decimal colour value */
42
+ color?: number;
43
+ footer?: DiscordEmbedFooter;
44
+ image?: DiscordEmbedImage;
45
+ thumbnail?: DiscordEmbedThumbnail;
46
+ author?: DiscordEmbedAuthor;
47
+ fields?: DiscordEmbedField[];
48
+ }
49
+ export interface DiscordAllowedMentions {
50
+ parse?: ('roles' | 'users' | 'everyone')[];
51
+ roles?: string[];
52
+ users?: string[];
53
+ replied_user?: boolean;
54
+ }
55
+ export interface DiscordWebhookPayload {
56
+ content?: string;
57
+ username?: string;
58
+ avatar_url?: string;
59
+ tts?: boolean;
60
+ embeds?: DiscordEmbed[];
61
+ allowed_mentions?: DiscordAllowedMentions;
62
+ /** Thread name to create (forum channels) */
63
+ thread_name?: string;
64
+ /** Message flags */
65
+ flags?: number;
66
+ }
67
+ export interface SlackWebhookPayload {
68
+ text?: string;
69
+ username?: string;
70
+ icon_emoji?: string;
71
+ icon_url?: string;
72
+ /** Override the default channel */
73
+ channel?: string;
74
+ /** Block Kit blocks */
75
+ blocks?: unknown[];
76
+ /** Legacy attachments */
77
+ attachments?: unknown[];
78
+ mrkdwn?: boolean;
79
+ unfurl_links?: boolean;
80
+ unfurl_media?: boolean;
81
+ }
82
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,+CAA+C;IAC/C,EAAE,EAAE,OAAO,CAAC;IACZ,uBAAuB;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,SAAS,CAAC,EAAE,qBAAqB,CAAC;IAClC,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,CAAC,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC,EAAE,CAAC;IAC3C,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IACxB,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uBAAuB;IACvB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,yBAAyB;IACzB,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB"}
package/dist/types.js ADDED
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ // ─── Shared ───────────────────────────────────────────────────────────────────
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA,iFAAiF"}
@@ -0,0 +1,10 @@
1
+ import type { WebhookConfig, WebhookResponse } from './types';
2
+ /**
3
+ * Send any JSON payload to any webhook URL (Discord, Slack, or custom).
4
+ *
5
+ * @param url Webhook URL
6
+ * @param payload Any JSON-serialisable object
7
+ * @param config Optional timeout/retry settings
8
+ */
9
+ export declare function sendWebhook(url: string, payload: unknown, config?: WebhookConfig): Promise<WebhookResponse>;
10
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE9D;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,OAAO,EAChB,MAAM,GAAE,aAAkB,GACzB,OAAO,CAAC,eAAe,CAAC,CAQ1B"}
package/dist/utils.js ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendWebhook = sendWebhook;
4
+ const devcodes_http_tool_1 = require("devcodes-http-tool");
5
+ /**
6
+ * Send any JSON payload to any webhook URL (Discord, Slack, or custom).
7
+ *
8
+ * @param url Webhook URL
9
+ * @param payload Any JSON-serialisable object
10
+ * @param config Optional timeout/retry settings
11
+ */
12
+ async function sendWebhook(url, payload, config = {}) {
13
+ const http = (0, devcodes_http_tool_1.create)({
14
+ timeout: config.timeout ?? 10000,
15
+ retries: config.retries ?? 2,
16
+ retryDelay: config.retryDelay ?? 500,
17
+ });
18
+ const res = await http.post(url, payload);
19
+ return { ok: res.status >= 200 && res.status < 300, status: res.status };
20
+ }
21
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;AAUA,kCAYC;AAtBD,2DAA4C;AAG5C;;;;;;GAMG;AACI,KAAK,UAAU,WAAW,CAC/B,GAAW,EACX,OAAgB,EAChB,SAAwB,EAAE;IAE1B,MAAM,IAAI,GAAG,IAAA,2BAAM,EAAC;QAClB,OAAO,EAAK,MAAM,CAAC,OAAO,IAAO,KAAM;QACvC,OAAO,EAAK,MAAM,CAAC,OAAO,IAAO,CAAC;QAClC,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,GAAG;KACrC,CAAC,CAAC;IACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;AAC3E,CAAC"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "devcodes-webhook",
3
+ "version": "1.0.0",
4
+ "description": "Send Discord and Slack webhooks with a simple, typed API. Built on devcodes-http-tool.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "README.md"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "dev": "tsc --watch",
14
+ "prepublishOnly": "npm run build"
15
+ },
16
+ "engines": {
17
+ "node": ">=14.0.0"
18
+ },
19
+ "keywords": [
20
+ "webhook",
21
+ "discord",
22
+ "slack",
23
+ "discord-webhook",
24
+ "slack-webhook",
25
+ "embed",
26
+ "notification",
27
+ "devcodes",
28
+ "typescript"
29
+ ],
30
+ "author": "Dev Codes",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/azaresw/devcodes-webhook.git"
35
+ },
36
+ "dependencies": {
37
+ "devcodes-http-tool": "^1.0.4"
38
+ },
39
+ "devDependencies": {
40
+ "typescript": "^5.3.3"
41
+ }
42
+ }