-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
130 lines (109 loc) · 3.44 KB
/
index.js
File metadata and controls
130 lines (109 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
const isJSON = require('./is_json');
class Scaledrone {
constructor({channelId, secretKey, baseURL} = {}) {
if (!channelId) {
throw new Error('ChannelId must be set');
}
if (!secretKey) {
throw new Error('SecretKey must be set');
}
if (typeof channelId !== 'string') {
throw new Error('ChannelId must be of type string');
}
if (typeof secretKey !== 'string') {
throw new Error('SecretKey must be of type string');
}
this.auth = {
user: channelId,
pass: secretKey
};
this.baseURL = baseURL || 'https://api2.scaledrone.com';
this.channelId = channelId;
}
// Public API
publish(roomName, message, callback) {
const object = isJSON(message);
let body;
let headers = {};
if (object) {
body = JSON.stringify(object);
headers['Content-Type'] = 'application/json';
} else {
body = message + '';
headers['Content-Type'] = 'text/plain';
}
let uri;
if (Array.isArray(roomName)) {
const rooms = roomName.map(room => `r=${room}`).join('&');
uri = `${this.channelId}/publish/rooms?${rooms}`;
} else {
uri = `${this.channelId}/${roomName}/publish`;
}
const p = this._request(uri, { method: 'POST', headers, body }, /*parseResponse*/ false);
return this._asCallback(p, callback);
}
channelStats(callback) {
const p = this._request(`${this.channelId}/stats`, { method: 'GET' }, /*parseResponse*/ true);
return this._asCallback(p, callback);
}
members(callback) {
const p = this._request(`${this.channelId}/members`, { method: 'GET' }, /*parseResponse*/ true);
return this._asCallback(p, callback);
}
rooms(callback) {
const p = this._request(`${this.channelId}/rooms`, { method: 'GET' }, /*parseResponse*/ true);
return this._asCallback(p, callback);
}
roomMembers(roomName, callback) {
const p = this._request(`${this.channelId}/${roomName}/members`, { method: 'GET' }, /*parseResponse*/ true);
return this._asCallback(p, callback);
}
allRoomMembers(callback) {
const p = this._request(`${this.channelId}/room-members`, { method: 'GET' }, /*parseResponse*/ true);
return this._asCallback(p, callback);
}
// Internals
_asCallback(promise, callback) {
if (typeof callback === 'function') {
promise.then(res => callback(null, res)).catch(err => callback(err));
return; // undefined (callback style)
}
return promise; // promise style
}
async _request(uri, init, parseResponse) {
const url = `${this.baseURL}/${uri}`;
const headers = {
...(init.headers || {}),
'Authorization': 'Basic ' + Buffer.from(`${this.auth.user}:${this.auth.pass}`).toString('base64')
};
const res = await fetch(url, { ...init, headers });
// Read body as text first (for uniform error handling)
let text = '';
try {
text = await res.text();
} catch (_) {
// ignore
}
if (res.status >= 400) {
let msg = text;
try {
msg = JSON.parse(text).message;
} catch (_) {
// keep raw text
}
throw new Error(msg);
}
if (!parseResponse) {
// Match original publish() behavior: return raw response text
return text;
}
// Parse JSON for the GET endpoints (match original)
try {
return JSON.parse(text);
} catch (_) {
// if server ever returns non-JSON, keep raw text
return text;
}
}
}
module.exports = Scaledrone;