vw-services-client
Version:
Partial port of https://github.com/robinostlund/volkswagencarnet for node
707 lines • 36.2 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var jssoup_1 = __importDefault(require("jssoup"));
var node_fetch_1 = __importDefault(require("node-fetch"));
// @ts-ignore
// tslint:disable-next-line:no-var-requires
var fetch = require('fetch-cookie/node-fetch')(node_fetch_1.default);
// tslint:disable:no-console
var HEADERS_SESSION = {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json;charset=UTF-8',
'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0.1; D5803 Build/23.5.A.1.291; wv) \
AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.111 Mobile Safari/537.36',
};
var HEADERS_AUTH = {
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,\
image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0.1; D5803 Build/23.5.A.1.291; wv) \
AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.111 Mobile Safari/537.36',
};
var BASE_SESSION = 'https://www.portal.volkswagen-we.com/';
var BASE_AUTH = 'https://identity.vwgroup.io';
function makeCopy(obj) {
var newMap = {};
// tslint:disable-next-line:forin
for (var i in obj) {
newMap[i] = obj[i];
}
return newMap;
}
function getJsonFromUrl(url) {
if (!url) {
url = location.href;
}
var question = url.indexOf('?');
var hash = url.indexOf('#');
if (hash === -1 && question === -1) {
return {};
}
if (hash === -1) {
hash = url.length;
}
var query = question === -1 || hash === question + 1 ? url.substring(hash) : url.substring(question + 1, hash);
var result = {};
query.split('&').forEach(function (part) {
if (!part) {
return;
}
part = part.split('+').join(' '); // replace every + with space, regexp-free version
var eq = part.indexOf('=');
var key = eq > -1 ? part.substr(0, eq) : part;
var val = eq > -1 ? decodeURIComponent(part.substr(eq + 1)) : '';
var from = key.indexOf('[');
if (from === -1) {
result[decodeURIComponent(key)] = val;
}
else {
var to = key.indexOf(']', from);
var index = decodeURIComponent(key.substring(from + 1, to));
key = decodeURIComponent(key.substring(0, from));
if (!result[key]) {
result[key] = [];
}
if (!index) {
result[key].push(val);
}
else {
result[key][index] = val;
}
}
});
return result;
}
var Connection = /** @class */ (function () {
function Connection(agent, username, password) {
this.agent = agent;
this.sessionHeaders = makeCopy(HEADERS_SESSION);
this.sessionBase = BASE_SESSION;
this.sessionAuthHeaders = makeCopy(HEADERS_AUTH);
this.sessionAuthBase = BASE_AUTH;
this.sessionAuthRefUrl = '';
this.sessionFirstUpdate = false;
this.sessionAuthUsername = username;
this.sessionAuthPassword = password;
this.state = {};
}
Connection.prototype.login = function () {
return __awaiter(this, void 0, void 0, function () {
var extractCSRF, req, text, csrf, responseData, lgUrl, refUrl1, content, getInput, getForm, loginCsrf, loginToken, loginHmac, loginFormAction, loginUrl, postData, toUrlEncoded, refUrl2, authRelayUrl, authCsrf, authToken, authHmac, authFormAction, authUrl, refUrl3, refUrl4, refUrl5, refUrl6, parsedUrl, state, code, url, url2, refUrl7, _a, e_1;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
// """ Reset session in case we would like to login again """
this.sessionHeaders = makeCopy(HEADERS_SESSION);
this.sessionAuthHeaders = makeCopy(HEADERS_AUTH);
extractCSRF = function (req) {
var r = /<meta name="_csrf" content="([^"]*)?"\/>/i;
var items = req.match(r);
return items[1];
};
_b.label = 1;
case 1:
_b.trys.push([1, 19, , 20]);
return [4 /*yield*/, fetch(this.sessionBase + '/portal/en_GB/web/guest/home', {
method: 'GET',
})];
case 2:
req = _b.sent();
if (req.status !== 200) {
return [2 /*return*/, false];
}
return [4 /*yield*/, req.text()];
case 3:
text = _b.sent();
csrf = extractCSRF(text);
// Request login page and get CSRF
this.sessionAuthHeaders.Referer = this.sessionBase + 'portal';
return [4 /*yield*/, fetch(this.sessionBase + 'portal/web/guest/home/-/csrftokenhandling/get-login-url', {
method: 'POST',
headers: this.sessionAuthHeaders,
redirect: 'follow',
})];
case 4:
req = _b.sent();
if (req.status !== 200) {
return [2 /*return*/, false];
}
return [4 /*yield*/, req.json()];
case 5:
responseData = _b.sent();
lgUrl = responseData.loginURL.path;
return [4 /*yield*/, fetch(lgUrl, {
method: 'GET',
redirect: 'manual',
headers: this.sessionAuthHeaders,
})];
case 6:
// no redirect so we can get values we look for
req = _b.sent();
if (req.status !== 302) {
return [2 /*return*/, false];
}
refUrl1 = req.headers.get('location');
return [4 /*yield*/, fetch(refUrl1, {
method: 'GET',
headers: this.sessionAuthHeaders,
})];
case 7:
// now get actual login page and get session id and ViewState
req = _b.sent();
if (req.status !== 200) {
return [2 /*return*/, false];
}
return [4 /*yield*/, req.text()];
case 8:
content = _b.sent();
getInput = function (data, name) {
var soup = new jssoup_1.default(data);
var items = soup.findAll('input');
for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
var item = items_1[_i];
if (item.attrs.name === name) {
return item.attrs.value;
}
}
return '';
};
getForm = function (data, name) {
var soup = new jssoup_1.default(data);
var items = soup.findAll('form');
for (var _i = 0, items_2 = items; _i < items_2.length; _i++) {
var item = items_2[_i];
if (item.attrs.id === name) {
return item.attrs.action;
}
}
return '';
};
loginCsrf = getInput(content, '_csrf');
loginToken = getInput(content, 'relayState');
loginHmac = getInput(content, 'hmac');
loginFormAction = getForm(content, 'emailPasswordForm');
loginUrl = this.sessionAuthBase + loginFormAction;
// post login
this.sessionAuthHeaders.Referer = refUrl1;
postData = {
email: this.sessionAuthUsername,
password: this.sessionAuthPassword,
relayState: loginToken,
hmac: loginHmac,
_csrf: loginCsrf,
};
toUrlEncoded = function (obj) {
return Object.keys(obj)
.map(function (k) { return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]); })
.join('&');
};
return [4 /*yield*/, fetch(loginUrl, {
method: 'POST',
redirect: 'manual',
body: toUrlEncoded(postData),
headers: this.sessionAuthHeaders,
})];
case 9:
req = _b.sent();
if (req.status !== 303) {
return [2 /*return*/, false];
}
refUrl2 = req.headers.get('location');
authRelayUrl = refUrl2;
return [4 /*yield*/, fetch(authRelayUrl, {
method: 'GET',
redirect: 'manual',
// body: toUrlEncoded(postData),
headers: this.sessionAuthHeaders,
})];
case 10:
// get: https://identity.vwgroup.io/signin-service/v1/xxx@apps_vw-dilab_com/login/authenticate?relayState=xxx&email=xxx
req = _b.sent();
if (req.status !== 200) {
return [2 /*return*/, false];
}
return [4 /*yield*/, req.text()];
case 11:
content = _b.sent();
authCsrf = getInput(content, '_csrf');
authToken = getInput(content, 'relayState');
authHmac = getInput(content, 'hmac');
authFormAction = getForm(content, 'credentialsForm');
authUrl = this.sessionAuthBase + authFormAction;
// post login
this.sessionAuthHeaders.Referer = authRelayUrl;
postData = {
email: this.sessionAuthUsername,
password: this.sessionAuthPassword,
relayState: authToken,
hmac: authHmac,
_csrf: authCsrf,
};
return [4 /*yield*/, fetch(authUrl, {
method: 'POST',
headers: this.sessionAuthHeaders,
redirect: 'manual',
body: toUrlEncoded(postData),
})];
case 12:
// post: https://identity.vwgroup.io/signin-service/v1/xxx@apps_vw-dilab_com/login/authenticate
req = _b.sent();
if (req.status !== 302) {
return [2 /*return*/, false];
}
refUrl3 = req.headers.get('location');
return [4 /*yield*/, fetch(refUrl3, {
method: 'GET',
headers: this.sessionAuthHeaders,
redirect: 'manual',
})];
case 13:
req = _b.sent();
if (req.status !== 302) {
return [2 /*return*/, false];
}
refUrl4 = req.headers.get('location');
return [4 /*yield*/, fetch(refUrl4, {
method: 'GET',
headers: this.sessionAuthHeaders,
redirect: 'manual',
})];
case 14:
req = _b.sent();
if (req.status !== 302) {
return [2 /*return*/, false];
}
refUrl5 = req.headers.get('location');
return [4 /*yield*/, fetch(refUrl5, {
method: 'GET',
headers: this.sessionAuthHeaders,
redirect: 'manual',
})];
case 15:
// user_id = parse_qs(urlparse(refUrl5).query).get('user_id')[0]
req = _b.sent();
if (req.status !== 302) {
return [2 /*return*/, false];
}
refUrl6 = req.headers.get('location');
parsedUrl = getJsonFromUrl(refUrl6);
state = parsedUrl.state;
code = parsedUrl.code;
// post:
// https://www.portal.volkswagen-we.com/portal/web/guest/complete-login?p_auth=xxx&p_p_id=33_WAR_cored5portlet&p_p_lifecycle=1&p_pstate=normal&p_p_mode=view&p_p_col_id=column-1&p_p_col_count=1&_33_WAR_cored5portlet_javax.portlet.action=getLoginStatus
this.sessionAuthHeaders.Referer = refUrl6;
postData = {
_33_WAR_cored5portlet_code: code,
_33_WAR_cored5portlet_landingPageUrl: '',
};
url = refUrl6.split('?')[0];
url2 = url +
'?p_auth=' +
state +
'&p_p_id=33_WAR_cored5portlet&p_p_lifecycle=1&p_p_state=normal&p_p_mode=view&p_p_col_id=column-1&p_p_col_count=1&_33_WAR_cored5portlet_javax.portlet.action=getLoginStatus';
return [4 /*yield*/, fetch(url2, {
method: 'POST',
headers: this.sessionAuthHeaders,
redirect: 'manual',
body: toUrlEncoded(postData),
timeout: 10000,
})];
case 16:
req = _b.sent();
if (req.status !== 302) {
return [2 /*return*/, false];
}
refUrl7 = req.headers.get('location');
return [4 /*yield*/, fetch(refUrl7, {
method: 'GET',
headers: this.sessionAuthHeaders,
redirect: 'manual',
})];
case 17:
req = _b.sent();
if (req.status !== 200) {
return [2 /*return*/, false];
}
_a = extractCSRF;
return [4 /*yield*/, req.text()];
case 18:
// We have a new CSRF
csrf = _a.apply(void 0, [_b.sent()]);
// cookie = this.session.cookies.get_dict()
// cookie = req.cookies
// this.session_guest_language_id = extract_guest_language_id(req.cookies.get('GUEST_LANGUAGE_ID').value)
// Update headers for requests
this.sessionHeaders.Referer = refUrl7;
this.sessionHeaders['X-CSRF-Token'] = csrf;
this.sessionAuthRefUrl = refUrl7 + '/';
return [2 /*return*/, true];
case 19:
e_1 = _b.sent();
console.log(e_1);
return [2 /*return*/, false];
case 20: return [2 /*return*/];
}
});
});
};
Connection.prototype.logout = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.post('-/logout/revoke', undefined, undefined)];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
Connection.prototype.update = function () {
return __awaiter(this, void 0, void 0, function () {
var loadedVehicles, _i, _a, vehicle, vehicleVin, _b, _c, vehicle, vehicleUrl, _d, _e, key, _f, _g, vehicle, e_2;
return __generator(this, function (_h) {
switch (_h.label) {
case 0:
_h.trys.push([0, 17, , 18]);
if (!this.sessionFirstUpdate) return [3 /*break*/, 4];
return [4 /*yield*/, this.validate_login()];
case 1:
if (!!(_h.sent())) return [3 /*break*/, 3];
console.warn('Session expired, creating new login session to carnet.');
return [4 /*yield*/, this.login()];
case 2:
_h.sent();
_h.label = 3;
case 3: return [3 /*break*/, 5];
case 4:
this.sessionFirstUpdate = true;
_h.label = 5;
case 5: return [4 /*yield*/, this.post('-/mainnavigation/get-fully-loaded-cars', undefined, undefined)];
case 6:
loadedVehicles = _h.sent();
console.log(loadedVehicles);
if (!(loadedVehicles.fullyLoadedVehiclesResponse &&
loadedVehicles.fullyLoadedVehiclesResponse.vehiclesNotFullyLoaded)) return [3 /*break*/, 12];
_i = 0, _a = loadedVehicles.fullyLoadedVehiclesResponse.vehiclesNotFullyLoaded;
_h.label = 7;
case 7:
if (!(_i < _a.length)) return [3 /*break*/, 10];
vehicle = _a[_i];
vehicleVin = vehicle.vin;
return [4 /*yield*/, this.post('-/mainnavigation/load-car-details/' + vehicleVin, undefined, undefined)];
case 8:
_h.sent();
_h.label = 9;
case 9:
_i++;
return [3 /*break*/, 7];
case 10: return [4 /*yield*/, this.post('-/mainnavigation/get-fully-loaded-cars', undefined, undefined)];
case 11:
loadedVehicles = _h.sent();
_h.label = 12;
case 12:
if (loadedVehicles.fullyLoadedVehiclesResponse && loadedVehicles.fullyLoadedVehiclesResponse.completeVehicles) {
// // update vehicles
for (_b = 0, _c = loadedVehicles.fullyLoadedVehiclesResponse.completeVehicles; _b < _c.length; _b++) {
vehicle = _c[_b];
vehicleUrl = this.sessionBase + vehicle.dashboardUrl;
if (!this.state[vehicleUrl]) {
this.state[vehicleUrl] = vehicle;
}
else {
for (_d = 0, _e = Object.keys(vehicle); _d < _e.length; _d++) {
key = _e[_d];
this.state[vehicleUrl][key] = vehicle[key];
}
}
}
}
_f = 0, _g = Object.keys(this.state);
_h.label = 13;
case 13:
if (!(_f < _g.length)) return [3 /*break*/, 16];
vehicle = _g[_f];
return [4 /*yield*/, this.update_vehicle(vehicle)];
case 14:
_h.sent();
_h.label = 15;
case 15:
_f++;
return [3 /*break*/, 13];
case 16: return [2 /*return*/, true];
case 17:
e_2 = _h.sent();
console.log(e_2);
return [3 /*break*/, 18];
case 18: return [2 /*return*/];
}
});
});
};
Connection.prototype.request = function (method, url, data) {
return __awaiter(this, void 0, void 0, function () {
var options, req, res;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
options = {
method: method,
headers: this.sessionHeaders,
redirect: 'manual',
};
if (data) {
options.body = JSON.stringify(data);
}
return [4 /*yield*/, fetch(url, options)];
case 1:
req = _a.sent();
return [4 /*yield*/, req.json()];
case 2:
res = _a.sent();
// console.log(`Received [{response.status}] response: {res}`)
return [2 /*return*/, res];
}
});
});
};
Connection.prototype.make_url = function (ref, rel) {
console.log("MAKE_URL ref=" + ref + " rel=" + rel);
if (rel) {
console.log('relative');
return rel + '/' + ref;
}
console.log('add abs');
return this.sessionAuthRefUrl + '/' + ref;
};
Connection.prototype.get = function (url, rel) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.request('GET', this.make_url(url, rel), undefined)];
case 1:
// """Perform a get query to the online service."""
return [2 /*return*/, _a.sent()];
}
});
});
};
Connection.prototype.post = function (url, rel, data) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!data) return [3 /*break*/, 2];
return [4 /*yield*/, this.request('POST', this.make_url(url, rel), data)];
case 1: return [2 /*return*/, _a.sent()];
case 2: return [4 /*yield*/, this.request('POST', this.make_url(url, rel), undefined)];
case 3: return [2 /*return*/, _a.sent()];
}
});
});
};
Connection.prototype.validate_login = function () {
return __awaiter(this, void 0, void 0, function () {
var messages;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.post('-/msgc/get-new-messages', undefined, undefined)];
case 1:
messages = _a.sent();
return [2 /*return*/, messages.errorCode === '0'];
}
});
});
};
Connection.prototype.update_vehicle = function (vehurl) {
return __awaiter(this, void 0, void 0, function () {
var url, response, e_3, response, err_1, response, err_2, response, err_3, response, err_4, response, err_5, response, err_6, response, err_7;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
url = vehurl;
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, this.post('-/msgc/get-new-messages', url, undefined)];
case 2:
response = _a.sent();
// messageList
if (response.errorCode === '0') {
this.state[url].vehicleMessagesNew = response.response;
}
else {
console.log("Could not fetch new messages: " + response);
}
return [3 /*break*/, 4];
case 3:
e_3 = _a.sent();
// except Exception as err:
console.log("Could not fetch new messages, error: " + e_3);
return [3 /*break*/, 4];
case 4:
_a.trys.push([4, 6, , 7]);
return [4 /*yield*/, this.post('-/msgc/get-latest-messages', url, undefined)];
case 5:
response = _a.sent();
// messageList
if (response.errorCode === '0') {
this.state[url].vehicleMessagesLatest = response.messageList;
}
else {
console.log("Could not fetch latest messages: " + response);
}
return [3 /*break*/, 7];
case 6:
err_1 = _a.sent();
console.log("Could not fetch latest messages, error: " + err_1);
return [3 /*break*/, 7];
case 7:
_a.trys.push([7, 9, , 10]);
return [4 /*yield*/, this.post('-/vsr/get-vsr', url, undefined)];
case 8:
response = _a.sent();
// messageList
if (response.errorCode === '0') {
this.state[url].vehicleStatus = response.vehicleStatusData;
}
else {
console.log("Could not fetch vsr: " + response);
}
return [3 /*break*/, 10];
case 9:
err_2 = _a.sent();
console.log("Could not fetch vsr messages, error: " + err_2);
return [3 /*break*/, 10];
case 10:
_a.trys.push([10, 12, , 13]);
return [4 /*yield*/, this.post('-/emanager/get-emanager', url, undefined)];
case 11:
response = _a.sent();
// messageList
if (response.errorCode === '0') {
this.state[url].EManager = response.EManager;
}
else {
console.log("Could not fetch e manager: " + response);
}
return [3 /*break*/, 13];
case 12:
err_3 = _a.sent();
console.log("Could not fetch e manager messages, error: " + err_3);
return [3 /*break*/, 13];
case 13:
_a.trys.push([13, 15, , 16]);
return [4 /*yield*/, this.post('-/cf/get-location', url, undefined)];
case 14:
response = _a.sent();
// messageList
if (response.errorCode === '0') {
this.state[url].vehiclePosition = response.position;
}
else {
console.log("Could not fetch position: " + response);
}
return [3 /*break*/, 16];
case 15:
err_4 = _a.sent();
console.log("Could not fetch position messages, error: " + err_4);
return [3 /*break*/, 16];
case 16:
_a.trys.push([16, 18, , 19]);
return [4 /*yield*/, this.post('-/vehicle-info/get-vehicle-details', url, undefined)];
case 17:
response = _a.sent();
// messageList
if (response.errorCode === '0') {
this.state[url].vehicleDetails = response.vehicleDetails;
}
else {
console.log("Could not fetch vehicle details: " + response);
}
return [3 /*break*/, 19];
case 18:
err_5 = _a.sent();
console.log("Could not fetch vehicle details messages, error: " + err_5);
return [3 /*break*/, 19];
case 19:
_a.trys.push([19, 21, , 22]);
return [4 /*yield*/, this.post('-/rah/get-status', url, undefined)];
case 20:
response = _a.sent();
// messageList
if (response.errorCode === '0') {
this.state[url].vehicleRemoteAuxiliaryHeating = response.remoteAuxiliaryHeating;
}
else {
console.log("Could not fetch vehicle vehicleRemoteAuxiliaryHeating: " + response);
}
return [3 /*break*/, 22];
case 21:
err_6 = _a.sent();
console.log("Could not fetch vehicle vehicleRemoteAuxiliaryHeating messages, error: " + err_6);
return [3 /*break*/, 22];
case 22:
_a.trys.push([22, 24, , 25]);
return [4 /*yield*/, this.post('-/rts/get-latest-trip-statistics', url, undefined)];
case 23:
response = _a.sent();
// messageList
if (response.errorCode === '0') {
this.state[url].vehicleLastTrips = response.rtsViewModel;
}
else {
console.log("Could not fetch vehicle vehicleLastTrips: " + response);
}
return [3 /*break*/, 25];
case 24:
err_7 = _a.sent();
console.log("Could not fetch vehicle vehicleLastTrips messages, error: " + err_7);
return [3 /*break*/, 25];
case 25: return [2 /*return*/];
}
});
});
};
return Connection;
}());
//# sourceMappingURL=main.js.map