wingbot 3.73.11 → 3.73.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wingbot",
3
- "version": "3.73.11",
3
+ "version": "3.73.12",
4
4
  "description": "Enterprise Messaging Bot Conversation Engine",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
package/src/BotApp.js CHANGED
@@ -231,6 +231,7 @@ class BotApp {
231
231
 
232
232
  const { onInteraction, onEvent } = onInteractionHandler({
233
233
  log,
234
+ // @ts-ignore
234
235
  anonymize: this._textFilter,
235
236
  snapshot,
236
237
  botId,
@@ -34,8 +34,19 @@ const ReturnSender = require('./ReturnSender');
34
34
  * @typedef {BotAppSenderOptions & ReturnSenderOptions} SenderOptions
35
35
  */
36
36
 
37
+ /**
38
+ * @typedef {object} DownloadedFile
39
+ * @prop {string} fileName
40
+ * @prop {string} mimeType
41
+ * @prop {string} extension
42
+ * @prop {Buffer} buffer
43
+ */
44
+
37
45
  const sign = promisify(jwt.sign);
38
46
 
47
+ const CONTENT_DISPO_ATTACH = /attachment;\s*filename="([^"]+)\.([a-z0-9]{2,6})"/i;
48
+ const FILENAME_MATCHER = /^http.+\/([a-zA-Z0-9-]+)_[a-zA-Z0-9]+(\.([a-zA-Z0-9]+)?)$/i;
49
+
39
50
  class BotAppSender extends ReturnSender {
40
51
 
41
52
  /**
@@ -60,21 +71,26 @@ class BotAppSender extends ReturnSender {
60
71
  this._tls = options.tls;
61
72
  this._agent = null;
62
73
 
74
+ /** @type {import('node-fetch').default} */
75
+ // @ts-ignore
63
76
  this._fetch = options.fetch || fetch;
64
77
  }
65
78
 
66
79
  static async signBody (body, secret, appId) {
67
80
  const goodSecret = await Promise.resolve(secret);
68
81
 
69
- const sha1 = crypto.createHash('sha1')
70
- .update(body)
71
- .digest('hex');
82
+ const sha1 = body === null
83
+ ? null
84
+ : crypto.createHash('sha1')
85
+ .update(body)
86
+ .digest('hex');
72
87
 
73
88
  return sign({
74
89
  appId,
75
90
  sha1,
76
91
  iss: 'apiapp',
77
92
  t: 'at'
93
+ // @ts-ignore
78
94
  }, goodSecret);
79
95
  }
80
96
 
@@ -93,6 +109,52 @@ class BotAppSender extends ReturnSender {
93
109
  return this._agent;
94
110
  }
95
111
 
112
+ /**
113
+ *
114
+ * @param {string} url
115
+ * @returns {Promise<DownloadedFile>}
116
+ */
117
+ async download (url) {
118
+ const [token, agent] = await Promise.all([
119
+ BotAppSender.signBody(null, this._secret, this._appId),
120
+ this._getAgent()
121
+ ]);
122
+
123
+ const headers = new Headers();
124
+
125
+ headers.set('Authorization', token);
126
+
127
+ const res = await this._fetch(url, {
128
+ headers, agent, method: 'GET'
129
+ });
130
+
131
+ // 'Content-Disposition': `attachment; filename="${file.origFileName}"`
132
+ const disposition = res.headers.get('content-disposition');
133
+
134
+ let name;
135
+ let extension;
136
+ if (disposition && disposition.match(CONTENT_DISPO_ATTACH)) {
137
+ [, name, extension] = disposition.match(CONTENT_DISPO_ATTACH);
138
+ } else if (url.match(FILENAME_MATCHER)) {
139
+ [, name, extension] = url.match(FILENAME_MATCHER);
140
+ } else {
141
+ throw new Error(`Can't resolve file extension on "${disposition || url}"`);
142
+ }
143
+
144
+ const mimeType = res.headers.get('content-type');
145
+
146
+ const buffer = await res.buffer();
147
+
148
+ const fileName = `${name}.${extension.toLowerCase()}`;
149
+
150
+ return {
151
+ mimeType,
152
+ fileName,
153
+ extension,
154
+ buffer
155
+ };
156
+ }
157
+
96
158
  /**
97
159
  *
98
160
  * @param {Buffer} data
package/src/Responder.js CHANGED
@@ -29,6 +29,7 @@ const EXCEPTION_HOPCOUNT_THRESHOLD = 5;
29
29
  /** @typedef {import('./ReturnSender').UploadResult} UploadResult */
30
30
  /** @typedef {import('./ReturnSender').SendOptions} SendOptions */
31
31
  /** @typedef {import('./ReturnSender').TextFilter} TextFilter */
32
+ /** @typedef {import('./BotAppSender').DownloadedFile} DownloadedFile */
32
33
  /** @typedef {import('./analytics/consts').TrackingCategory} TrackingCategory */
33
34
  /** @typedef {import('./transcript/transcriptFromHistory').Transcript} Transcript */
34
35
  /** @typedef {import('./analytics/consts').TrackingType} TrackingType */
@@ -1274,6 +1275,19 @@ class Responder {
1274
1275
  return ret;
1275
1276
  }
1276
1277
 
1278
+ /**
1279
+ *
1280
+ * @param {string} url
1281
+ * @returns {Promise<DownloadedFile>}
1282
+ */
1283
+ async dowloadFromChat (url) {
1284
+ if (typeof this._messageSender.download !== 'function') {
1285
+ throw new Error('Message sender doesn\'t support dowload method');
1286
+ }
1287
+ const fileData = await this._messageSender.download(url);
1288
+ return fileData;
1289
+ }
1290
+
1277
1291
  /**
1278
1292
  *
1279
1293
  * @param {Buffer} data