@jambonz/time-series 0.1.8 → 0.1.11

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/index.js CHANGED
@@ -5,6 +5,7 @@ const AlertType = {
5
5
  WEBHOOK_CONNECTION_FAILURE: 'webhook-connection-failure',
6
6
  WEBHOOK_URL_NOTFOUND: 'webhook-url-notfound',
7
7
  WEBHOOK_AUTH_FAILURE: 'webhook-auth-failure',
8
+ INVALID_APP_PAYLOAD: 'invalid-app-payload',
8
9
  TTS_NOT_PROVISIONED: 'no-tts',
9
10
  STT_NOT_PROVISIONED: 'no-stt',
10
11
  TTS_FAILURE: 'tts-failure',
@@ -79,85 +80,81 @@ const writeData = async(client) => {
79
80
  }
80
81
  };
81
82
 
82
- const createCallCountsQuery = ({account_sid, page, page_size, days, start, end}) => {
83
- let sql = `SELECT * from call_counts WHERE account_sid = '${account_sid}'`;
84
- if (days) sql += `AND time > now() - ${days}d `;
83
+ const createCallCountsQuery = ({page, page_size, days, start, end}) => {
84
+ let sql = 'SELECT * from call_counts WHERE account_sid = $account_sid ';
85
+ if (days) sql += 'AND time > $timestamp ';
85
86
  else {
86
- if (start) sql += `AND time >= '${start}' `;
87
- if (end) sql += `AND time <= '${end}' `;
87
+ if (start) sql += 'AND time >= $start ';
88
+ if (end) sql += 'AND time <= $end ';
88
89
  }
89
90
  sql += ' ORDER BY time DESC';
90
- if (page_size) sql += ` LIMIT ${page_size}`;
91
- if (page) sql += ` OFFSET ${(page - 1) * page_size}`;
92
- //console.log(sql);
91
+ if (page_size) sql += ' LIMIT $page_size';
92
+ if (page) sql += ' OFFSET $offset';
93
93
  return sql;
94
94
  };
95
95
 
96
- const createCallCountsCountQuery = ({account_sid, days, start, end}) => {
97
- let sql = `SELECT COUNT(calls_in_progress) from call_counts WHERE account_sid = '${account_sid}' `;
98
- if (days) sql += `AND time > now() - ${days}d `;
96
+ const createCallCountsCountQuery = ({days, start, end}) => {
97
+ let sql = 'SELECT COUNT(calls_in_progress) from call_counts WHERE account_sid = $account_sid ';
98
+ if (days) sql += 'AND time > $timestamp ';
99
99
  else {
100
- if (start) sql += `AND time >= '${start}' `;
101
- if (end) sql += `AND time <= '${end}' `;
100
+ if (start) sql += 'AND time >= $start ';
101
+ if (end) sql += 'AND time <= $end ';
102
102
  }
103
- //console.log(sql);
104
103
  return sql;
105
104
  };
106
105
 
107
- const createCdrQuery = ({account_sid, page, page_size, trunk, direction, answered, days, start, end}) => {
108
- let sql = `SELECT * from cdrs WHERE account_sid = '${account_sid}'`;
109
- if (trunk) sql += `AND trunk = '${trunk}' `;
110
- if (direction) sql += `AND direction = '${direction}' `;
111
- if (['true', 'false'].includes(answered)) sql += `AND answered = '${answered}' `;
112
- if (days) sql += `AND time > now() - ${days}d `;
106
+ const createCdrQuery = ({page, page_size, trunk, direction, answered, days, start, end}) => {
107
+ let sql = 'SELECT * from cdrs WHERE account_sid = $account_sid ';
108
+ if (trunk) sql += 'AND trunk = $trunk ';
109
+ if (direction) sql += 'AND direction = $direction ';
110
+ if (['true', 'false'].includes(answered)) sql += 'AND answered = $answered ';
111
+ if (days) sql += 'AND time > $timestamp ';
113
112
  else {
114
- if (start) sql += `AND time >= '${start}' `;
115
- if (end) sql += `AND time <= '${end}' `;
113
+ if (start) sql += 'AND time >= $start ';
114
+ if (end) sql += 'AND time <= $end ';
116
115
  }
117
116
  sql += ' ORDER BY time DESC';
118
- if (page_size) sql += ` LIMIT ${page_size}`;
119
- if (page) sql += ` OFFSET ${(page - 1) * page_size}`;
120
- //console.log(sql);
117
+ if (page_size) sql += ' LIMIT $page_size';
118
+ if (page) sql += ' OFFSET $offset';
121
119
  return sql;
122
120
  };
123
- const createCdrCountQuery = ({account_sid, trunk, direction, answered, days, start, end}) => {
124
- let sql = `SELECT COUNT(sip_callid) from cdrs WHERE account_sid = '${account_sid}' `;
125
- if (trunk) sql += `AND trunk = '${trunk}' `;
126
- if (direction) sql += `AND direction = '${direction}' `;
127
- if (['true', 'false'].includes(answered)) sql += `AND answered = '${answered}' `;
128
- if (days) sql += `AND time > now() - ${days}d `;
121
+ const createCdrCountQuery = ({trunk, direction, answered, days, start, end}) => {
122
+ let sql = 'SELECT COUNT(sip_callid) from cdrs WHERE account_sid = $account_sid ';
123
+ if (trunk) sql += 'AND trunk = $trunk ';
124
+ if (direction) sql += 'AND direction = $direction ';
125
+ if (['true', 'false'].includes(answered)) sql += 'AND answered = $answered ';
126
+ if (days) sql += 'AND time > $timestamp ';
129
127
  else {
130
- if (start) sql += `AND time >= '${start}' `;
131
- if (end) sql += `AND time <= '${end}' `;
128
+ if (start) sql += 'AND time >= $start ';
129
+ if (end) sql += 'AND time <= $end ';
132
130
  }
133
- //console.log(sql);
134
131
  return sql;
135
132
  };
136
133
 
137
- const createAlertsQuery = ({account_sid, alert_type, page, page_size, days, start, end}) => {
138
- let sql = `SELECT * FROM alerts WHERE account_sid = '${account_sid}' `;
139
- if (alert_type) sql += `AND alert_type = '${alert_type}' `;
140
- if (days) sql += `AND time > now() - ${days}d `;
134
+ const createAlertsQuery = ({target_sid, alert_type, page, page_size, days, start, end}) => {
135
+ let sql = 'SELECT * FROM alerts WHERE account_sid = $account_sid ';
136
+ if (target_sid) sql += 'AND target_sid = $target_sid ';
137
+ if (alert_type) sql += 'AND alert_type = $alert_type ';
138
+ if (days) sql += 'AND time > $timestamp ';
141
139
  else {
142
- if (start) sql += `AND time >= '${start}' `;
143
- if (end) sql += `AND time <= '${end}' `;
140
+ if (start) sql += 'AND time >= $start ';
141
+ if (end) sql += 'AND time <= $end ';
144
142
  }
145
143
  sql += ' ORDER BY time DESC';
146
- if (page_size) sql += ` LIMIT ${page_size}`;
147
- if (page) sql += ` OFFSET ${(page - 1) * page_size}`;
148
- //console.log(sql);
144
+ if (page_size) sql += ' LIMIT $page_size';
145
+ if (page) sql += ' OFFSET $offset';
149
146
  return sql;
150
147
  };
151
148
 
152
- const createAlertsCountQuery = ({account_sid, alert_type, days, start, end}) => {
153
- let sql = `SELECT COUNT(message) FROM alerts WHERE account_sid = '${account_sid}' `;
154
- if (alert_type) sql += `AND alert_type = '${alert_type}' `;
155
- if (days) sql += `AND time > now() - ${days}d `;
149
+ const createAlertsCountQuery = ({target_sid, alert_type, days, start, end}) => {
150
+ let sql = 'SELECT COUNT(message) FROM alerts WHERE account_sid = $account_sid ';
151
+ if (target_sid) sql += 'AND target_sid = $target_sid ';
152
+ if (alert_type) sql += 'AND alert_type = $alert_type ';
153
+ if (days) sql += 'AND time > $timestamp ';
156
154
  else {
157
- if (start) sql += `AND time >= '${start}' `;
158
- if (end) sql += `AND time <= '${end}' `;
155
+ if (start) sql += 'AND time >= $start ';
156
+ if (end) sql += 'AND time <= $end ';
159
157
  }
160
- //console.log(sql);
161
158
  return sql;
162
159
  };
163
160
 
@@ -194,14 +191,15 @@ const queryCallCounts = async(client, opts) => {
194
191
  page: opts.page,
195
192
  data: []
196
193
  };
194
+ const params = generateBindParameters(opts);
197
195
  const sqlTotal = createCallCountsCountQuery(opts);
198
- const obj = await client.queryRaw(sqlTotal);
196
+ const obj = await client.queryRaw(sqlTotal, { placeholders: params});
199
197
  //console.log(`sqlTotal: ${sqlTotal}, results: ${JSON.stringify(obj)}`);
200
198
  if (!obj.results || !obj.results[0].series) return response;
201
199
  response.total = obj.results[0].series[0].values[0][1];
202
200
 
203
201
  const sql = createCallCountsQuery(opts);
204
- const res = await client.queryRaw(sql);
202
+ const res = await client.queryRaw(sql, { placeholders: params});
205
203
  //console.log(`sql: ${sqlTotal}, results: ${JSON.stringify(res)}`);
206
204
  if (res.results[0].series && res.results[0].series.length) {
207
205
  const {columns, values} = res.results[0].series[0];
@@ -254,14 +252,15 @@ const queryCdrs = async(client, opts) => {
254
252
  page: opts.page,
255
253
  data: []
256
254
  };
255
+ const params = generateBindParameters(opts);
257
256
  const sqlTotal = createCdrCountQuery(opts);
258
- const obj = await client.queryRaw(sqlTotal);
257
+ const obj = await client.queryRaw(sqlTotal, { placeholders: params});
259
258
  //console.log(`sql: ${sqlTotal}, results: ${JSON.stringify(obj)}`);
260
259
  if (!obj.results || !obj.results[0].series) return response;
261
260
  response.total = obj.results[0].series[0].values[0][1];
262
261
 
263
262
  const sql = createCdrQuery(opts);
264
- const res = await client.queryRaw(sql);
263
+ const res = await client.queryRaw(sql, { placeholders: params});
265
264
  if (res.results[0].series && res.results[0].series.length) {
266
265
  const {columns, values} = res.results[0].series[0];
267
266
  const data = values.map((v) => {
@@ -284,7 +283,7 @@ const writeAlerts = async(client, alerts) => {
284
283
  if (!client.locals.initialized) await initDatabase(client, 'alerts');
285
284
  alerts = (Array.isArray(alerts) ? alerts : [alerts])
286
285
  .map((alert) => {
287
- const {alert_type, account_sid, url, status, vendor, count, detail, timestamp} = alert;
286
+ const {alert_type, account_sid, target_sid, url, status, vendor, count, detail, timestamp} = alert;
288
287
  let message = alert.message;
289
288
  if (!message) {
290
289
  switch (alert_type) {
@@ -300,6 +299,9 @@ const writeAlerts = async(client, alerts) => {
300
299
  case AlertType.WEBHOOK_URL_NOTFOUND:
301
300
  message = `webhook url not found: ${url}`;
302
301
  break;
302
+ case AlertType.INVALID_APP_PAYLOAD:
303
+ message = `${url} return invalid app payload`;
304
+ break;
303
305
  case AlertType.TTS_NOT_PROVISIONED:
304
306
  message = `text to speech credentials for ${vendor} have not been provisioned`;
305
307
  break;
@@ -329,7 +331,9 @@ const writeAlerts = async(client, alerts) => {
329
331
  break;
330
332
  }
331
333
  }
332
- const obj = {measurement: 'alerts', fields: { message }, tags: { alert_type, account_sid }};
334
+ let fields = { message };
335
+ if (target_sid) fields = Object.assign(fields, {target_sid});
336
+ const obj = {measurement: 'alerts', fields: fields, tags: { alert_type, account_sid }};
333
337
  if (timestamp) obj.timestamp = timestamp;
334
338
  if (detail) obj.fields.detail = detail;
335
339
  return obj;
@@ -342,6 +346,13 @@ const writeAlerts = async(client, alerts) => {
342
346
  return;
343
347
  };
344
348
 
349
+ const generateBindParameters = (opts) => {
350
+ const params = {...opts};
351
+ if (opts.days) params.timestamp = Date.now() * 1000000 - opts.days * 24 * 60 * 60 * 1000000000;
352
+ if (opts.page) params.offset = opts.page - 1 >= 0 && opts.page_size >= 0 ? (opts.page - 1) * opts.page_size : 0;
353
+ return params;
354
+ };
355
+
345
356
  const queryAlerts = async(client, opts) => {
346
357
  if (!client.locals.initialized) await initDatabase(client, 'alerts');
347
358
  const response = {
@@ -350,14 +361,15 @@ const queryAlerts = async(client, opts) => {
350
361
  page: opts.page,
351
362
  data: []
352
363
  };
364
+ const params = generateBindParameters(opts);
353
365
  const sqlTotal = createAlertsCountQuery(opts);
354
- const obj = await client.queryRaw(sqlTotal);
366
+ const obj = await client.queryRaw(sqlTotal, { placeholders: params});
355
367
  //console.log(`query total alerts: ${sqlTotal}: ${JSON.stringify(obj)}`);
356
368
  if (!obj.results || !obj.results[0].series) return response;
357
369
  response.total = obj.results[0].series[0].values[0][1];
358
370
 
359
371
  const sql = createAlertsQuery(opts);
360
- const res = await client.queryRaw(sql);
372
+ const res = await client.queryRaw(sql, { placeholders: params});
361
373
  if (res.results[0].series && res.results[0].series.length) {
362
374
  const {columns, values} = res.results[0].series[0];
363
375
  const data = values.map((v) => {
@@ -379,6 +391,7 @@ module.exports = (logger, opts) => {
379
391
 
380
392
  const cdrClient = new Influx.InfluxDB({database: 'cdrs', schemas: schemas.cdr, ...opts});
381
393
  const alertClient = new Influx.InfluxDB({database: 'alerts', schemas: schemas.alerts, ...opts});
394
+ const callCountClient = new Influx.InfluxDB({database: 'call_counts', schemas: schemas.call_counts, ...opts});
382
395
 
383
396
  cdrClient.locals = {
384
397
  db: 'cdrs',
@@ -396,15 +409,24 @@ module.exports = (logger, opts) => {
396
409
  commitInterval: opts.commitInterval || 10,
397
410
  data: []
398
411
  };
412
+ callCountClient.locals = {
413
+ db: 'call_counts',
414
+ initialized: false,
415
+ writing: false,
416
+ commitSize: opts.commitSize || 1,
417
+ commitInterval: opts.commitInterval || 10,
418
+ data: []
419
+ };
399
420
 
400
421
  if (opts.commitSize > 1 && opts.commitInterval && opts.commitInterval > 2) {
422
+ setInterval(writeData.bind(null, callCountClient), opts.commitInterval * 1000);
401
423
  setInterval(writeData.bind(null, cdrClient), opts.commitInterval * 1000);
402
424
  setInterval(writeData.bind(null, alertClient), opts.commitInterval * 1000);
403
425
  }
404
426
 
405
427
  return {
406
- writeCallCount: writeCallCount.bind(null, cdrClient),
407
- queryCallCounts: queryCallCounts.bind(null, cdrClient),
428
+ writeCallCount: writeCallCount.bind(null, callCountClient),
429
+ queryCallCounts: queryCallCounts.bind(null, callCountClient),
408
430
  writeCdrs: writeCdrs.bind(null, cdrClient),
409
431
  queryCdrs: queryCdrs.bind(null, cdrClient),
410
432
  writeAlerts: writeAlerts.bind(null, alertClient),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jambonz/time-series",
3
- "version": "0.1.8",
3
+ "version": "0.1.11",
4
4
  "description": "write and query data to time series daetabase",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -12,7 +12,7 @@
12
12
  "license": "MIT",
13
13
  "dependencies": {
14
14
  "debug": "^4.3.1",
15
- "influx": "^5.8.0"
15
+ "influx": "^5.9.3"
16
16
  },
17
17
  "devDependencies": {
18
18
  "eslint": "^7.23.0",
@@ -73,6 +73,12 @@ test('write timeseries data', async(t) => {
73
73
  account_sid: 'yyyy',
74
74
  url: 'http://foo.bar'
75
75
  },
76
+ {
77
+ alert_type: AlertType.INVALID_APP_PAYLOAD,
78
+ account_sid: 'yyyy',
79
+ target_sid: 'zzzz',
80
+ message: 'invalid app payload'
81
+ },
76
82
  {
77
83
  alert_type: AlertType.TTS_NOT_PROVISIONED,
78
84
  account_sid: 'yyyy',
@@ -117,7 +123,12 @@ test('write timeseries data', async(t) => {
117
123
 
118
124
  result = await queryAlerts({account_sid: 'yyyy', page: 1, page_size: 25, days: 7});
119
125
  //console.log(JSON.stringify(result));
120
- t.ok(result.data.length === 11, 'queried alerts');
126
+ t.ok(result.data.length === 12, 'queried alerts');
127
+ t.ok(result.data[0].target_sid === null)
128
+
129
+ result = await queryAlerts({account_sid: 'yyyy', target_sid: 'zzzz', page: 1, page_size: 25, days: 7});
130
+ t.ok(result.data.length === 1, 'queried alerts by target_sid');
131
+ t.ok(result.data[0].target_sid === 'zzzz')
121
132
 
122
133
  result = await writeCallCount(
123
134
  {