slack-logs 3.0.3 → 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
@@ -267,3 +267,142 @@ slack.rawBody(payload);
267
267
  ```
268
268
 
269
269
  If payload is invalid or sending fails, it logs a console error.
270
+
271
+ ---
272
+
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.3",
3
+ "version": "3.0.4",
4
4
  "description": "slack-logs",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",