created ewelink class

This commit is contained in:
Martín M
2019-06-23 18:37:55 -03:00
parent 77b8f3f131
commit 11be3e0d58
3 changed files with 172 additions and 1 deletions

71
lib/helper.js Normal file
View File

@@ -0,0 +1,71 @@
const crypto = require('crypto');
const random = require('random');
const nonce = require('nonce')();
const makeFakeIMEI = () => {
const num1 = random.int(1000, 9999);
const num2 = random.int(1000, 9999);
return `DF7425A0-${num1}-${num2}-9F5E-3BC9179E48FB`;
};
const loginPayload = ({ email, password }) => ({
email,
password,
version: 6,
ts: `${Math.round(new Date().getTime() / 1000)}`,
nonce: `${nonce()}`,
appid: 'oeVkj2lYFGnJu5XUtWisfW4utiN4u9Mq',
imei: makeFakeIMEI(),
os: 'iOS',
model: 'iPhone10,6',
romVersion: '11.1.2',
appVersion: '3.5.3',
});
const wssLoginPayload = ({ at, apiKey }) => {
const timeStamp = new Date() / 1000;
const ts = Math.floor(timeStamp);
const sequence = Math.floor(timeStamp * 1000);
const payload = {
action: 'userOnline',
userAgent: 'app',
version: 6,
nonce: `${nonce()}`,
apkVesrion: '1.8',
os: 'ios',
at,
apikey: apiKey,
ts: `${ts}`,
model: 'iPhone10,6',
romVersion: '11.1.2',
sequence,
};
return JSON.stringify(payload);
};
const wssUpdatePayload = ({ apiKey, deviceId, params }) => {
const timeStamp = new Date() / 1000;
const sequence = Math.floor(timeStamp * 1000);
const payload = {
action: 'update',
userAgent: 'app',
apikey: apiKey,
deviceid: `${deviceId}`,
params,
sequence,
};
return JSON.stringify(payload);
};
const makeAuthorizationSign = body =>
crypto
.createHmac('sha256', '6Nz4n0xA8s8qdxQf2GqurZj2Fs55FUvM')
.update(JSON.stringify(body))
.digest('base64');
module.exports = {
makeAuthorizationSign,
loginPayload,
wssLoginPayload,
wssUpdatePayload,
};

100
main.js Normal file
View File

@@ -0,0 +1,100 @@
const rp = require('request-promise');
const W3CWebSocket = require('websocket').w3cwebsocket;
const WebSocketAsPromised = require('websocket-as-promised');
const delay = require('delay');
const {
makeAuthorizationSign,
loginPayload,
wssLoginPayload,
wssUpdatePayload,
} = require('./lib/helper');
class eWeLink {
constructor({ region = 'us', email, password }) {
this.apiUrl = `https://${region}-api.coolkit.cc:8080/api`;
this.apiWebSocket = 'wss://us-pconnect3.coolkit.cc:8080/api/ws';
this.email = email;
this.password = password;
this.apiKey = '';
this.at = '';
}
async makeRequest({ method = 'GET', uri, body = {}, qs = {} }) {
const { apiKey, at } = this;
if (!apiKey && !at) {
await this.login();
}
const response = await rp({
method,
uri: `${this.apiUrl}${uri}`,
headers: { Authorization: `Bearer ${this.at}` },
body,
qs,
json: true,
});
return response;
}
async login() {
const body = loginPayload({
email: this.email,
password: this.password,
});
const response = await rp({
method: 'POST',
uri: `${this.apiUrl}/user/login`,
headers: { Authorization: `Sign ${makeAuthorizationSign(body)}` },
body,
json: true,
});
this.apiKey = response.user.apikey;
this.at = response.at;
return response;
}
async getDevices() {
const response = await this.makeRequest({
uri: '/user/device',
qs: { lang: 'en', getTags: 1 },
});
return response;
}
async getDevice(deviceId) {
const response = await this.makeRequest({
uri: `/user/device/${deviceId}`,
qs: { lang: 'en', getTags: 1 },
});
return response;
}
async toggleDevice(deviceId) {
const device = await this.getDevice(deviceId);
const status = device.params.switch === 'on' ? 'off' : 'on';
const payloadLogin = wssLoginPayload({ at: this.at, apiKey: this.apiKey });
const payloadUpdate = wssUpdatePayload({
apiKey: this.apiKey,
deviceId,
params: { switch: status },
});
const wsp = new WebSocketAsPromised(this.apiWebSocket, {
createWebSocket: url => new W3CWebSocket(url),
});
await wsp.open();
await wsp.send(payloadLogin);
await delay(1000);
await wsp.send(payloadUpdate);
await wsp.close();
return { status: 'ok' };
}
}
module.exports = eWeLink;

View File

@@ -2,7 +2,7 @@
"name": "ewelink-api",
"version": "1.0.0",
"description": "eWeLink API for Node.js",
"main": "index.js",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},