@atmosx/event-product-parser 3.0.53 → 3.0.54

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/.github/README.md CHANGED
@@ -23,7 +23,7 @@ const { Manager } = require(`@atmosx/event-product-parser`) // CJS Importing
23
23
  import { Manager } from '@atmosx/event-product-parser' // EJS Importing
24
24
 
25
25
  const Client = new Manager({
26
- Database: `shapefiles.db`,
26
+ Database: `event-product-parser.db`,
27
27
  EnableWireService: false,
28
28
  EnableJournal: true,
29
29
  EnableDebugging: false,
@@ -39,8 +39,8 @@ const Client = new Manager({
39
39
  },
40
40
  CacheSettings: {
41
41
  Enabled: true,
42
- MaxDatabaseHistory: 5000,
43
- MaxRetentionHistory: 555,
42
+ MaxDatabaseHistory: 50000,
43
+ MaxRetentionHistory: 1500,
44
44
  },
45
45
  StanzaSettings: {
46
46
  DisableUGC: false,
@@ -54,12 +54,13 @@ const Client = new Manager({
54
54
  },
55
55
  BroadcastifySettings: {
56
56
  BroadcastifyAttachments: true,
57
+ BroadcastifyDatabase: `https://scriptkitty.cafe/ftp/@atmosphericx/assets/broadcastify.json`,
57
58
  BroadcastifyTags: [`Public Safety`, `Amateur Radio`, `Other`, `Rail`, `Aviation`, `Marine`, `Disaster Event`, `Special Event`]
58
59
  },
59
60
  NotifyServer: {
60
61
  Enabled: false,
61
- Server: "https://ntfy.domainname.com",
62
- Attachments: "https://domainname.com/Storage/EasScenarios",
62
+ Server: "https://ntfy.scriptkitty.cafe",
63
+ Attachments: "https://scriptkitty.cafe/ftp/@bucket/EAS/encoded",
63
64
  Credentials: {
64
65
  Username: "username",
65
66
  Password: "password"
@@ -67,22 +68,16 @@ const Client = new Manager({
67
68
  },
68
69
  ListenerSettings: [
69
70
  {
70
- events: [`*Thunderstorm Warning*`, `* Watch`],
71
- webhook: {
72
- enabled: true,
73
- destination: "https://discord.com/api/XXXXXXXXXX/XXXXXXXXXXX",
74
- title: "AtmosphericX - (Thunderstorm Warnings and Watches)",
75
- message: "<@&XXXXXXXXXXXXXXXXXXXXX>",
76
- ratelimit: 1
71
+ Events: ["*Extreme Heat Warning*"],
72
+ NotificationServer: {
73
+ Enabled: false,
74
+ Topic: "heat-warnings",
75
+ Priority: 5
77
76
  },
78
- notify: {
79
- enabled: false,
80
- topic: "thunderstorm_events",
81
- },
82
- uploads: {
83
- eas: true,
84
- file: true,
85
- event: true
77
+ Uploads: {
78
+ EAS: true,
79
+ File: true,
80
+ JSON: true
86
81
  }
87
82
  }
88
83
  ],
@@ -94,106 +89,29 @@ const Client = new Manager({
94
89
  SPCWatchesOnly: true,
95
90
  ShapefileSkipPoints: 0,
96
91
  NodeTTL: 60,
97
- NodeMinDistance: 120,
92
+ NodeMinDistance: 125,
98
93
  EventFiltering: {
99
94
  ListeningEvents: [
100
- "*Severe Thunderstorm Warning*",
101
- "*Blizzard*", "*Ice Storm*", "*Winter Storm*", "*Snow Squall*",
102
- "Tornado Emergency", "*Tornado Warning*",
103
- "Special Weather Statement", "Marine Weather Statement",
104
- "*Tsunami*", "*Hurricane*", "*Tropical Storm*", "*Special Marine*",
105
- "*Flash Flood Warning*", "*Flash Flood Watch*", "*Flash Flood Advisory*",
106
- "Mesoscale Discussion",
107
- "*Storm Prediction Center*",
108
- "PDS Tornado Watch", "Tornado Watch", "Severe Thunderstorm Watch", "Flash Flood Watch", "PDS Severe Thunderstorm Watch",
109
- "*Administrative*", "National Weather Service Policy",
110
- "Fire Weather Warning", "Fire Weather Watch", "Fire Weather Advisory",
95
+ "*Warning*"
111
96
  ],
112
- ListeningICAO: [`KLOT`],
97
+ ListeningICAO: [],
98
+ ListeningUGC: [],
99
+ ListeningStates: [],
113
100
  IgnoredICAO: [],
114
101
  IgnoredEvents: [],
115
- ListeningUGC: [`WIC001`],
116
- ListeningStates: [`MO`, `IA`],
117
102
  NodeLocationFiltering: false,
118
103
  IgnoreTestProducts: true,
119
104
  },
120
105
  ArchiveSettings: {
121
- TTL: 600,
122
- EventDirectory: `Storage/EventProducts`,
123
- TextDirectory: `Storage/TextProducts`,
124
- EasDirectory: `Storage/EasScenarios`,
125
- EasToneout: `tone.wav`,
106
+ TTL: 30,
107
+ EventDirectory: `@bucket/ParsedProducts`,
108
+ TextDirectory: `@bucket/RawTextProducts`,
109
+ EasDirectory: `@bucket/EAS`,
110
+ EasToneout: `eas-toneout.wav`,
126
111
  }
127
112
  }
128
113
  })
129
114
  ```
130
- ### General Settings
131
- - **Database**: The database file name and location, please make sure to include the `.db` extension.
132
- - **EnableWireService**: Whether to enable `NOAA Weather Wire Service` within the parser. This requires credentials from [NOAA Weather Wire Service](https://www.weather.gov/nwws/).
133
- - **EnableJournal**: Whether to output logs without requiring event `listeners`.
134
-
135
- ### NOAAWeatherWireServiceSettings
136
- - **ReconnectionSettings**: When the XMPP client gets disconnected or has an error, choose to reconnect to the service again. This contains a reconnection check interval.
137
- - **CredentialSettings**: The username (nickname) and password that is required for using `NOAA Weather Wire Service`.
138
- - **CacheSettings**: The ability to use the cache system so when you relaunch the parser, it will have a event retention history of all the stanzas collected.
139
- - **StanzaSettings**: Modify what type of products metadata you'd like to receive. (UGC, VTEC, RawText)
140
-
141
- ### NationalWeatherServiceSettings
142
- - **CallbackInterval**: The interval at which the parser will check for new alerts from the National Weather Service API.
143
- - **EventsEndpoint**: The URL that directs to the API.
144
-
145
- ## BroadcastifySettings
146
- - **BroadcastifyAttachments**: Whether to enable broadcastify attachments for events.
147
- - **BroadcastifyDatabase**: The download url to point to for the collection of broadcastify feeds. (Stored locally once downloaded)
148
- - **BroadcastifyTags**: An array of tags to filter broadcastify feeds. (`Public Safety`, `Amateur Radio`, `Other`, `Rail`, `Aviation`, `Marine`, `Disaster Event`, `Special Event`)
149
-
150
- ## NotifyServer
151
- - **Enabled**: Whether to enable the notify server for events. This uses the [ntfy.sh](https://ntfy.sh/) service to send notifications for events. This is optional and can be disabled if not needed.
152
- - **Server**: The notify server URL (Ex. `https://ntfy.domainname.com`)
153
- - **Attachments**: The URL to the attachments directory (Ex. `https://domainname.com/Storage/EasScenarios`)
154
- - **Credentials**: The username and password for the notify server if required. (Optional)
155
-
156
- ### ListenerSettings
157
- - **events**: An array of event types that will trigger the listener when they are received by the parser. If this array is empty, the listener will be triggered for all events.
158
-
159
- #### Webhook
160
- - **enabled**: If the webhook is enabled or not
161
- - **destination**: Webhook URL
162
- - **title**: The title of the webhook
163
- - **message**: The message you'd like to use for the webhook
164
- - **ratelimit**: How many messages can it send before being ratelimited
165
-
166
- #### Notify
167
- - **enabled**: If the notify server is enabled or not
168
- - **topic**: The topic you'd like to use for the notify server. This is used to send notifications for events. (Ex. `thunderstorm_events`)
169
-
170
- #### Uploads
171
- - **eas**: Whether to enable auto eas generated audio files
172
- - **file**: Wheather to generate text files
173
-
174
-
175
- ### GlobalSettings
176
- - **EventManagement**: Whether to enable the event management system which includes filtering, tracking nodes, and custom messages.
177
- - **BetterEventNames**: Changes events to a more specific version depending on parameters, message types, etc. `(Ex. "Tornado Warning" -> "Observed Tornado Warning")`
178
- - **DisableGeometryParsing**: Disable automatically appending GeoJSON geometry data to the events to save on memory consumption.
179
- - **UseShapefileCoordinates**: Whether to use the shapefile database to obtain the coordinates for events with specified UGC zones.
180
- - **SPCWatchesOnly**: Whether to only listen for SPC watches only (TOR/SVR) (If using the API, this is ignored).
181
- - **ShapefileSkipPoints**: When using the shapefile database to obtain coordinates, you can choose to skip a certain amount of points to reduce the number of coordinates for large events. (Ex. If an event has 1000 coordinates and you set this to `2`, it will only use every other coordinate, therefore using 500 coordinates instead of 1000).
182
- - **NodeTTL**: How often nodes should be checked per event. (Tracking/Filtering)
183
- - **NodeMinDistance**: The minimum distance to filter events from the node (Miles)
184
- - **ListeningEvents**: Events you'd like to listen for. If this array is left empty, it will listen for **ALL** events and products.
185
- - **ListeningICAO**: ICAO codes for the weather stations you'd like to listen for. Filtering all events that do not contain the codes. `(Ex. ["KLOT", "TORD"])`
186
- - **IgnoredICAO**: Ignored ICAO codes `(Ex. ["KWNS"])`
187
- - **IgnoredEvents**: Ignored events / products.
188
- - **ListeningUGC**: Zones you'd like to listen to `(Ex. ["ILZ001"])`
189
- - **ListeningStates**: States you'd like to listen to `(Ex. ["IL"])`
190
- - **NodeLocationFiltering**: If you want tracking nodes to filter out events based on radius. (Miles)\
191
- - **IgnoreTextProducts**: If you want to ignore test products and events.
192
- - **TTL**: How long files live for before getting automatically deleted
193
- - **TextDirectory**: The location to store text products that are generated.
194
- - **EasDirectory**: The location to store audio eas files that are generated.
195
- - **EasToneout**: The toneout prefix to use for generated eas messages.
196
-
197
115
 
198
116
  ## How do custom listeners work?
199
117
 
@@ -1124,7 +1124,7 @@ module.exports = __toCommonJS(index_exports);
1124
1124
  var import_path = __toESM(require("path"));
1125
1125
  var import_node_events = require("events");
1126
1126
  var bootstrap = {
1127
- version: `3.0.53`,
1127
+ version: `3.0.54`,
1128
1128
  isReady: true,
1129
1129
  ratelimits: {},
1130
1130
  session_xmpp: null,
@@ -6424,8 +6424,8 @@ var setEasTone = (options) => __async(null, null, function* () {
6424
6424
  return outTTS;
6425
6425
  });
6426
6426
 
6427
- // src/@parsers/@text/text.getEmbed.ts
6428
- var getEmebed = (event) => {
6427
+ // src/@parsers/@text/text.getEmbedText.ts
6428
+ var getEmebedText = (event) => {
6429
6429
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na;
6430
6430
  const line = (label, value, condition = true) => condition && value ? `${label} ${value}` : null;
6431
6431
  const isStatement = event.properties.status_metadata.is_statement;
@@ -6462,8 +6462,8 @@ var getEmebed = (event) => {
6462
6462
  ].filter(Boolean).join("\n");
6463
6463
  };
6464
6464
 
6465
- // src/@parsers/@text/text.getRaw.ts
6466
- var getRaw = (event) => {
6465
+ // src/@parsers/@text/text.getStringText.ts
6466
+ var getStringText = (event) => {
6467
6467
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da;
6468
6468
  const line = (label, value, condition = true) => condition && value ? `${label} ${value}` : null;
6469
6469
  const isStatement = event.properties.status_metadata.is_statement;
@@ -6560,7 +6560,7 @@ var getMatched = (strings, string) => {
6560
6560
  // src/@manager/manager.updateListener.ts
6561
6561
  var import_fs3 = require("fs");
6562
6562
  var updateListener = (event) => __async(null, null, function* () {
6563
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
6563
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
6564
6564
  const tick = performance.now();
6565
6565
  const settings = bootstrap.settings;
6566
6566
  const listeners2 = settings.ListenerSettings;
@@ -6579,19 +6579,20 @@ var updateListener = (event) => __async(null, null, function* () {
6579
6579
  attachments: properties2.metadata.attachments
6580
6580
  };
6581
6581
  for (const listener2 of listeners2) {
6582
- const events = listener2 == null ? void 0 : listener2.events;
6583
- const webhook = listener2 == null ? void 0 : listener2.webhook;
6584
- const uploads = listener2 == null ? void 0 : listener2.uploads;
6582
+ const events = listener2 == null ? void 0 : listener2.Events;
6583
+ const webhook = listener2 == null ? void 0 : listener2.Webhook;
6584
+ const notify = listener2 == null ? void 0 : listener2.NotificationServer;
6585
+ const uploads = listener2 == null ? void 0 : listener2.Uploads;
6585
6586
  const isMatched = getMatched(events != null ? events : [], metadata.name);
6586
6587
  if ((events == null ? void 0 : events.length) == 0 || isMatched) {
6587
- if (uploads == null ? void 0 : uploads.eas) {
6588
+ if (uploads == null ? void 0 : uploads.EAS) {
6588
6589
  metadata.eas = yield setEasTone({
6589
6590
  title: `${metadata.name}_${metadata.status}_${metadata.tracking}`,
6590
6591
  message: metadata.description,
6591
6592
  header: metadata.header
6592
6593
  });
6593
6594
  }
6594
- if (uploads == null ? void 0 : uploads.file) {
6595
+ if (uploads == null ? void 0 : uploads.File) {
6595
6596
  const fDestination = settings.GlobalSettings.ArchiveSettings.TextDirectory;
6596
6597
  if (fDestination) {
6597
6598
  const file = `${fDestination}/${metadata.name}_${metadata.status}_${metadata.tracking}.txt`.replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
@@ -6606,7 +6607,7 @@ var updateListener = (event) => __async(null, null, function* () {
6606
6607
  }
6607
6608
  metadata.file = metadata.raw;
6608
6609
  }
6609
- if (uploads == null ? void 0 : uploads.event) {
6610
+ if (uploads == null ? void 0 : uploads.JSON) {
6610
6611
  const eDestination = settings.GlobalSettings.ArchiveSettings.EventDirectory;
6611
6612
  if (eDestination) {
6612
6613
  const file = `${eDestination}/${metadata.name}_${metadata.status}_${metadata.tracking}.json`.replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
@@ -6617,37 +6618,34 @@ var updateListener = (event) => __async(null, null, function* () {
6617
6618
  }
6618
6619
  metadata.json = JSON.stringify(getCleanedEvent(event), null, 2);
6619
6620
  }
6620
- if (settings.NotifyServer.Enabled && ((_a = listener2 == null ? void 0 : listener2.notify) == null ? void 0 : _a.enabled) && ((_b = listener2 == null ? void 0 : listener2.notify) == null ? void 0 : _b.topic)) {
6621
- const auth = ((_c = settings.NotifyServer.Credentials) == null ? void 0 : _c.Username) && ((_d = settings.NotifyServer.Credentials) == null ? void 0 : _d.Password) ? {
6622
- username: settings.NotifyServer.Credentials.Username,
6623
- password: settings.NotifyServer.Credentials.Password
6624
- } : void 0;
6625
- const attachment = metadata.eas && settings.NotifyServer.Attachments ? `${settings.NotifyServer.Attachments}/${metadata.name}_${metadata.status}_${metadata.tracking}.wav` : null;
6621
+ if (((_a = settings == null ? void 0 : settings.NotifyServer) == null ? void 0 : _a.Enabled) && (notify == null ? void 0 : notify.Enabled) && (notify == null ? void 0 : notify.Topic)) {
6622
+ const server = settings == null ? void 0 : settings.NotifyServer;
6623
+ const auth = ((_b = server == null ? void 0 : server.Credentials) == null ? void 0 : _b.Username) && ((_c = server == null ? void 0 : server.Credentials) == null ? void 0 : _c.Password) ? { username: (_e = (_d = settings == null ? void 0 : settings.NotifyServer) == null ? void 0 : _d.Credentials) == null ? void 0 : _e.Username, password: (_f = server == null ? void 0 : server.Credentials) == null ? void 0 : _f.Password } : void 0;
6624
+ const attachment = metadata.eas && (server == null ? void 0 : server.Attachments) ? `${server == null ? void 0 : server.Attachments}/${metadata.name}_${metadata.status}_${metadata.tracking}.wav` : void 0;
6626
6625
  yield createHttp(__spreadProps(__spreadValues({
6627
- url: `${settings.NotifyServer.Server.replace(/\/$/, "")}/${(_e = listener2 == null ? void 0 : listener2.notify) == null ? void 0 : _e.topic}`,
6626
+ url: `${(_g = server == null ? void 0 : server.Server) == null ? void 0 : _g.replace(/\/$/, "")}/${(_h = listener2 == null ? void 0 : listener2.NotificationServer) == null ? void 0 : _h.Topic}`,
6628
6627
  timeout: 15e3,
6629
6628
  method: "POST"
6630
6629
  }, auth && { auth }), {
6631
- headers: __spreadProps(__spreadValues({
6630
+ headers: __spreadValues({
6632
6631
  "Title": `${metadata.name} (${metadata.status})`,
6633
- "Tags": (_g = (_f = properties2.parameters.tags) == null ? void 0 : _f.join(",")) != null ? _g : "N/A"
6634
- }, attachment && { "Attach": attachment }), {
6635
- "Priority": "max",
6636
- "Sound": "siren"
6637
- }),
6638
- body: getRaw(event)
6632
+ "Tags": (_j = (_i = properties2.parameters.tags) == null ? void 0 : _i.join(",")) != null ? _j : "N/A",
6633
+ "Expires": new Date(properties2.expires).getTime(),
6634
+ "Priority": (notify == null ? void 0 : notify.Priority) ? notify.Priority.toString() : "5"
6635
+ }, attachment && { "Attach": attachment }),
6636
+ body: getStringText(event)
6639
6637
  }));
6640
6638
  }
6641
- if ((webhook == null ? void 0 : webhook.enabled) && (webhook == null ? void 0 : webhook.destination)) {
6642
- const isRatelimited = setTimeoutAction({ identifier: webhook.destination, interval: ((_h = webhook.ratelimit) != null ? _h : 2) * 2, max: (_i = webhook.ratelimit) != null ? _i : 2, addTime: true });
6639
+ if ((webhook == null ? void 0 : webhook.Enabled) && (webhook == null ? void 0 : webhook.Destination)) {
6640
+ const isRatelimited = setTimeoutAction({ identifier: webhook.Destination, interval: ((_k = webhook.Ratelimit) != null ? _k : 2) * 2, max: (_l = webhook.Ratelimit) != null ? _l : 2, addTime: true });
6643
6641
  const form = new FormData();
6644
6642
  const embed = {
6645
6643
  title: `${metadata.name} (${metadata.status})`,
6646
- description: getEmebed(event),
6644
+ description: getEmebedText(event),
6647
6645
  fields: [],
6648
6646
  color: 16711680,
6649
6647
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
6650
- footer: { text: (_j = webhook.title) != null ? _j : `AtmosphericX` }
6648
+ footer: { text: (_m = webhook.Title) != null ? _m : `AtmosphericX` }
6651
6649
  };
6652
6650
  if (isRatelimited.limited) {
6653
6651
  return;
@@ -6661,32 +6659,32 @@ var updateListener = (event) => __async(null, null, function* () {
6661
6659
  value: metadata.description ? "```\n" + metadata.description.split("\n").map((l) => l.trim()).filter(Boolean).join("\n") + "\n```" : ""
6662
6660
  });
6663
6661
  }
6664
- if (((_k = metadata.attachments) == null ? void 0 : _k.length) > 0) {
6662
+ if (((_n = metadata.attachments) == null ? void 0 : _n.length) > 0) {
6665
6663
  metadata.attachments = metadata.attachments.slice(0, 5);
6666
6664
  embed.fields.push({
6667
6665
  name: "Attachments",
6668
6666
  value: metadata.attachments.map((attachment) => `- [${attachment.name.length > 45 ? attachment.name.substring(0, 45) + "..." : attachment.name}](${attachment.link})`).join("\n")
6669
6667
  });
6670
6668
  }
6671
- if (uploads == null ? void 0 : uploads.file) {
6669
+ if (uploads == null ? void 0 : uploads.File) {
6672
6670
  form.append("fUpload", new Blob([Buffer.from(metadata.file)], { type: "application/text" }), `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.txt`);
6673
6671
  }
6674
- if (uploads == null ? void 0 : uploads.event) {
6672
+ if (uploads == null ? void 0 : uploads.JSON) {
6675
6673
  form.append("fUpload2", new Blob([Buffer.from(metadata.json)], { type: "application/json" }), `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.json`);
6676
6674
  }
6677
- if (uploads == null ? void 0 : uploads.eas) {
6675
+ if (uploads == null ? void 0 : uploads.EAS) {
6678
6676
  if (metadata.eas) {
6679
6677
  const file = (0, import_fs3.readFileSync)(metadata.eas);
6680
6678
  form.append("fEas", new Blob([Buffer.from(file)], { type: "audio/mpeg" }), `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}_eas.mp3`);
6681
6679
  }
6682
6680
  }
6683
6681
  form.append("payload_json", JSON.stringify({
6684
- username: (_l = webhook.title) != null ? _l : "AtmosphericX",
6685
- content: (_m = webhook.message) != null ? _m : "",
6682
+ username: (_o = webhook.Title) != null ? _o : "AtmosphericX",
6683
+ content: (_p = webhook.Message) != null ? _p : "",
6686
6684
  embeds: [embed]
6687
6685
  }));
6688
6686
  yield createHttp({
6689
- url: webhook.destination,
6687
+ url: webhook.Destination,
6690
6688
  timeout: 15e3,
6691
6689
  method: `POST`,
6692
6690
  body: form
@@ -6925,16 +6923,17 @@ var mkEvent = (event) => __async(null, null, function* () {
6925
6923
 
6926
6924
  // src/@manager/manager.rmEvent.ts
6927
6925
  var rmEvent = (event) => __async(null, null, function* () {
6928
- const getEvent = bootstrap.cache.events.features.find((f) => {
6926
+ const gSelect = event;
6927
+ const gEvent = bootstrap.cache.events.features.find((f) => {
6929
6928
  var _a, _b, _c, _d;
6930
6929
  return ((_b = (_a = f == null ? void 0 : f.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.tracking) === ((_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.metadata) == null ? void 0 : _d.tracking);
6931
6930
  });
6932
- const cachedStatus = event.properties.status;
6933
- event.properties.expires = (/* @__PURE__ */ new Date()).toISOString();
6934
- event.properties.status = `Expired`;
6935
- event.properties.status_metadata.is_expired = true;
6936
- if (getEvent) {
6937
- if (!event.properties.status_metadata.is_statement) {
6931
+ const gStatement = event.properties.status_metadata.is_statement;
6932
+ gSelect.properties.expires = (/* @__PURE__ */ new Date()).toISOString();
6933
+ gSelect.properties.status = `Expired`;
6934
+ gSelect.properties.status_metadata.is_expired = true;
6935
+ if (gEvent) {
6936
+ if (!gStatement) {
6938
6937
  setEventEmit({
6939
6938
  event: `onEventStatus`,
6940
6939
  metadata: {
@@ -6945,10 +6944,10 @@ var rmEvent = (event) => __async(null, null, function* () {
6945
6944
  });
6946
6945
  setEventEmit({ event: `onExpiredProduct`, metadata: event });
6947
6946
  }
6948
- if (cachedStatus != `Statement`) yield updateListener(event);
6949
- bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(getEvent), 1);
6947
+ bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(gEvent), 1);
6950
6948
  bootstrap.cache.hashes = bootstrap.cache.hashes.filter((hash) => hash.tracking !== event.properties.metadata.tracking);
6951
6949
  setTimeoutAction({ identifier: event.properties.metadata.tracking, expire: true });
6950
+ if (!gStatement) yield updateListener(gSelect);
6952
6951
  }
6953
6952
  setEventEmit({
6954
6953
  event: `onEventCache`,
@@ -1104,7 +1104,7 @@ var require_main3 = __commonJS({
1104
1104
  import path from "path";
1105
1105
  import { EventEmitter } from "events";
1106
1106
  var bootstrap = {
1107
- version: `3.0.53`,
1107
+ version: `3.0.54`,
1108
1108
  isReady: true,
1109
1109
  ratelimits: {},
1110
1110
  session_xmpp: null,
@@ -6404,8 +6404,8 @@ var setEasTone = (options) => __async(null, null, function* () {
6404
6404
  return outTTS;
6405
6405
  });
6406
6406
 
6407
- // src/@parsers/@text/text.getEmbed.ts
6408
- var getEmebed = (event) => {
6407
+ // src/@parsers/@text/text.getEmbedText.ts
6408
+ var getEmebedText = (event) => {
6409
6409
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na;
6410
6410
  const line = (label, value, condition = true) => condition && value ? `${label} ${value}` : null;
6411
6411
  const isStatement = event.properties.status_metadata.is_statement;
@@ -6442,8 +6442,8 @@ var getEmebed = (event) => {
6442
6442
  ].filter(Boolean).join("\n");
6443
6443
  };
6444
6444
 
6445
- // src/@parsers/@text/text.getRaw.ts
6446
- var getRaw = (event) => {
6445
+ // src/@parsers/@text/text.getStringText.ts
6446
+ var getStringText = (event) => {
6447
6447
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da;
6448
6448
  const line = (label, value, condition = true) => condition && value ? `${label} ${value}` : null;
6449
6449
  const isStatement = event.properties.status_metadata.is_statement;
@@ -6540,7 +6540,7 @@ var getMatched = (strings, string) => {
6540
6540
  // src/@manager/manager.updateListener.ts
6541
6541
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, writeFileSync as writeFileSync3, readFileSync as readFileSync2, appendFileSync } from "fs";
6542
6542
  var updateListener = (event) => __async(null, null, function* () {
6543
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
6543
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
6544
6544
  const tick = performance.now();
6545
6545
  const settings = bootstrap.settings;
6546
6546
  const listeners2 = settings.ListenerSettings;
@@ -6559,19 +6559,20 @@ var updateListener = (event) => __async(null, null, function* () {
6559
6559
  attachments: properties2.metadata.attachments
6560
6560
  };
6561
6561
  for (const listener2 of listeners2) {
6562
- const events = listener2 == null ? void 0 : listener2.events;
6563
- const webhook = listener2 == null ? void 0 : listener2.webhook;
6564
- const uploads = listener2 == null ? void 0 : listener2.uploads;
6562
+ const events = listener2 == null ? void 0 : listener2.Events;
6563
+ const webhook = listener2 == null ? void 0 : listener2.Webhook;
6564
+ const notify = listener2 == null ? void 0 : listener2.NotificationServer;
6565
+ const uploads = listener2 == null ? void 0 : listener2.Uploads;
6565
6566
  const isMatched = getMatched(events != null ? events : [], metadata.name);
6566
6567
  if ((events == null ? void 0 : events.length) == 0 || isMatched) {
6567
- if (uploads == null ? void 0 : uploads.eas) {
6568
+ if (uploads == null ? void 0 : uploads.EAS) {
6568
6569
  metadata.eas = yield setEasTone({
6569
6570
  title: `${metadata.name}_${metadata.status}_${metadata.tracking}`,
6570
6571
  message: metadata.description,
6571
6572
  header: metadata.header
6572
6573
  });
6573
6574
  }
6574
- if (uploads == null ? void 0 : uploads.file) {
6575
+ if (uploads == null ? void 0 : uploads.File) {
6575
6576
  const fDestination = settings.GlobalSettings.ArchiveSettings.TextDirectory;
6576
6577
  if (fDestination) {
6577
6578
  const file = `${fDestination}/${metadata.name}_${metadata.status}_${metadata.tracking}.txt`.replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
@@ -6586,7 +6587,7 @@ var updateListener = (event) => __async(null, null, function* () {
6586
6587
  }
6587
6588
  metadata.file = metadata.raw;
6588
6589
  }
6589
- if (uploads == null ? void 0 : uploads.event) {
6590
+ if (uploads == null ? void 0 : uploads.JSON) {
6590
6591
  const eDestination = settings.GlobalSettings.ArchiveSettings.EventDirectory;
6591
6592
  if (eDestination) {
6592
6593
  const file = `${eDestination}/${metadata.name}_${metadata.status}_${metadata.tracking}.json`.replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
@@ -6597,37 +6598,34 @@ var updateListener = (event) => __async(null, null, function* () {
6597
6598
  }
6598
6599
  metadata.json = JSON.stringify(getCleanedEvent(event), null, 2);
6599
6600
  }
6600
- if (settings.NotifyServer.Enabled && ((_a = listener2 == null ? void 0 : listener2.notify) == null ? void 0 : _a.enabled) && ((_b = listener2 == null ? void 0 : listener2.notify) == null ? void 0 : _b.topic)) {
6601
- const auth = ((_c = settings.NotifyServer.Credentials) == null ? void 0 : _c.Username) && ((_d = settings.NotifyServer.Credentials) == null ? void 0 : _d.Password) ? {
6602
- username: settings.NotifyServer.Credentials.Username,
6603
- password: settings.NotifyServer.Credentials.Password
6604
- } : void 0;
6605
- const attachment = metadata.eas && settings.NotifyServer.Attachments ? `${settings.NotifyServer.Attachments}/${metadata.name}_${metadata.status}_${metadata.tracking}.wav` : null;
6601
+ if (((_a = settings == null ? void 0 : settings.NotifyServer) == null ? void 0 : _a.Enabled) && (notify == null ? void 0 : notify.Enabled) && (notify == null ? void 0 : notify.Topic)) {
6602
+ const server = settings == null ? void 0 : settings.NotifyServer;
6603
+ const auth = ((_b = server == null ? void 0 : server.Credentials) == null ? void 0 : _b.Username) && ((_c = server == null ? void 0 : server.Credentials) == null ? void 0 : _c.Password) ? { username: (_e = (_d = settings == null ? void 0 : settings.NotifyServer) == null ? void 0 : _d.Credentials) == null ? void 0 : _e.Username, password: (_f = server == null ? void 0 : server.Credentials) == null ? void 0 : _f.Password } : void 0;
6604
+ const attachment = metadata.eas && (server == null ? void 0 : server.Attachments) ? `${server == null ? void 0 : server.Attachments}/${metadata.name}_${metadata.status}_${metadata.tracking}.wav` : void 0;
6606
6605
  yield createHttp(__spreadProps(__spreadValues({
6607
- url: `${settings.NotifyServer.Server.replace(/\/$/, "")}/${(_e = listener2 == null ? void 0 : listener2.notify) == null ? void 0 : _e.topic}`,
6606
+ url: `${(_g = server == null ? void 0 : server.Server) == null ? void 0 : _g.replace(/\/$/, "")}/${(_h = listener2 == null ? void 0 : listener2.NotificationServer) == null ? void 0 : _h.Topic}`,
6608
6607
  timeout: 15e3,
6609
6608
  method: "POST"
6610
6609
  }, auth && { auth }), {
6611
- headers: __spreadProps(__spreadValues({
6610
+ headers: __spreadValues({
6612
6611
  "Title": `${metadata.name} (${metadata.status})`,
6613
- "Tags": (_g = (_f = properties2.parameters.tags) == null ? void 0 : _f.join(",")) != null ? _g : "N/A"
6614
- }, attachment && { "Attach": attachment }), {
6615
- "Priority": "max",
6616
- "Sound": "siren"
6617
- }),
6618
- body: getRaw(event)
6612
+ "Tags": (_j = (_i = properties2.parameters.tags) == null ? void 0 : _i.join(",")) != null ? _j : "N/A",
6613
+ "Expires": new Date(properties2.expires).getTime(),
6614
+ "Priority": (notify == null ? void 0 : notify.Priority) ? notify.Priority.toString() : "5"
6615
+ }, attachment && { "Attach": attachment }),
6616
+ body: getStringText(event)
6619
6617
  }));
6620
6618
  }
6621
- if ((webhook == null ? void 0 : webhook.enabled) && (webhook == null ? void 0 : webhook.destination)) {
6622
- const isRatelimited = setTimeoutAction({ identifier: webhook.destination, interval: ((_h = webhook.ratelimit) != null ? _h : 2) * 2, max: (_i = webhook.ratelimit) != null ? _i : 2, addTime: true });
6619
+ if ((webhook == null ? void 0 : webhook.Enabled) && (webhook == null ? void 0 : webhook.Destination)) {
6620
+ const isRatelimited = setTimeoutAction({ identifier: webhook.Destination, interval: ((_k = webhook.Ratelimit) != null ? _k : 2) * 2, max: (_l = webhook.Ratelimit) != null ? _l : 2, addTime: true });
6623
6621
  const form = new FormData();
6624
6622
  const embed = {
6625
6623
  title: `${metadata.name} (${metadata.status})`,
6626
- description: getEmebed(event),
6624
+ description: getEmebedText(event),
6627
6625
  fields: [],
6628
6626
  color: 16711680,
6629
6627
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
6630
- footer: { text: (_j = webhook.title) != null ? _j : `AtmosphericX` }
6628
+ footer: { text: (_m = webhook.Title) != null ? _m : `AtmosphericX` }
6631
6629
  };
6632
6630
  if (isRatelimited.limited) {
6633
6631
  return;
@@ -6641,32 +6639,32 @@ var updateListener = (event) => __async(null, null, function* () {
6641
6639
  value: metadata.description ? "```\n" + metadata.description.split("\n").map((l) => l.trim()).filter(Boolean).join("\n") + "\n```" : ""
6642
6640
  });
6643
6641
  }
6644
- if (((_k = metadata.attachments) == null ? void 0 : _k.length) > 0) {
6642
+ if (((_n = metadata.attachments) == null ? void 0 : _n.length) > 0) {
6645
6643
  metadata.attachments = metadata.attachments.slice(0, 5);
6646
6644
  embed.fields.push({
6647
6645
  name: "Attachments",
6648
6646
  value: metadata.attachments.map((attachment) => `- [${attachment.name.length > 45 ? attachment.name.substring(0, 45) + "..." : attachment.name}](${attachment.link})`).join("\n")
6649
6647
  });
6650
6648
  }
6651
- if (uploads == null ? void 0 : uploads.file) {
6649
+ if (uploads == null ? void 0 : uploads.File) {
6652
6650
  form.append("fUpload", new Blob([Buffer.from(metadata.file)], { type: "application/text" }), `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.txt`);
6653
6651
  }
6654
- if (uploads == null ? void 0 : uploads.event) {
6652
+ if (uploads == null ? void 0 : uploads.JSON) {
6655
6653
  form.append("fUpload2", new Blob([Buffer.from(metadata.json)], { type: "application/json" }), `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.json`);
6656
6654
  }
6657
- if (uploads == null ? void 0 : uploads.eas) {
6655
+ if (uploads == null ? void 0 : uploads.EAS) {
6658
6656
  if (metadata.eas) {
6659
6657
  const file = readFileSync2(metadata.eas);
6660
6658
  form.append("fEas", new Blob([Buffer.from(file)], { type: "audio/mpeg" }), `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}_eas.mp3`);
6661
6659
  }
6662
6660
  }
6663
6661
  form.append("payload_json", JSON.stringify({
6664
- username: (_l = webhook.title) != null ? _l : "AtmosphericX",
6665
- content: (_m = webhook.message) != null ? _m : "",
6662
+ username: (_o = webhook.Title) != null ? _o : "AtmosphericX",
6663
+ content: (_p = webhook.Message) != null ? _p : "",
6666
6664
  embeds: [embed]
6667
6665
  }));
6668
6666
  yield createHttp({
6669
- url: webhook.destination,
6667
+ url: webhook.Destination,
6670
6668
  timeout: 15e3,
6671
6669
  method: `POST`,
6672
6670
  body: form
@@ -6905,16 +6903,17 @@ var mkEvent = (event) => __async(null, null, function* () {
6905
6903
 
6906
6904
  // src/@manager/manager.rmEvent.ts
6907
6905
  var rmEvent = (event) => __async(null, null, function* () {
6908
- const getEvent = bootstrap.cache.events.features.find((f) => {
6906
+ const gSelect = event;
6907
+ const gEvent = bootstrap.cache.events.features.find((f) => {
6909
6908
  var _a, _b, _c, _d;
6910
6909
  return ((_b = (_a = f == null ? void 0 : f.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.tracking) === ((_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.metadata) == null ? void 0 : _d.tracking);
6911
6910
  });
6912
- const cachedStatus = event.properties.status;
6913
- event.properties.expires = (/* @__PURE__ */ new Date()).toISOString();
6914
- event.properties.status = `Expired`;
6915
- event.properties.status_metadata.is_expired = true;
6916
- if (getEvent) {
6917
- if (!event.properties.status_metadata.is_statement) {
6911
+ const gStatement = event.properties.status_metadata.is_statement;
6912
+ gSelect.properties.expires = (/* @__PURE__ */ new Date()).toISOString();
6913
+ gSelect.properties.status = `Expired`;
6914
+ gSelect.properties.status_metadata.is_expired = true;
6915
+ if (gEvent) {
6916
+ if (!gStatement) {
6918
6917
  setEventEmit({
6919
6918
  event: `onEventStatus`,
6920
6919
  metadata: {
@@ -6925,10 +6924,10 @@ var rmEvent = (event) => __async(null, null, function* () {
6925
6924
  });
6926
6925
  setEventEmit({ event: `onExpiredProduct`, metadata: event });
6927
6926
  }
6928
- if (cachedStatus != `Statement`) yield updateListener(event);
6929
- bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(getEvent), 1);
6927
+ bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(gEvent), 1);
6930
6928
  bootstrap.cache.hashes = bootstrap.cache.hashes.filter((hash) => hash.tracking !== event.properties.metadata.tracking);
6931
6929
  setTimeoutAction({ identifier: event.properties.metadata.tracking, expire: true });
6930
+ if (!gStatement) yield updateListener(gSelect);
6932
6931
  }
6933
6932
  setEventEmit({
6934
6933
  event: `onEventCache`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atmosx/event-product-parser",
3
- "version": "3.0.53",
3
+ "version": "3.0.54",
4
4
  "description": "NOAA Weather Wire & NWS API Parser - Built for standalone and Project AtmosphericX Integration.",
5
5
  "main": "dist/cjs/index.cjs",
6
6
  "module": "dist/esm/index.mjs",
@@ -24,15 +24,16 @@ import { setTimeoutAction } from "../@modules/@utilities/utilities.setTimeoutAct
24
24
  import { updateListener } from "./manager.updateListener";
25
25
 
26
26
  export const rmEvent = async (event: TypeEvent): Promise<void> => {
27
- const getEvent = bootstrap.cache.events.features.find(f => f?.properties?.metadata?.tracking === event?.properties?.metadata?.tracking);
28
- const cachedStatus = event.properties.status;
27
+ const gSelect = event;
28
+ const gEvent = bootstrap.cache.events.features.find(f => f?.properties?.metadata?.tracking === event?.properties?.metadata?.tracking);
29
+ const gStatement = event.properties.status_metadata.is_statement
29
30
 
30
- event.properties.expires = new Date().toISOString();
31
- event.properties.status = `Expired`;
32
- event.properties.status_metadata.is_expired = true;
31
+ gSelect.properties.expires = new Date().toISOString();
32
+ gSelect.properties.status = `Expired`;
33
+ gSelect.properties.status_metadata.is_expired = true;
33
34
 
34
- if (getEvent) {
35
- if (!event.properties.status_metadata.is_statement) {
35
+ if (gEvent) {
36
+ if (!gStatement) {
36
37
  setEventEmit({
37
38
  event: `onEventStatus`,
38
39
  metadata: {
@@ -43,10 +44,11 @@ export const rmEvent = async (event: TypeEvent): Promise<void> => {
43
44
  })
44
45
  setEventEmit({ event: `onExpiredProduct`, metadata: event })
45
46
  }
46
- if (cachedStatus != `Statement`) await updateListener(event)
47
- bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(getEvent), 1);
47
+
48
+ bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(gEvent), 1);
48
49
  bootstrap.cache.hashes = bootstrap.cache.hashes.filter(hash => hash.tracking !== event.properties.metadata.tracking);
49
50
  setTimeoutAction({ identifier: event.properties.metadata.tracking, expire: true })
51
+ if (!gStatement) await updateListener(gSelect)
50
52
  }
51
53
 
52
54
  setEventEmit({
@@ -22,8 +22,8 @@ import { TypeListener } from "../@types/type.listener";
22
22
  import { bootstrap } from "../bootstrap"
23
23
  import { setEasTone } from "../@modules/@eas/eas.setEasTone"
24
24
  import { setTimeoutAction } from "../@modules/@utilities/utilities.setTimeoutAction";
25
- import { getEmebed } from "../@parsers/@text/text.getEmbed";
26
- import { getRaw } from "../@parsers/@text/text.getRaw";
25
+ import { getEmebedText } from "../@parsers/@text/text.getEmbedText";
26
+ import { getStringText } from "../@parsers/@text/text.getStringText";
27
27
  import { getCleanedEvent } from "../@building/building.clean"
28
28
  import { createHttp } from "../@modules/@utilities/utilities.createHttp";
29
29
  import { setDebug } from "../@modules/@utilities/utilities.setDebug";
@@ -50,13 +50,14 @@ export const updateListener = async (event: TypeEvent): Promise<void> => {
50
50
  }
51
51
 
52
52
  for (const listener of listeners) {
53
- const events = listener?.events;
54
- const webhook = listener?.webhook;
55
- const uploads = listener?.uploads
53
+ const events = listener?.Events;
54
+ const webhook = listener?.Webhook;
55
+ const notify = listener?.NotificationServer;
56
+ const uploads = listener?.Uploads
56
57
  const isMatched = getMatched(events ?? [], metadata.name)
57
58
 
58
59
  if (events?.length == 0 || isMatched) {
59
- if (uploads?.eas) {
60
+ if (uploads?.EAS) {
60
61
  metadata.eas = await setEasTone({
61
62
  title: `${metadata.name}_${metadata.status}_${metadata.tracking}`,
62
63
  message: metadata.description,
@@ -64,7 +65,7 @@ export const updateListener = async (event: TypeEvent): Promise<void> => {
64
65
  });
65
66
  }
66
67
 
67
- if (uploads?.file) {
68
+ if (uploads?.File) {
68
69
  const fDestination = settings.GlobalSettings.ArchiveSettings.TextDirectory;
69
70
  if (fDestination) {
70
71
  const file = (`${fDestination}/${metadata.name}_${metadata.status}_${metadata.tracking}.txt`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
@@ -78,7 +79,7 @@ export const updateListener = async (event: TypeEvent): Promise<void> => {
78
79
  metadata.file = metadata.raw;
79
80
  }
80
81
 
81
- if (uploads?.event) {
82
+ if (uploads?.JSON) {
82
83
  const eDestination = settings.GlobalSettings.ArchiveSettings.EventDirectory;
83
84
  if (eDestination) {
84
85
  const file = (`${eDestination}/${metadata.name}_${metadata.status}_${metadata.tracking}.json`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
@@ -88,40 +89,36 @@ export const updateListener = async (event: TypeEvent): Promise<void> => {
88
89
  metadata.json = JSON.stringify(getCleanedEvent(event), null, 2);
89
90
  }
90
91
 
91
- if (settings.NotifyServer.Enabled && listener?.notify?.enabled && listener?.notify?.topic) {
92
- const auth = settings.NotifyServer.Credentials?.Username && settings.NotifyServer.Credentials?.Password
93
- ? {
94
- username: settings.NotifyServer.Credentials.Username,
95
- password: settings.NotifyServer.Credentials.Password
96
- }
97
- : undefined;
98
- const attachment = metadata.eas && settings.NotifyServer.Attachments ? `${settings.NotifyServer.Attachments}/${metadata.name}_${metadata.status}_${metadata.tracking}.wav` : null;
92
+ if (settings?.NotifyServer?.Enabled && notify?.Enabled && notify?.Topic) {
93
+ const server = settings?.NotifyServer;
94
+ const auth = server?.Credentials?.Username && server?.Credentials?.Password ? { username: settings?.NotifyServer?.Credentials?.Username, password: server?.Credentials?.Password } : undefined;
95
+ const attachment = metadata.eas && server?.Attachments ? `${server?.Attachments}/${metadata.name}_${metadata.status}_${metadata.tracking}.wav` : undefined;
99
96
  await createHttp({
100
- url: `${settings.NotifyServer.Server.replace(/\/$/, "")}/${listener?.notify?.topic}`,
97
+ url: `${server?.Server?.replace(/\/$/, "")}/${listener?.NotificationServer?.Topic}`,
101
98
  timeout: 15_000,
102
99
  method: "POST",
103
100
  ...(auth && { auth }),
104
101
  headers: {
105
102
  "Title": `${metadata.name} (${metadata.status})`,
106
103
  "Tags": properties.parameters.tags?.join(",") ?? "N/A",
104
+ "Expires": new Date(properties.expires).getTime(),
105
+ "Priority": notify?.Priority ? notify.Priority.toString() : "5",
107
106
  ... (attachment && { "Attach": attachment }),
108
- "Priority": "max",
109
- "Sound": "siren",
110
107
  },
111
- body: getRaw(event)
108
+ body: getStringText(event)
112
109
  })
113
110
  }
114
111
 
115
- if (webhook?.enabled && webhook?.destination) {
116
- const isRatelimited = setTimeoutAction({ identifier: webhook.destination, interval: (webhook.ratelimit ?? 2) * 2, max: (webhook.ratelimit ?? 2), addTime: true })
112
+ if (webhook?.Enabled && webhook?.Destination) {
113
+ const isRatelimited = setTimeoutAction({ identifier: webhook.Destination, interval: (webhook.Ratelimit ?? 2) * 2, max: (webhook.Ratelimit ?? 2), addTime: true })
117
114
  const form = new FormData();
118
115
  const embed = {
119
116
  title: `${metadata.name} (${metadata.status})`,
120
- description: getEmebed(event),
117
+ description: getEmebedText(event),
121
118
  fields: [],
122
119
  color: 16711680,
123
120
  timestamp: new Date().toISOString(),
124
- footer: { text: webhook.title ?? `AtmosphericX` }
121
+ footer: { text: webhook.Title ?? `AtmosphericX` }
125
122
  };
126
123
 
127
124
  if (isRatelimited.limited) { return }
@@ -146,15 +143,15 @@ export const updateListener = async (event: TypeEvent): Promise<void> => {
146
143
  });
147
144
  }
148
145
 
149
- if (uploads?.file) {
146
+ if (uploads?.File) {
150
147
  form.append("fUpload", new Blob([Buffer.from(metadata.file)], {type: "application/text"}), `${properties.event}_${properties.status}_${properties.metadata.tracking}.txt`)
151
148
  }
152
149
 
153
- if (uploads?.event) {
150
+ if (uploads?.JSON) {
154
151
  form.append("fUpload2", new Blob([Buffer.from(metadata.json)], {type: "application/json"}), `${properties.event}_${properties.status}_${properties.metadata.tracking}.json`)
155
152
  }
156
153
 
157
- if (uploads?.eas) {
154
+ if (uploads?.EAS) {
158
155
  if (metadata.eas) {
159
156
  const file = readFileSync(metadata.eas)
160
157
  form.append("fEas", new Blob([Buffer.from(file)], { type: "audio/mpeg" }), `${properties.event}_${properties.status}_${properties.metadata.tracking}_eas.mp3`)
@@ -162,13 +159,13 @@ export const updateListener = async (event: TypeEvent): Promise<void> => {
162
159
  }
163
160
 
164
161
  form.append("payload_json", JSON.stringify({
165
- username: webhook.title ?? "AtmosphericX",
166
- content: webhook.message ?? "",
162
+ username: webhook.Title ?? "AtmosphericX",
163
+ content: webhook.Message ?? "",
167
164
  embeds: [embed]
168
165
  }));
169
166
 
170
167
  await createHttp({
171
- url: webhook.destination,
168
+ url: webhook.Destination,
172
169
  timeout: 15e3,
173
170
  method: `POST`,
174
171
  body: form
@@ -19,7 +19,7 @@
19
19
 
20
20
  import { TypeEvent } from "../../@types/type.event"
21
21
 
22
- export const getEmebed = (event: TypeEvent): string => {
22
+ export const getEmebedText = (event: TypeEvent): string => {
23
23
  const line = (label: string, value: unknown, condition = true) => condition && value ? `${label} ${value}` : null;
24
24
  const isStatement = event.properties.status_metadata.is_statement;
25
25
  const isExpired = event.properties.status_metadata.is_expired;
@@ -19,7 +19,7 @@
19
19
 
20
20
  import { TypeEvent } from "../../@types/type.event"
21
21
 
22
- export const getRaw = (event: TypeEvent): string => {
22
+ export const getStringText = (event: TypeEvent): string => {
23
23
  const line = (label: string, value: unknown, condition = true) => condition && value ? `${label} ${value}` : null;
24
24
  const isStatement = event.properties.status_metadata.is_statement;
25
25
  const isExpired = event.properties.status_metadata.is_expired;
@@ -18,20 +18,21 @@
18
18
  */
19
19
 
20
20
  export type TypeListener = {
21
- events: string[]
22
- webhook?: {
23
- enabled: boolean
24
- destination: string
25
- ratelimit: number
26
- title: string
27
- message: string
21
+ Events: string[]
22
+ Webhook?: {
23
+ Enabled: boolean
24
+ Destination: string
25
+ Ratelimit: number
26
+ Title: string
27
+ Message: string
28
28
  }
29
- notify?: {
30
- enabled: boolean
31
- topic: string
29
+ NotificationServer?: {
30
+ Enabled: boolean
31
+ Topic: string
32
+ Priority?: 1 | 2 | 3 | 4 | 5 | void
32
33
  }
33
- uploads?: {
34
- file?: boolean, eas?: boolean, event?: boolean
34
+ Uploads?: {
35
+ File?: boolean, EAS?: boolean, JSON?: boolean
35
36
  }
36
37
 
37
38
  }
package/src/bootstrap.ts CHANGED
@@ -21,7 +21,7 @@ import path from 'path'
21
21
  import { EventEmitter } from 'node:events';
22
22
 
23
23
  export const bootstrap = {
24
- version: `3.0.53`,
24
+ version: `3.0.54`,
25
25
  isReady: true,
26
26
  ratelimits: {},
27
27
  session_xmpp: null,
package/testing/init.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const { Manager } = require(`../dist/cjs/index.cjs`)
2
2
 
3
3
  const Client = new Manager({
4
- Database: `shapefiles.db`,
4
+ Database: `event-product-parser.db`,
5
5
  EnableWireService: false,
6
6
  EnableJournal: true,
7
7
  EnableDebugging: false,
@@ -17,8 +17,8 @@ const Client = new Manager({
17
17
  },
18
18
  CacheSettings: {
19
19
  Enabled: true,
20
- MaxDatabaseHistory: 5000,
21
- MaxRetentionHistory: 555,
20
+ MaxDatabaseHistory: 50000,
21
+ MaxRetentionHistory: 1500,
22
22
  },
23
23
  StanzaSettings: {
24
24
  DisableUGC: false,
@@ -32,12 +32,13 @@ const Client = new Manager({
32
32
  },
33
33
  BroadcastifySettings: {
34
34
  BroadcastifyAttachments: true,
35
+ BroadcastifyDatabase: `https://scriptkitty.cafe/ftp/@atmosphericx/assets/broadcastify.json`,
35
36
  BroadcastifyTags: [`Public Safety`, `Amateur Radio`, `Other`, `Rail`, `Aviation`, `Marine`, `Disaster Event`, `Special Event`]
36
37
  },
37
38
  NotifyServer: {
38
39
  Enabled: false,
39
- Server: "https://ntfy.domainname.com",
40
- Attachments: "https://domainname.com/Storage/EasScenarios",
40
+ Server: "https://ntfy.scriptkitty.cafe",
41
+ Attachments: "https://scriptkitty.cafe/ftp/@bucket/EAS/encoded",
41
42
  Credentials: {
42
43
  Username: "username",
43
44
  Password: "password"
@@ -45,22 +46,16 @@ const Client = new Manager({
45
46
  },
46
47
  ListenerSettings: [
47
48
  {
48
- events: [`*Thunderstorm Warning*`, `* Watch`],
49
- webhook: {
50
- enabled: true,
51
- destination: "https://discord.com/api/XXXXXXXXXX/XXXXXXXXXXX",
52
- title: "AtmosphericX - (Thunderstorm Warnings and Watches)",
53
- message: "<@&XXXXXXXXXXXXXXXXXXXXX>",
54
- ratelimit: 1
49
+ Events: ["*Extreme Heat Warning*"],
50
+ NotificationServer: {
51
+ Enabled: false,
52
+ Topic: "heat-warnings",
53
+ Priority: 5
55
54
  },
56
- notify: {
57
- enabled: false,
58
- topic: "thunderstorm_events",
59
- },
60
- uploads: {
61
- eas: true,
62
- file: true,
63
- event: true
55
+ Uploads: {
56
+ EAS: true,
57
+ File: true,
58
+ JSON: true
64
59
  }
65
60
  }
66
61
  ],
@@ -72,35 +67,25 @@ const Client = new Manager({
72
67
  SPCWatchesOnly: true,
73
68
  ShapefileSkipPoints: 0,
74
69
  NodeTTL: 60,
75
- NodeMinDistance: 120,
70
+ NodeMinDistance: 125,
76
71
  EventFiltering: {
77
72
  ListeningEvents: [
78
- "*Severe Thunderstorm Warning*",
79
- "*Blizzard*", "*Ice Storm*", "*Winter Storm*", "*Snow Squall*",
80
- "Tornado Emergency", "*Tornado Warning*",
81
- "Special Weather Statement", "Marine Weather Statement",
82
- "*Tsunami*", "*Hurricane*", "*Tropical Storm*", "*Special Marine*",
83
- "*Flash Flood Warning*", "*Flash Flood Watch*", "*Flash Flood Advisory*",
84
- "Mesoscale Discussion",
85
- "*Storm Prediction Center*",
86
- "PDS Tornado Watch", "Tornado Watch", "Severe Thunderstorm Watch", "Flash Flood Watch", "PDS Severe Thunderstorm Watch",
87
- "*Administrative*", "National Weather Service Policy",
88
- "Fire Weather Warning", "Fire Weather Watch", "Fire Weather Advisory",
73
+ "*Warning*"
89
74
  ],
90
- ListeningICAO: [`KLOT`],
75
+ ListeningICAO: [],
76
+ ListeningUGC: [],
77
+ ListeningStates: [],
91
78
  IgnoredICAO: [],
92
79
  IgnoredEvents: [],
93
- ListeningUGC: [`WIC001`],
94
- ListeningStates: [`MO`, `IA`],
95
80
  NodeLocationFiltering: false,
96
81
  IgnoreTestProducts: true,
97
82
  },
98
83
  ArchiveSettings: {
99
- TTL: 600,
100
- EventDirectory: `Storage/EventProducts`,
101
- TextDirectory: `Storage/TextProducts`,
102
- EasDirectory: `Storage/EasScenarios`,
103
- EasToneout: `tone.wav`,
84
+ TTL: 30,
85
+ EventDirectory: `@bucket/ParsedProducts`,
86
+ TextDirectory: `@bucket/RawTextProducts`,
87
+ EasDirectory: `@bucket/EAS`,
88
+ EasToneout: `eas-toneout.wav`,
104
89
  }
105
90
  }
106
- })
91
+ })