slack-logs 3.0.2 → 3.0.4

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 CHANGED
@@ -26,6 +26,16 @@ npm install slack-logs
26
26
  yarn add slack-logs
27
27
  ```
28
28
 
29
+ ### Demo
30
+
31
+ [StackBlitz Demo](https://stackblitz.com/edit/stackblitz-starters-minuqbqu?file=index.js)
32
+
33
+ <!-- ![Slack Logs Demo](./images/demo-preview.png) -->
34
+
35
+ ### Try payload experiments here:
36
+
37
+ [Slack Block Kit Builder](https://app.slack.com/block-kit-builder/T9D4GM7L0)
38
+
29
39
  ### Configuration:
30
40
 
31
41
  Before you start, ensure you have created an Incoming Webhook in Slack and have the webhook URL ready. For more information on setting up Incoming Webhooks in Slack, visit [Slack's API documentation.](https://api.slack.com/messaging/webhooks)
@@ -208,12 +218,6 @@ Contributions are welcome! If you have a feature request, bug report, or a pull
208
218
 
209
219
  This package is licensed under the MIT License - see the LICENSE file for details.
210
220
 
211
- ### Demo
212
-
213
- [StackBlitz Demo](https://stackblitz.com/edit/stackblitz-starters-minuqbqu?file=index.js)
214
-
215
- <!-- ![Slack Logs Demo](./images/demo-preview.png) -->
216
-
217
221
  ### Raw body
218
222
 
219
223
  Use `slack.rawBody(...)` when you want to send a custom Slack payload as-is.
@@ -264,6 +268,141 @@ slack.rawBody(payload);
264
268
 
265
269
  If payload is invalid or sending fails, it logs a console error.
266
270
 
267
- Try payload experiments here:
271
+ ---
268
272
 
269
- [Slack Block Kit Builder](https://app.slack.com/block-kit-builder/T9D4GM7L0)
273
+ ## Slack Bot
274
+
275
+ Use `slackbot` when you want the same logging helpers with bot-token based multi-channel support.
276
+
277
+ ### Configuration
278
+
279
+ ```
280
+ import { slackbot, slackBotConfig } from "slack-logs";
281
+ or
282
+ const { slackbot, slackBotConfig } = require("slack-logs");
283
+
284
+ slackBotConfig({
285
+ botToken: "xoxb-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX",
286
+ defaultChannelId: "C0123456789",
287
+ enableAlerts: true,
288
+ });
289
+ ```
290
+
291
+ `slackBotConfig(...)` rules:
292
+
293
+ - `botToken` and `enableAlerts` are required
294
+ - `defaultChannelId` is optional if you pass `channelId` in method calls
295
+ - if `defaultChannelId` is not set in config, package falls back to `SLACK_BOT_DEFAULT_CHANNEL_ID`
296
+
297
+ ### Environment variables
298
+
299
+ Use env values only when `slackBotConfig(...)` is not called.
300
+
301
+ `.env` 🚨
302
+
303
+ ```
304
+ ...
305
+ SLACK_BOT_TOKEN="xoxb-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX"
306
+ SLACK_BOT_DEFAULT_CHANNEL_ID="C0123456789"
307
+
308
+ # Optional field.
309
+ # If not defined, logs are sent by default.
310
+ # true / True / TRUE sends logs.
311
+ # false / False / FALSE skips logs.
312
+ ENABLE_SLACK_BOT_LOGS=true
313
+ ...
314
+ ```
315
+
316
+ ### Methods
317
+
318
+ ```
319
+ slackbot.log(label, data, channelId?);
320
+ slackbot.logBlockMessage(label, payload, errorType?, channelId?);
321
+ slackbot.rawBody(payload, channelId?);
322
+ ```
323
+
324
+ ### `slackbot.log(...)`
325
+
326
+ `slackbot.log(...)` uses the same payload format as `slack.log(...)`, so the output style is the same.
327
+
328
+ ```
329
+ import { slackbot } from "slack-logs";
330
+
331
+ slackbot.log("Data Log with bold", "Here is *BOLD* message", "C0123456789");
332
+ slackbot.log("Highlight Log", "`Message`", "C0123456789");
333
+ slackbot.log("Emoji :rocket: Log", "Yeah :female-technologist::skin-tone-2:");
334
+ slackbot.log("Object Log", {id:"123", value:"Lorem Impulse"});
335
+ ```
336
+
337
+ ![Sample Image](https://i.imgur.com/ucAnAiJ.png)
338
+
339
+ ### `slackbot.logBlockMessage(...)`
340
+
341
+ `slackbot.logBlockMessage(...)` uses the same payload format as `slack.logBlockMessage(...)`, so the same output examples apply.
342
+
343
+ ```
344
+ import { LogLevel, slackbot } from "slack-logs";
345
+
346
+ const payload = [
347
+ { title: "Title 1", value: "1234" },
348
+ { title: "Title 2", value: 123 },
349
+ { title: "Title 3", value: { id: 12 } },
350
+ { title: "Title 4", value: [{ id: 12 }] },
351
+ ];
352
+
353
+ slackbot.logBlockMessage("Custom Logs!", payload, LogLevel.DEFAULT, "C0123456789");
354
+ slackbot.logBlockMessage("Some Information Logs!", payload, LogLevel.INFO);
355
+ slackbot.logBlockMessage("Critical Alert!", payload, LogLevel.ERROR);
356
+ ```
357
+
358
+ ![Sample Image](https://i.imgur.com/Ohlktzr.png)
359
+
360
+ ### `slackbot.rawBody(...)`
361
+
362
+ Use `slackbot.rawBody(...)` when you want to send a custom Slack payload with an optional `channelId`.
363
+
364
+ ```
365
+ import { slackbot } from "slack-logs";
366
+
367
+ const payload = {
368
+ blocks: [
369
+ {
370
+ type: "section",
371
+ text: {
372
+ type: "mrkdwn",
373
+ text: "Hello from custom payload",
374
+ },
375
+ },
376
+ {
377
+ type: "divider",
378
+ },
379
+ {
380
+ type: "actions",
381
+ elements: [
382
+ {
383
+ type: "button",
384
+ text: {
385
+ type: "plain_text",
386
+ text: "Open",
387
+ emoji: true,
388
+ },
389
+ value: "click_me_123",
390
+ url: "https://google.com",
391
+ },
392
+ ],
393
+ },
394
+ ],
395
+ };
396
+
397
+ slackbot.rawBody(payload, "C0123456789");
398
+ ```
399
+
400
+ `slackbot.rawBody(...)` expects a plain object payload like:
401
+
402
+ ```
403
+ {
404
+ "blocks": [...]
405
+ }
406
+ ```
407
+
408
+ If payload is invalid or sending fails, it logs a console error.
package/dist/index.d.ts CHANGED
@@ -1,30 +1,13 @@
1
+ import type { BlocksInterface, LogLevel } from "./shared";
1
2
  interface Slack {
2
3
  log(label: string, data: any): Promise<null | undefined>;
3
- logBlockMessage(label: string, objectData: BlocksInterface[], error_type?: LogLevel): Promise<null | undefined>;
4
+ logBlockMessage(label: string, objectData: BlocksInterface[], errorType?: LogLevel): Promise<null | undefined>;
4
5
  rawBody(payload: Record<string, any>): Promise<null | undefined>;
5
6
  }
6
- export interface SlackLogConfigOptions {
7
- webhookUrl: string;
8
- enableAlerts: boolean;
9
- }
10
- interface BlocksInterface {
11
- title: string;
12
- value: any;
13
- }
14
- export declare enum LogLevel {
15
- DEFAULT = "DEFAULT",
16
- SUCCESS = "SUCCESS",
17
- INFO = "INFO",
18
- WARN = "WARN",
19
- ERROR = "ERROR"
20
- }
21
- export declare enum LogColor {
22
- DEFAULT = "#B4B4B8",
23
- SUCCESS = "#65B741",
24
- INFO = "#40A2D8",
25
- WARN = "#E3651D",
26
- ERROR = "#FF0000"
27
- }
28
- export declare function slackLogConfig(config: SlackLogConfigOptions): void;
7
+ export type { SlackBotConfigOptions } from "./slack-bot";
8
+ export { slackBotConfig, slackbot } from "./slack-bot";
9
+ export type { BlocksInterface } from "./shared";
10
+ export { LogColor, LogLevel } from "./shared";
11
+ export type { SlackLogConfigOptions } from "./webhook";
12
+ export { slackLogConfig } from "./webhook";
29
13
  export declare const slack: Slack;
30
- export {};
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}Object.defineProperty(exports,"__esModule",{value:!0});var o,t,r=e(require("axios"));exports.LogLevel=void 0,(o=exports.LogLevel||(exports.LogLevel={})).DEFAULT="DEFAULT",o.SUCCESS="SUCCESS",o.INFO="INFO",o.WARN="WARN",o.ERROR="ERROR",exports.LogColor=void 0,(t=exports.LogColor||(exports.LogColor={})).DEFAULT="#B4B4B8",t.SUCCESS="#65B741",t.INFO="#40A2D8",t.WARN="#E3651D",t.ERROR="#FF0000";const n={};const s={async log(e,o){const t=JSON.stringify(o);if(!l())return console.error("🚨 Invalid Slack webhook URL. Kindly check slackLogConfig(...) or 'SLACK_WEBHOOK_URL' in your .env file! 🚨"),null;let r={text:`*${e}:* ${t}`};await c(r)},async logBlockMessage(e,o,t=exports.LogLevel.DEFAULT){if(!l())return console.error("🚨 Invalid Slack webhook URL. Kindly check slackLogConfig(...) or 'SLACK_WEBHOOK_URL' in your .env file! 🚨"),null;const r=exports.LogColor[t],n=[],s=[],a=[];n.push({type:"divider"}),n.push({type:"header",text:{type:"plain_text",text:e,emoji:!0}}),n.push({type:"divider"}),o?.length&&o.forEach((e=>{let o=JSON.stringify(e.value);a.push({type:"section",text:{type:"mrkdwn",text:`*${e.title}:* ${o}`}})})),s.push({color:r,blocks:a});let i={text:e,blocks:n,attachments:s};await c(i)},rawBody:async e=>l()?function(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}(e)?void await c(e):(console.error('🚨 Invalid Slack payload for rawBody(...). Expected an object like { "blocks": [...] } 🚨'),null):(console.error("🚨 Invalid Slack webhook URL. Kindly check slackLogConfig(...) or 'SLACK_WEBHOOK_URL' in your .env file! 🚨"),null)};function l(){const e=a();if(!e)return!1;return!!/^https:\/\/hooks\.slack\.com\/services\/[A-Za-z0-9]+\/[A-Za-z0-9]+\/[A-Za-z0-9]+$/.test(e)||(console.error(`🚨 Slack webhook URL does not look in correct format. Current value is "${e}", expected format is "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX". 🚨`),!1)}function a(){return n.webhookUrl??process.env.SLACK_WEBHOOK_URL}async function c(e){if(!function(){if("boolean"==typeof n.enableAlerts)return n.enableAlerts;const e=(process?.env?.ENABLE_SLACK_LOGS??"").toString().trim();return!e||"true"===e.toLowerCase()||(e.toLowerCase(),!1)}())return null;const o=a();return await r.default.post(o,JSON.stringify(e),{headers:{"Content-Type":"application/json"}}).catch((e=>{const o=e?.response?.data?.error||e?.response?.statusText||e?.message||"Unknown error";console.error(`🚨 Error sending log message to Slack: ${o}`)}))}exports.slack=s,exports.slackLogConfig=function(e){n.webhookUrl=e.webhookUrl,n.enableAlerts=e.enableAlerts};
1
+ "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}Object.defineProperty(exports,"__esModule",{value:!0});var o,t,n=e(require("axios"));exports.LogLevel=void 0,(o=exports.LogLevel||(exports.LogLevel={})).DEFAULT="DEFAULT",o.SUCCESS="SUCCESS",o.INFO="INFO",o.WARN="WARN",o.ERROR="ERROR",exports.LogColor=void 0,(t=exports.LogColor||(exports.LogColor={})).DEFAULT="#B4B4B8",t.SUCCESS="#65B741",t.INFO="#40A2D8",t.WARN="#E3651D",t.ERROR="#FF0000";const r={};function s(){const e=l();if(!e)return!1;return!!/^https:\/\/hooks\.slack\.com\/services\/[A-Za-z0-9]+\/[A-Za-z0-9]+\/[A-Za-z0-9]+$/.test(e)||(console.error(`🚨 Slack webhook URL does not look in correct format. Current value is "${e}", expected format is "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX". 🚨`),!1)}function l(){return r.webhookUrl??process.env.SLACK_WEBHOOK_URL}async function a(e){if(!function(){if("boolean"==typeof r.enableAlerts)return r.enableAlerts;const e=(process?.env?.ENABLE_SLACK_LOGS??"").toString().trim();return!e||"true"===e.toLowerCase()||(e.toLowerCase(),!1)}())return null;const o=l();await n.default.post(o,JSON.stringify(e),{headers:{"Content-Type":"application/json"}}).catch((e=>{const o=e?.response?.data?.error||e?.response?.statusText||e?.message||"Unknown error";console.error(`🚨 Error sending log message to Slack: ${o}`)}))}const c={};const i={log:async(e,o,t)=>(await p(function(e,o){return{text:`*${e}:* ${JSON.stringify(o)}`}}(e,o),t),null),logBlockMessage:async(e,o,t=exports.LogLevel.DEFAULT,n)=>(await p(function(e,o,t=exports.LogLevel.DEFAULT){const n=[];return o?.length&&o.forEach((e=>{n.push({type:"section",text:{type:"mrkdwn",text:`*${e.title}:* ${JSON.stringify(e.value)}`}})})),{text:e,blocks:[{type:"divider"},{type:"header",text:{type:"plain_text",text:e,emoji:!0}},{type:"divider"}],attachments:[{color:exports.LogColor[t],blocks:n}]}}(e,o,t),n),null),rawBody:async(e,o)=>function(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}(e)?(await p(e,o),null):(console.error('🚨 Invalid Slack payload for slackbot.rawBody(...). Expected an object like { "blocks": [...] } 🚨'),null)};function u(e,o){const t=("string"==typeof e.channel?e.channel:void 0)??o??c.defaultChannelId??process.env.SLACK_BOT_DEFAULT_CHANNEL_ID;return function(e){return!!e&&/^[CGD][A-Z0-9]+$/.test(e)}(t)?t:(console.error("🚨 Invalid Slack channel ID. Kindly pass a valid channelId or set 'defaultChannelId' in slackBotConfig(...) / 'SLACK_BOT_DEFAULT_CHANNEL_ID' in your .env file! 🚨"),null)}async function p(e,o){if(!function(){if("boolean"==typeof c.enableAlerts)return c.enableAlerts;const e=(process?.env?.ENABLE_SLACK_BOT_LOGS??process?.env?.ENABLE_SLACK_LOGS??"").toString().trim();return!e||"true"===e.toLowerCase()||(e.toLowerCase(),!1)}())return null;const t=c.botToken??process.env.SLACK_BOT_TOKEN;if(!function(e){return!!e&&/^xoxb-[A-Za-z0-9-]+$/.test(e)}(t))return console.error("🚨 Invalid Slack bot token. Kindly check slackBotConfig(...) or 'SLACK_BOT_TOKEN' in your .env file! 🚨"),null;const r=u(e,o);return r?await n.default.post("https://slack.com/api/chat.postMessage",{...e,channel:r},{headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json; charset=utf-8"}}).then((e=>{e?.data?.ok||console.error(`🚨 Error sending bot message to Slack: ${e?.data?.error||"Unknown error"}`)})).catch((e=>{const o=e?.response?.data?.error||e?.response?.statusText||e?.message||"Unknown error";console.error(`🚨 Error sending bot message to Slack: ${o}`)})):null}const d={...{async log(e,o){const t=JSON.stringify(o);if(!s())return console.error("🚨 Invalid Slack webhook URL. Kindly check slackLogConfig(...) or 'SLACK_WEBHOOK_URL' in your .env file! 🚨"),null;const n={text:`*${e}:* ${t}`};await a(n)},async logBlockMessage(e,o,t=exports.LogLevel.DEFAULT){if(!s())return console.error("🚨 Invalid Slack webhook URL. Kindly check slackLogConfig(...) or 'SLACK_WEBHOOK_URL' in your .env file! 🚨"),null;const n=exports.LogColor[t],r=[],l=[],c=[];r.push({type:"divider"}),r.push({type:"header",text:{type:"plain_text",text:e,emoji:!0}}),r.push({type:"divider"}),o?.length&&o.forEach((e=>{const o=JSON.stringify(e.value);c.push({type:"section",text:{type:"mrkdwn",text:`*${e.title}:* ${o}`}})})),l.push({color:n,blocks:c});const i={text:e,blocks:r,attachments:l};await a(i)},rawBody:async e=>s()?function(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}(e)?void await a(e):(console.error('🚨 Invalid Slack payload for rawBody(...). Expected an object like { "blocks": [...] } 🚨'),null):(console.error("🚨 Invalid Slack webhook URL. Kindly check slackLogConfig(...) or 'SLACK_WEBHOOK_URL' in your .env file! 🚨"),null)}};exports.slack=d,exports.slackBotConfig=function(e){c.botToken=e.botToken,c.defaultChannelId=e.defaultChannelId,c.enableAlerts=e.enableAlerts},exports.slackLogConfig=function(e){r.webhookUrl=e.webhookUrl,r.enableAlerts=e.enableAlerts},exports.slackbot=i;
@@ -0,0 +1,40 @@
1
+ export interface BlocksInterface {
2
+ title: string;
3
+ value: any;
4
+ }
5
+ export declare enum LogLevel {
6
+ DEFAULT = "DEFAULT",
7
+ SUCCESS = "SUCCESS",
8
+ INFO = "INFO",
9
+ WARN = "WARN",
10
+ ERROR = "ERROR"
11
+ }
12
+ export declare enum LogColor {
13
+ DEFAULT = "#B4B4B8",
14
+ SUCCESS = "#65B741",
15
+ INFO = "#40A2D8",
16
+ WARN = "#E3651D",
17
+ ERROR = "#FF0000"
18
+ }
19
+ export declare function buildLogPayload(label: string, data: any): {
20
+ text: string;
21
+ };
22
+ export declare function buildLogBlockPayload(label: string, objectData: BlocksInterface[], errorType?: LogLevel): {
23
+ text: string;
24
+ blocks: ({
25
+ type: string;
26
+ text?: undefined;
27
+ } | {
28
+ type: string;
29
+ text: {
30
+ type: string;
31
+ text: string;
32
+ emoji: boolean;
33
+ };
34
+ })[];
35
+ attachments: {
36
+ color: LogColor;
37
+ blocks: object[];
38
+ }[];
39
+ };
40
+ export declare function isValidRawPayload(payload: Record<string, any>): boolean;
@@ -0,0 +1,15 @@
1
+ import type { BlocksInterface } from "./shared";
2
+ import { LogLevel } from "./shared";
3
+ export interface SlackBotConfigOptions {
4
+ botToken: string;
5
+ defaultChannelId?: string;
6
+ enableAlerts: boolean;
7
+ }
8
+ interface SlackBot {
9
+ log(label: string, data: any, channelId?: string): Promise<null | undefined>;
10
+ logBlockMessage(label: string, objectData: BlocksInterface[], errorType?: LogLevel, channelId?: string): Promise<null | undefined>;
11
+ rawBody(payload: Record<string, any>, channelId?: string): Promise<null | undefined>;
12
+ }
13
+ export declare function slackBotConfig(config: SlackBotConfigOptions): void;
14
+ export declare const slackbot: SlackBot;
15
+ export {};
@@ -0,0 +1,12 @@
1
+ import { LogLevel } from "./shared";
2
+ import type { BlocksInterface } from "./shared";
3
+ export interface SlackLogConfigOptions {
4
+ webhookUrl: string;
5
+ enableAlerts: boolean;
6
+ }
7
+ export declare function slackLogConfig(config: SlackLogConfigOptions): void;
8
+ export declare const slackWebhook: {
9
+ log(label: string, data: any): Promise<null | undefined>;
10
+ logBlockMessage(label: string, objectData: BlocksInterface[], errorType?: LogLevel): Promise<null | undefined>;
11
+ rawBody(payload: Record<string, any>): Promise<null | undefined>;
12
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slack-logs",
3
- "version": "3.0.2",
3
+ "version": "3.0.4",
4
4
  "description": "slack-logs",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",