wingbot 3.73.11 → 3.73.13
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 +1 -1
- package/src/BotApp.js +1 -0
- package/src/BotAppSender.js +65 -3
- package/src/Responder.js +14 -0
package/package.json
CHANGED
package/src/BotApp.js
CHANGED
package/src/BotAppSender.js
CHANGED
|
@@ -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 =
|
|
70
|
-
|
|
71
|
-
.
|
|
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
|