iobroker.google-sharedlocations2 0.0.1 → 0.0.3
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/README.md +5 -2
- package/io-package.json +207 -175
- package/package.json +4 -2
- package/src/main.ts +86 -55
- package/src/prettier.config.mjs +9 -0
package/README.md
CHANGED
|
@@ -27,9 +27,12 @@ Copyright and trademark of Google are property of Google.
|
|
|
27
27
|
Placeholder for the next version (at the beginning of the line):
|
|
28
28
|
### **WORK IN PROGRESS**
|
|
29
29
|
-->
|
|
30
|
+
### 0.0.3 (2026-01-28)
|
|
31
|
+
* (Garfonso) prevent login if no username and password is set
|
|
32
|
+
* (Garfonso) fix tests
|
|
30
33
|
|
|
31
|
-
###
|
|
32
|
-
* (Garfonso)
|
|
34
|
+
### 0.0.2 (2026-01-28)
|
|
35
|
+
* (Garfonso) store password encrypted
|
|
33
36
|
|
|
34
37
|
## License
|
|
35
38
|
MIT License
|
package/io-package.json
CHANGED
|
@@ -1,178 +1,210 @@
|
|
|
1
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
|
-
"authors": [
|
|
47
|
-
"Garfonso <garfonso@mobo.info>"
|
|
48
|
-
],
|
|
49
|
-
"keywords": [
|
|
50
|
-
"google",
|
|
51
|
-
"geofence",
|
|
52
|
-
"gps",
|
|
53
|
-
"position",
|
|
54
|
-
"geo"
|
|
55
|
-
],
|
|
56
|
-
"licenseInformation": {
|
|
57
|
-
"type": "free",
|
|
58
|
-
"license": "MIT"
|
|
59
|
-
},
|
|
60
|
-
"platform": "Javascript/Node.js",
|
|
61
|
-
"icon": "google-sharedlocations2.png",
|
|
62
|
-
"enabled": true,
|
|
63
|
-
"extIcon": "https://raw.githubusercontent.com/Garfonso/ioBroker.google-sharedlocations2/main/admin/google-sharedlocations2.png",
|
|
64
|
-
"readme": "https://github.com/Garfonso/ioBroker.google-sharedlocations2/blob/main/README.md",
|
|
65
|
-
"loglevel": "info",
|
|
66
|
-
"tier": 3,
|
|
67
|
-
"mode": "daemon",
|
|
68
|
-
"type": "geoposition",
|
|
69
|
-
"compact": true,
|
|
70
|
-
"connectionType": "cloud",
|
|
71
|
-
"dataSource": "poll",
|
|
72
|
-
"adminUI": {
|
|
73
|
-
"config": "json"
|
|
74
|
-
},
|
|
75
|
-
"dependencies": [
|
|
76
|
-
{
|
|
77
|
-
"js-controller": ">=6.0.11"
|
|
78
|
-
}
|
|
79
|
-
],
|
|
80
|
-
"globalDependencies": [
|
|
81
|
-
{
|
|
82
|
-
"admin": ">=7.0.23"
|
|
83
|
-
}
|
|
84
|
-
],
|
|
85
|
-
"osDependencies": {
|
|
86
|
-
"linux": [
|
|
87
|
-
"ca-certificates",
|
|
88
|
-
"fonts-liberation",
|
|
89
|
-
"libappindicator3-1",
|
|
90
|
-
"libasound2",
|
|
91
|
-
"libatk-bridge2.0-0",
|
|
92
|
-
"libatk1.0-0",
|
|
93
|
-
"libc6",
|
|
94
|
-
"libcairo2",
|
|
95
|
-
"libcups2",
|
|
96
|
-
"libdbus-1-3",
|
|
97
|
-
"libexpat1",
|
|
98
|
-
"libfontconfig1",
|
|
99
|
-
"libgbm1",
|
|
100
|
-
"libgcc1",
|
|
101
|
-
"libglib2.0-0",
|
|
102
|
-
"libgtk-3-0",
|
|
103
|
-
"libnspr4",
|
|
104
|
-
"libnss3",
|
|
105
|
-
"libpango-1.0-0",
|
|
106
|
-
"libpangocairo-1.0-0",
|
|
107
|
-
"libstdc++6",
|
|
108
|
-
"libx11-6",
|
|
109
|
-
"libx11-xcb1",
|
|
110
|
-
"libxcb1",
|
|
111
|
-
"libxcomposite1",
|
|
112
|
-
"libxcursor1",
|
|
113
|
-
"libxdamage1",
|
|
114
|
-
"libxext6",
|
|
115
|
-
"libxfixes3",
|
|
116
|
-
"libxi6",
|
|
117
|
-
"libxrandr2",
|
|
118
|
-
"libxrender1",
|
|
119
|
-
"libxss1",
|
|
120
|
-
"libxtst6",
|
|
121
|
-
"lsb-release",
|
|
122
|
-
"wget",
|
|
123
|
-
"xdg-utils"
|
|
124
|
-
]
|
|
125
|
-
}
|
|
2
|
+
"common": {
|
|
3
|
+
"name": "google-sharedlocations2",
|
|
4
|
+
"version": "0.0.3",
|
|
5
|
+
"news": {
|
|
6
|
+
"0.0.3": {
|
|
7
|
+
"en": "prevent login if no username and password is set\nfix tests",
|
|
8
|
+
"de": "verhindern login, wenn kein benutzername und passwort eingestellt ist\ntests repariert",
|
|
9
|
+
"ru": "предотвратить вход в систему, если имя пользователя и пароль не установлены\nисправление",
|
|
10
|
+
"pt": "impedir o login se nenhum nome de usuário e senha estiver definido\ncorrigir os testes",
|
|
11
|
+
"nl": "login voorkomen als er geen gebruikersnaam en wachtwoord is ingesteld\nvastleggen van tests",
|
|
12
|
+
"fr": "empêcher le login si aucun nom d'utilisateur et mot de passe n'est défini\nessais de correction",
|
|
13
|
+
"it": "impedire il login se non viene impostato nessun nome utente e password\ntest di correzione",
|
|
14
|
+
"es": "previene el inicio de sesión si no se establece el nombre de usuario y la contraseña\npruebas de reparación",
|
|
15
|
+
"pl": "zapobiec logowaniu, jeśli nie jest ustawiona nazwa użytkownika i hasło\nbadania naprawcze",
|
|
16
|
+
"uk": "заборонити логін, якщо не встановлено ім’я користувача та пароль\nфіксувати тести",
|
|
17
|
+
"zh-cn": "如果没有设置用户名和密码, 请防止登录\n固定测试"
|
|
18
|
+
},
|
|
19
|
+
"0.0.2": {
|
|
20
|
+
"en": "store password encrypted",
|
|
21
|
+
"de": "speicher passwort verschlüsselt",
|
|
22
|
+
"ru": "зашифрованный пароль",
|
|
23
|
+
"pt": "guardar a senha encriptada",
|
|
24
|
+
"nl": "wachtwoord versleuteld opslaan",
|
|
25
|
+
"fr": "crypté du mot de passe de stockage",
|
|
26
|
+
"it": "negozio password crittografato",
|
|
27
|
+
"es": "almacenar contraseña cifrada",
|
|
28
|
+
"pl": "przechowywać zaszyfrowane hasło",
|
|
29
|
+
"uk": "зашифрований паролем",
|
|
30
|
+
"zh-cn": "存储加密密码"
|
|
31
|
+
},
|
|
32
|
+
"0.0.1": {
|
|
33
|
+
"en": "initial release",
|
|
34
|
+
"de": "Erstveröffentlichung",
|
|
35
|
+
"ru": "Начальная версия",
|
|
36
|
+
"pt": "lançamento inicial",
|
|
37
|
+
"nl": "Eerste uitgave",
|
|
38
|
+
"fr": "Première version",
|
|
39
|
+
"it": "Versione iniziale",
|
|
40
|
+
"es": "Versión inicial",
|
|
41
|
+
"pl": "Pierwsze wydanie",
|
|
42
|
+
"uk": "Початкова версія",
|
|
43
|
+
"zh-cn": "首次出版"
|
|
44
|
+
}
|
|
126
45
|
},
|
|
127
|
-
"
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
46
|
+
"titleLang": {
|
|
47
|
+
"en": "Google Shared Locations 2",
|
|
48
|
+
"de": "Von Google freigegebene Standorte 2",
|
|
49
|
+
"ru": "Общие местоположения Google 2",
|
|
50
|
+
"pt": "Locais compartilhados do Google 2",
|
|
51
|
+
"nl": "Google gedeelde locaties 2",
|
|
52
|
+
"fr": "Emplacements partagés Google 2",
|
|
53
|
+
"it": "Posizioni condivise di Google 2",
|
|
54
|
+
"es": "Ubicaciones compartidas de Google 2",
|
|
55
|
+
"pl": "Udostępnione lokalizacje Google 2",
|
|
56
|
+
"uk": "Google Shared Locations 2",
|
|
57
|
+
"zh-cn": "Google 共享位置 2"
|
|
131
58
|
},
|
|
132
|
-
"
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
59
|
+
"desc": {
|
|
60
|
+
"en": "Share your location with ioBroker via google maps.",
|
|
61
|
+
"de": "Teilen Sie Ihren Standort über Google Maps mit ioBroker.",
|
|
62
|
+
"ru": "Поделитесь своим местоположением с ioBroker через карты Google.",
|
|
63
|
+
"pt": "Compartilhe sua localização com o ioBroker através do Google Maps.",
|
|
64
|
+
"nl": "Deel uw locatie met ioBroker via Google Maps.",
|
|
65
|
+
"fr": "Partagez votre position avec ioBroker via Google Maps.",
|
|
66
|
+
"it": "Condividi la tua posizione con ioBroker tramite Google Maps.",
|
|
67
|
+
"es": "Comparte tu ubicación con ioBroker a través de Google Maps.",
|
|
68
|
+
"pl": "Udostępnij swoją lokalizację ioBrokerowi za pośrednictwem map Google.",
|
|
69
|
+
"uk": "Поділіться своїм місцезнаходженням з ioBroker через карти Google.",
|
|
70
|
+
"zh-cn": "通过谷歌地图与 ioBroker 分享您的位置。"
|
|
71
|
+
},
|
|
72
|
+
"authors": [
|
|
73
|
+
"Garfonso <garfonso@mobo.info>"
|
|
74
|
+
],
|
|
75
|
+
"keywords": [
|
|
76
|
+
"google",
|
|
77
|
+
"geofence",
|
|
78
|
+
"gps",
|
|
79
|
+
"position",
|
|
80
|
+
"geo"
|
|
81
|
+
],
|
|
82
|
+
"licenseInformation": {
|
|
83
|
+
"type": "free",
|
|
84
|
+
"license": "MIT"
|
|
85
|
+
},
|
|
86
|
+
"platform": "Javascript/Node.js",
|
|
87
|
+
"icon": "google-sharedlocations2.png",
|
|
88
|
+
"enabled": true,
|
|
89
|
+
"extIcon": "https://raw.githubusercontent.com/Garfonso/ioBroker.google-sharedlocations2/main/admin/google-sharedlocations2.png",
|
|
90
|
+
"readme": "https://github.com/Garfonso/ioBroker.google-sharedlocations2/blob/main/README.md",
|
|
91
|
+
"loglevel": "info",
|
|
92
|
+
"tier": 3,
|
|
93
|
+
"mode": "daemon",
|
|
94
|
+
"type": "geoposition",
|
|
95
|
+
"compact": true,
|
|
96
|
+
"connectionType": "cloud",
|
|
97
|
+
"dataSource": "poll",
|
|
98
|
+
"adminUI": {
|
|
99
|
+
"config": "json"
|
|
100
|
+
},
|
|
101
|
+
"dependencies": [
|
|
102
|
+
{
|
|
103
|
+
"js-controller": ">=6.0.11"
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"globalDependencies": [
|
|
107
|
+
{
|
|
108
|
+
"admin": ">=7.0.23"
|
|
109
|
+
}
|
|
110
|
+
],
|
|
111
|
+
"osDependencies": {
|
|
112
|
+
"linux": [
|
|
113
|
+
"ca-certificates",
|
|
114
|
+
"fonts-liberation",
|
|
115
|
+
"libappindicator3-1",
|
|
116
|
+
"libasound2",
|
|
117
|
+
"libatk-bridge2.0-0",
|
|
118
|
+
"libatk1.0-0",
|
|
119
|
+
"libc6",
|
|
120
|
+
"libcairo2",
|
|
121
|
+
"libcups2",
|
|
122
|
+
"libdbus-1-3",
|
|
123
|
+
"libexpat1",
|
|
124
|
+
"libfontconfig1",
|
|
125
|
+
"libgbm1",
|
|
126
|
+
"libgcc1",
|
|
127
|
+
"libglib2.0-0",
|
|
128
|
+
"libgtk-3-0",
|
|
129
|
+
"libnspr4",
|
|
130
|
+
"libnss3",
|
|
131
|
+
"libpango-1.0-0",
|
|
132
|
+
"libpangocairo-1.0-0",
|
|
133
|
+
"libstdc++6",
|
|
134
|
+
"libx11-6",
|
|
135
|
+
"libx11-xcb1",
|
|
136
|
+
"libxcb1",
|
|
137
|
+
"libxcomposite1",
|
|
138
|
+
"libxcursor1",
|
|
139
|
+
"libxdamage1",
|
|
140
|
+
"libxext6",
|
|
141
|
+
"libxfixes3",
|
|
142
|
+
"libxi6",
|
|
143
|
+
"libxrandr2",
|
|
144
|
+
"libxrender1",
|
|
145
|
+
"libxss1",
|
|
146
|
+
"libxtst6",
|
|
147
|
+
"lsb-release",
|
|
148
|
+
"wget",
|
|
149
|
+
"xdg-utils"
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"native": {
|
|
154
|
+
"googleUsername": "",
|
|
155
|
+
"googlePassword": "",
|
|
156
|
+
"pollInterval": 60
|
|
157
|
+
},
|
|
158
|
+
"protectedNative": [
|
|
159
|
+
"googlePassword"
|
|
160
|
+
],
|
|
161
|
+
"encryptedNative": [
|
|
162
|
+
"googlePassword"
|
|
163
|
+
],
|
|
164
|
+
"objects": [],
|
|
165
|
+
"instanceObjects": [
|
|
166
|
+
{
|
|
167
|
+
"_id": "info",
|
|
168
|
+
"type": "channel",
|
|
169
|
+
"common": {
|
|
170
|
+
"name": "Information"
|
|
171
|
+
},
|
|
172
|
+
"native": {}
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"_id": "info.connection",
|
|
176
|
+
"type": "state",
|
|
177
|
+
"common": {
|
|
178
|
+
"role": "indicator.connected",
|
|
179
|
+
"name": "Device or service connected",
|
|
180
|
+
"type": "boolean",
|
|
181
|
+
"read": true,
|
|
182
|
+
"write": false,
|
|
183
|
+
"def": false
|
|
184
|
+
},
|
|
185
|
+
"native": {}
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"_id": "info.currentCookies",
|
|
189
|
+
"type": "state",
|
|
190
|
+
"common": {
|
|
191
|
+
"role": "state",
|
|
192
|
+
"name": "Current authentication cookies",
|
|
193
|
+
"desc": "Overwrite to set cookies manually. Set empty to login again.",
|
|
194
|
+
"type": "string",
|
|
195
|
+
"read": true,
|
|
196
|
+
"write": true,
|
|
197
|
+
"def": ""
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"_id": "users",
|
|
202
|
+
"type": "folder",
|
|
203
|
+
"common": {
|
|
204
|
+
"name": "Users",
|
|
205
|
+
"desc": "Retrieved information on users."
|
|
206
|
+
},
|
|
207
|
+
"native": {}
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.google-sharedlocations2",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Share your location with iobroker via google maps.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Garfonso",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"@alcalzone/release-script-plugin-manual-review": "^4.0.0",
|
|
37
37
|
"@iobroker/adapter-dev": "^1.5.0",
|
|
38
38
|
"@iobroker/dev-server": "^0.8.0",
|
|
39
|
+
"@iobroker/eslint-config": "^2.2.0",
|
|
39
40
|
"@iobroker/testing": "^5.2.2",
|
|
40
41
|
"@iobroker/types": "^7.1.0",
|
|
41
42
|
"@tsconfig/node22": "^22.0.5",
|
|
@@ -61,7 +62,8 @@
|
|
|
61
62
|
"test": "npm run test:ts && npm run test:package",
|
|
62
63
|
"translate": "translate-adapter",
|
|
63
64
|
"release": "release-script",
|
|
64
|
-
"dev-server": "dev-server"
|
|
65
|
+
"dev-server": "dev-server",
|
|
66
|
+
"lint": "eslint -c eslint.config.mjs src/"
|
|
65
67
|
},
|
|
66
68
|
"bugs": {
|
|
67
69
|
"url": "https://github.com/Garfonso/ioBroker.google-sharedlocations2/issues"
|
package/src/main.ts
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
// you need to create an adapter
|
|
7
7
|
import * as utils from '@iobroker/adapter-core';
|
|
8
8
|
|
|
9
|
-
import puppeteer
|
|
9
|
+
import puppeteer from 'puppeteer';
|
|
10
|
+
import type { Browser } from 'puppeteer';
|
|
10
11
|
import axios from 'axios';
|
|
11
12
|
|
|
12
13
|
//used to test timeout against
|
|
@@ -66,13 +67,13 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
//start polling positions
|
|
69
|
-
|
|
70
|
+
this.pollPositions();
|
|
70
71
|
if (this._cookies) {
|
|
71
72
|
await this.sendRequest();
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
private
|
|
76
|
+
private pollPositions(): void {
|
|
76
77
|
this._pollTimeout = this.setTimeout(async () => {
|
|
77
78
|
if (!this._cookies) {
|
|
78
79
|
this.log.debug('Cannot poll positions, no cookies available!');
|
|
@@ -85,7 +86,7 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
85
86
|
}, this._pollInterval * 1000);
|
|
86
87
|
}
|
|
87
88
|
|
|
88
|
-
private async sendRequest() {
|
|
89
|
+
private async sendRequest(): Promise<void> {
|
|
89
90
|
if (!this._cookies) {
|
|
90
91
|
this.log.error('Cannot send request, no cookies available!');
|
|
91
92
|
await this.setState('info.connection', false, true);
|
|
@@ -96,22 +97,22 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
96
97
|
this.log.debug('Sending request with current cookies');
|
|
97
98
|
const options = {
|
|
98
99
|
method: 'GET',
|
|
99
|
-
url:
|
|
100
|
+
url: 'https://www.google.com/maps/rpc/locationsharing/read',
|
|
100
101
|
headers: {
|
|
101
|
-
|
|
102
|
+
Cookie: this._cookies,
|
|
102
103
|
},
|
|
103
104
|
params: {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
authuser: 2,
|
|
106
|
+
hl: 'en',
|
|
107
|
+
gl: 'us',
|
|
107
108
|
//pb is place on map. Is irrelevant, set to google head quarters here.
|
|
108
|
-
|
|
109
|
-
}
|
|
109
|
+
pb: '!1m7!8m6!1m3!1i14!2i8413!3i5385!2i6!3x4095!2m3!1e0!2sm!3i407105169!3m7!2sen!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e1!5m4!1e4!8m2!1e0!1e1!6m9!1e12!2i2!26m1!4b1!30m1!1f1.3953487873077393!39b1!44e1!50e0!23i4111425',
|
|
110
|
+
},
|
|
110
111
|
};
|
|
111
112
|
|
|
112
113
|
try {
|
|
113
114
|
const response = await axios.request(options);
|
|
114
|
-
this.log.debug(
|
|
115
|
+
this.log.debug(`Request successful, response code: ${response.status}`);
|
|
115
116
|
const data = response.data.split('\n').slice(1).join('\n');
|
|
116
117
|
const locationData = JSON.parse(data);
|
|
117
118
|
const locations = locationData[0];
|
|
@@ -129,7 +130,7 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
132
|
} catch (e) {
|
|
132
|
-
this.log.error(
|
|
133
|
+
this.log.error(`Error during request: ${(e as Error).message}`);
|
|
133
134
|
if (this._successFullPolls > 0) {
|
|
134
135
|
//try to get new cookie:
|
|
135
136
|
await this.loginToGetNewCookies();
|
|
@@ -137,7 +138,7 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
137
138
|
}
|
|
138
139
|
}
|
|
139
140
|
|
|
140
|
-
private async fillIntoObjects(locationData: any) {
|
|
141
|
+
private async fillIntoObjects(locationData: any): Promise<void> {
|
|
141
142
|
try {
|
|
142
143
|
const user = {
|
|
143
144
|
id: undefined,
|
|
@@ -148,31 +149,49 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
148
149
|
address: undefined,
|
|
149
150
|
battery: undefined,
|
|
150
151
|
timestamp: undefined,
|
|
151
|
-
accuracy: undefined
|
|
152
|
+
accuracy: undefined,
|
|
152
153
|
};
|
|
153
154
|
|
|
154
|
-
if(locationData && Array.isArray(locationData)) {
|
|
155
|
+
if (locationData && Array.isArray(locationData)) {
|
|
155
156
|
// locationData present
|
|
156
|
-
if(locationData[0] && locationData[0][0])
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
if(locationData[
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if(locationData[
|
|
163
|
-
|
|
164
|
-
|
|
157
|
+
if (locationData[0] && locationData[0][0]) {
|
|
158
|
+
user.id = locationData[0][0];
|
|
159
|
+
}
|
|
160
|
+
if (locationData[0] && locationData[0][1]) {
|
|
161
|
+
user.photoURL = locationData[0][1];
|
|
162
|
+
}
|
|
163
|
+
if (locationData[0] && locationData[0][3]) {
|
|
164
|
+
user.name = locationData[0][3];
|
|
165
|
+
}
|
|
166
|
+
if (locationData[1] && locationData[1][1] && locationData[1][1][2]) {
|
|
167
|
+
user.lat = locationData[1][1][2];
|
|
168
|
+
}
|
|
169
|
+
if (locationData[1] && locationData[1][1] && locationData[1][1][1]) {
|
|
170
|
+
user.long = locationData[1][1][1];
|
|
171
|
+
}
|
|
172
|
+
if (locationData[1] && locationData[1][4]) {
|
|
173
|
+
user.address = locationData[1][4];
|
|
174
|
+
}
|
|
175
|
+
if (locationData[13] && locationData[13][1]) {
|
|
176
|
+
user.battery = locationData[13][1];
|
|
177
|
+
}
|
|
178
|
+
if (locationData[1] && locationData[1][2]) {
|
|
179
|
+
user.timestamp = locationData[1][2];
|
|
180
|
+
}
|
|
181
|
+
if (locationData[1] && locationData[1][3]) {
|
|
182
|
+
user.accuracy = locationData[1][3];
|
|
183
|
+
}
|
|
165
184
|
}
|
|
166
185
|
|
|
167
186
|
if (user.id) {
|
|
168
|
-
const basepath = `users.${user.id}`;
|
|
187
|
+
const basepath = `users.${user.id as string}`;
|
|
169
188
|
const deviceObj = {
|
|
170
189
|
_id: basepath,
|
|
171
190
|
type: 'device',
|
|
172
191
|
common: {
|
|
173
192
|
name: user.name || user.id,
|
|
174
193
|
},
|
|
175
|
-
native: {}
|
|
194
|
+
native: {},
|
|
176
195
|
};
|
|
177
196
|
await this.setObjectNotExistsAsync(basepath, deviceObj as ioBroker.SettableDeviceObject);
|
|
178
197
|
|
|
@@ -188,7 +207,7 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
188
207
|
},
|
|
189
208
|
native: {},
|
|
190
209
|
});
|
|
191
|
-
await this.setState(`${basepath}.photoURL`, {val: user.photoURL, ts: user.timestamp, ack: true});
|
|
210
|
+
await this.setState(`${basepath}.photoURL`, { val: user.photoURL, ts: user.timestamp, ack: true });
|
|
192
211
|
}
|
|
193
212
|
|
|
194
213
|
if (user.name) {
|
|
@@ -203,7 +222,7 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
203
222
|
},
|
|
204
223
|
native: {},
|
|
205
224
|
});
|
|
206
|
-
await this.setState(`${basepath}.name`, {val: user.name, ts: user.timestamp, ack: true});
|
|
225
|
+
await this.setState(`${basepath}.name`, { val: user.name, ts: user.timestamp, ack: true });
|
|
207
226
|
}
|
|
208
227
|
|
|
209
228
|
if (user.lat) {
|
|
@@ -218,7 +237,7 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
218
237
|
},
|
|
219
238
|
native: {},
|
|
220
239
|
});
|
|
221
|
-
await this.setState(`${basepath}.lat`, {val: user.lat, ts: user.timestamp, ack: true});
|
|
240
|
+
await this.setState(`${basepath}.lat`, { val: user.lat, ts: user.timestamp, ack: true });
|
|
222
241
|
}
|
|
223
242
|
|
|
224
243
|
if (user.long) {
|
|
@@ -233,7 +252,7 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
233
252
|
},
|
|
234
253
|
native: {},
|
|
235
254
|
});
|
|
236
|
-
await this.setState(`${basepath}.long`, { val: user.long, ts: user.timestamp, ack: true});
|
|
255
|
+
await this.setState(`${basepath}.long`, { val: user.long, ts: user.timestamp, ack: true });
|
|
237
256
|
}
|
|
238
257
|
|
|
239
258
|
if (user.address) {
|
|
@@ -248,7 +267,7 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
248
267
|
},
|
|
249
268
|
native: {},
|
|
250
269
|
});
|
|
251
|
-
await this.setState(`${basepath}.address`, { val: user.address, ts: user.timestamp, ack: true});
|
|
270
|
+
await this.setState(`${basepath}.address`, { val: user.address, ts: user.timestamp, ack: true });
|
|
252
271
|
}
|
|
253
272
|
|
|
254
273
|
if (user.battery !== undefined) {
|
|
@@ -260,11 +279,11 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
260
279
|
read: true,
|
|
261
280
|
write: false,
|
|
262
281
|
role: 'value.battery',
|
|
263
|
-
unit: '%'
|
|
282
|
+
unit: '%',
|
|
264
283
|
},
|
|
265
284
|
native: {},
|
|
266
285
|
});
|
|
267
|
-
await this.setState(`${basepath}.battery`, { val: user.battery, ts: user.timestamp, ack: true});
|
|
286
|
+
await this.setState(`${basepath}.battery`, { val: user.battery, ts: user.timestamp, ack: true });
|
|
268
287
|
}
|
|
269
288
|
|
|
270
289
|
if (user.accuracy !== undefined) {
|
|
@@ -276,15 +295,15 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
276
295
|
read: true,
|
|
277
296
|
write: false,
|
|
278
297
|
role: 'value.gps.accuracy',
|
|
279
|
-
unit: 'm'
|
|
298
|
+
unit: 'm',
|
|
280
299
|
},
|
|
281
300
|
native: {},
|
|
282
301
|
});
|
|
283
|
-
await this.setState(`${basepath}.accuracy`, { val: user.accuracy, ts: user.timestamp, ack: true});
|
|
302
|
+
await this.setState(`${basepath}.accuracy`, { val: user.accuracy, ts: user.timestamp, ack: true });
|
|
284
303
|
}
|
|
285
304
|
}
|
|
286
305
|
} catch (e) {
|
|
287
|
-
this.log.error(
|
|
306
|
+
this.log.error(`Could not parse user location data: ${(e as Error).message}`);
|
|
288
307
|
}
|
|
289
308
|
}
|
|
290
309
|
|
|
@@ -294,6 +313,11 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
294
313
|
this.log.info('Seems we are already trying to log in. Aborting new login attempt.');
|
|
295
314
|
return;
|
|
296
315
|
}
|
|
316
|
+
if (!this.config.googleUsername || !this.config.googlePassword) {
|
|
317
|
+
this.log.warn('Google username or password not set in adapter configuration. Can not login.');
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
|
|
297
321
|
this.log.info('Trying to login to Google to get new cookies.');
|
|
298
322
|
this._successFullPolls = 0;
|
|
299
323
|
|
|
@@ -301,12 +325,8 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
301
325
|
this.log.debug('Starting browser.');
|
|
302
326
|
this._browser = await puppeteer.launch({
|
|
303
327
|
headless: true,
|
|
304
|
-
args: [
|
|
305
|
-
|
|
306
|
-
'--disable-setuid-sandbox',
|
|
307
|
-
'--disable-blink-features=AutomationControlled'
|
|
308
|
-
],
|
|
309
|
-
ignoreDefaultArgs: ['--enable-automation'] //hide automation flag, did not help.
|
|
328
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-blink-features=AutomationControlled'],
|
|
329
|
+
ignoreDefaultArgs: ['--enable-automation'], //hide automation flag, did not help.
|
|
310
330
|
});
|
|
311
331
|
this.log.debug('browser started, opening new page.');
|
|
312
332
|
const page = await this._browser.newPage();
|
|
@@ -315,13 +335,19 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
315
335
|
await page.evaluateOnNewDocument(() => {
|
|
316
336
|
Object.defineProperty(navigator, 'webdriver', { get: () => false });
|
|
317
337
|
});
|
|
318
|
-
await page.setUserAgent({
|
|
338
|
+
await page.setUserAgent({
|
|
339
|
+
userAgent:
|
|
340
|
+
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
341
|
+
});
|
|
319
342
|
|
|
320
343
|
this.log.debug('going to google login page.');
|
|
321
|
-
await page.goto(
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
344
|
+
await page.goto(
|
|
345
|
+
'https://accounts.google.com/ServiceLogin?hl=de&continue=https://www.google.com/maps&gae=cb-eomtm',
|
|
346
|
+
{
|
|
347
|
+
waitUntil: 'networkidle2',
|
|
348
|
+
timeout: 60000,
|
|
349
|
+
},
|
|
350
|
+
);
|
|
325
351
|
|
|
326
352
|
this.log.debug('filling in username and clicking next.');
|
|
327
353
|
await page.locator('#identifierId').fill(this.config.googleUsername);
|
|
@@ -358,7 +384,7 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
358
384
|
}
|
|
359
385
|
this._browser = null;
|
|
360
386
|
} catch (e) {
|
|
361
|
-
this.log.error(
|
|
387
|
+
this.log.error(`Error in puppeteer: ${(e as Error).message}`);
|
|
362
388
|
}
|
|
363
389
|
}
|
|
364
390
|
|
|
@@ -379,7 +405,10 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
379
405
|
}
|
|
380
406
|
if (this._browser) {
|
|
381
407
|
//ignore results here.
|
|
382
|
-
this._browser
|
|
408
|
+
this._browser
|
|
409
|
+
.close()
|
|
410
|
+
.then(() => {})
|
|
411
|
+
.catch(() => {});
|
|
383
412
|
}
|
|
384
413
|
callback();
|
|
385
414
|
} catch (error) {
|
|
@@ -419,7 +448,9 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
419
448
|
await this.sendRequest();
|
|
420
449
|
}
|
|
421
450
|
} else {
|
|
422
|
-
this.log.info(
|
|
451
|
+
this.log.info(
|
|
452
|
+
'Current cookies state was changed from outside the adapter, updating internal cookie store.',
|
|
453
|
+
);
|
|
423
454
|
this._cookies = state.val as string;
|
|
424
455
|
}
|
|
425
456
|
}
|
|
@@ -442,9 +473,9 @@ class GoogleSharedlocations2 extends utils.Adapter {
|
|
|
442
473
|
// }
|
|
443
474
|
}
|
|
444
475
|
//if (require.main !== module) {
|
|
445
|
-
|
|
446
|
-
|
|
476
|
+
// Export the constructor in compact mode
|
|
477
|
+
//module.exports = (options: Partial<utils.AdapterOptions> | undefined) => new GoogleSharedlocations2(options);
|
|
447
478
|
//} else {
|
|
448
|
-
|
|
449
|
-
|
|
479
|
+
// otherwise start the instance directly
|
|
480
|
+
(() => new GoogleSharedlocations2())();
|
|
450
481
|
//}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// iobroker prettier configuration file
|
|
2
|
+
import prettierConfig from '@iobroker/eslint-config/prettier.config.mjs';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
...prettierConfig,
|
|
6
|
+
// Adjust these to match your preferences:
|
|
7
|
+
useTabs: false, // or false for spaces
|
|
8
|
+
singleQuote: true, // or true for single quotes
|
|
9
|
+
};
|