alexa_remotectl 0.3.0 → 0.4.2
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/alexa_remotectl.rb +171 -12
- data.tar.gz.sig +0 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 769f37b93490b3ab472fea0e8bc15dc1ce3c2e34cb3b4c01ce0ddc6c296fdff9
|
4
|
+
data.tar.gz: 66bdfb5add38d18635c34469ebd2a508a152daa76319c043ccfc81c67569781d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50ae6554ebe0f56317439880759316c90cfcd154d564cf45db4d517c5471115a10d0f4bad197e74090f96cc952fa9bf8f5f1dd43c0889285c78822022fd488ad
|
7
|
+
data.tar.gz: ab6a5c377f4575298d29dbe02592a7a3a20949a7a88326926ab968d725cd2a3e9ec7ccc3cf71aca1300f2fa56dd14964653aff09f9d501538031639ca04fe07f
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/lib/alexa_remotectl.rb
CHANGED
@@ -22,14 +22,15 @@ class CodeWizard
|
|
22
22
|
|
23
23
|
return 'no curl command found' unless s =~ /curl/
|
24
24
|
|
25
|
-
cookie, serialno, type = parse(s)
|
25
|
+
cookie, csrf, serialno, type = parse(s)
|
26
26
|
|
27
27
|
@s =<<EOF
|
28
28
|
require 'alexa_remotectl'
|
29
29
|
|
30
30
|
cookie = '#{cookie}'
|
31
|
+
csrf = '#{csrf}'
|
31
32
|
device = {serialno: '#{serialno}', type: '#{type}'}
|
32
|
-
alexa = AlexaRemoteCtl.new(cookie: cookie, device: device)
|
33
|
+
alexa = AlexaRemoteCtl.new(cookie: cookie, csrf: csrf, device: device)
|
33
34
|
alexa.pause
|
34
35
|
#alexa.play
|
35
36
|
EOF
|
@@ -50,17 +51,21 @@ EOF
|
|
50
51
|
serialno = s[/deviceSerialNumber=(\w+)/,1]
|
51
52
|
type = s[/deviceType=(\w+)/,1]
|
52
53
|
cookie = s[/Cookie: ([^']+)/,1]
|
54
|
+
csrf = s[/csrf: ([^']+)/,1]
|
53
55
|
|
54
|
-
[cookie, serialno, type]
|
56
|
+
[cookie, csrf, serialno, type]
|
55
57
|
|
56
58
|
end
|
57
59
|
end
|
58
60
|
|
59
61
|
class AlexaRemoteCtl
|
60
62
|
|
61
|
-
|
63
|
+
# note: Added the Cross-site request forgery (crsf) variable
|
64
|
+
#
|
65
|
+
def initialize(domain: 'alexa.amazon.co.uk', device: {}, cookie: '', customerid: '', csrf: '')
|
62
66
|
|
63
|
-
@domain, @device, @cookie = domain, device, cookie
|
67
|
+
@domain, @device, @cookie, @customerid = domain, device, cookie, customerid
|
68
|
+
@csrf = csrf
|
64
69
|
|
65
70
|
end
|
66
71
|
|
@@ -68,6 +73,11 @@ class AlexaRemoteCtl
|
|
68
73
|
device_player()[:playerInfo]
|
69
74
|
end
|
70
75
|
|
76
|
+
def list_ebooks()
|
77
|
+
get_json '/api/ebooks/library', "mediaOwnerCustomerId=#{@customerid}" +
|
78
|
+
"&nextToken=&size=50"
|
79
|
+
end
|
80
|
+
|
71
81
|
def mute?()
|
72
82
|
info()[:volume][:muted]
|
73
83
|
end
|
@@ -87,6 +97,32 @@ class AlexaRemoteCtl
|
|
87
97
|
pp_cmd('Play')
|
88
98
|
end
|
89
99
|
|
100
|
+
def play_ebook(id)
|
101
|
+
|
102
|
+
serialno = @device[:serialno]
|
103
|
+
type = @device[:type]
|
104
|
+
|
105
|
+
url = "https://#{@domain}/api/ebooks/queue-and-play?"
|
106
|
+
|
107
|
+
body = {
|
108
|
+
'asin' => id,
|
109
|
+
'deviceType' => type,
|
110
|
+
'deviceSerialNumber' => serialno,
|
111
|
+
'mediaOwnerCustomerId' => @customerid
|
112
|
+
}.to_json
|
113
|
+
|
114
|
+
post_request url, body
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
def play_hq(id)
|
119
|
+
device_phq(id)
|
120
|
+
end
|
121
|
+
|
122
|
+
def playing?()
|
123
|
+
info()[:state] == 'PLAYING'
|
124
|
+
end
|
125
|
+
|
90
126
|
# Artist name
|
91
127
|
#
|
92
128
|
def text1()
|
@@ -132,18 +168,51 @@ class AlexaRemoteCtl
|
|
132
168
|
serialno = @device[:serialno]
|
133
169
|
type = @device[:type]
|
134
170
|
|
135
|
-
url = "https://#{@domain}/api/np/command?
|
171
|
+
url = "https://#{@domain}/api/np/command?deviceSerial" +
|
172
|
+
"Number=#{serialno}&deviceType=#{type}"
|
136
173
|
post_command url, body
|
137
174
|
|
138
175
|
end
|
139
176
|
|
177
|
+
# play historical queue (PHQ)
|
178
|
+
#
|
179
|
+
def device_phq(queueid)
|
180
|
+
|
181
|
+
serialno = @device[:serialno]
|
182
|
+
type = @device[:type]
|
183
|
+
|
184
|
+
url = "https://#{@domain}/api/media/play-historical-queue"
|
185
|
+
|
186
|
+
body = {
|
187
|
+
'deviceType' => type,
|
188
|
+
'deviceSerialNumber' => serialno,
|
189
|
+
'queueId' => queueid,
|
190
|
+
'startTime' => nil,
|
191
|
+
'service' => nil,
|
192
|
+
'trackSource' => nil,
|
193
|
+
'mediaOwnerCustomerId' => @customerid
|
194
|
+
}.to_json
|
195
|
+
|
196
|
+
post_request url, body
|
197
|
+
|
198
|
+
end
|
199
|
+
|
140
200
|
def device_player()
|
201
|
+
get_json '/api/np/player'
|
202
|
+
end
|
203
|
+
|
204
|
+
def get_json(uri, params='')
|
205
|
+
|
141
206
|
serialno = @device[:serialno]
|
142
207
|
type = @device[:type]
|
143
208
|
|
144
|
-
url = "https://#{@domain}
|
145
|
-
|
209
|
+
url = "https://#{@domain}#{uri}?deviceSerial" +
|
210
|
+
"Number=#{serialno}&deviceType=#{type}"
|
211
|
+
url += '&' + params if params.length > 1
|
212
|
+
|
213
|
+
r = get_request url
|
146
214
|
JSON.parse(r.body, symbolize_names: true)
|
215
|
+
|
147
216
|
end
|
148
217
|
|
149
218
|
def make_response(uri, request)
|
@@ -151,16 +220,17 @@ class AlexaRemoteCtl
|
|
151
220
|
request["Accept"] = "application/json, text/javascript, */*; q=0.01"
|
152
221
|
request["Accept-Language"] = "en-GB,en-US;q=0.9,en;q=0.8"
|
153
222
|
request["Connection"] = "keep-alive"
|
154
|
-
request["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8"
|
155
223
|
request["Cookie"] = @cookie
|
156
224
|
|
157
225
|
request["Referer"] = "https://#{@domain}/spa/index.html"
|
158
226
|
request["Sec-Fetch-Dest"] = "empty"
|
159
227
|
request["Sec-Fetch-Mode"] = "cors"
|
160
228
|
request["Sec-Fetch-Site"] = "same-origin"
|
161
|
-
request["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64)
|
229
|
+
request["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) " +
|
230
|
+
"AppleWebKit/537.36 (KHTML, like Gecko) " +
|
231
|
+
"Chrome/101.0.4951.64 Safari/537.36"
|
162
232
|
request["X-Requested-With"] = "XMLHttpRequest"
|
163
|
-
request["csrf"] =
|
233
|
+
request["csrf"] = @csrf
|
164
234
|
request["dnt"] = "1"
|
165
235
|
request["sec-ch-ua"] = "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"101\""
|
166
236
|
request["sec-ch-ua-mobile"] = "?0"
|
@@ -177,6 +247,7 @@ class AlexaRemoteCtl
|
|
177
247
|
end
|
178
248
|
|
179
249
|
def post_command(url, body='')
|
250
|
+
|
180
251
|
uri = URI.parse(url)
|
181
252
|
request = Net::HTTP::Post.new(uri)
|
182
253
|
request.body = body
|
@@ -189,7 +260,7 @@ class AlexaRemoteCtl
|
|
189
260
|
# response.body
|
190
261
|
end
|
191
262
|
|
192
|
-
def
|
263
|
+
def get_request(url)
|
193
264
|
|
194
265
|
uri = URI.parse(url)
|
195
266
|
request = Net::HTTP::Get.new(uri)
|
@@ -200,4 +271,92 @@ class AlexaRemoteCtl
|
|
200
271
|
|
201
272
|
end
|
202
273
|
|
274
|
+
|
275
|
+
def post_request(url, body='')
|
276
|
+
|
277
|
+
uri = URI.parse(url)
|
278
|
+
request = Net::HTTP::Post.new(uri)
|
279
|
+
request.body = body
|
280
|
+
response = make_response(uri, request)
|
281
|
+
|
282
|
+
# response.code
|
283
|
+
# response.body
|
284
|
+
|
285
|
+
end
|
286
|
+
|
287
|
+
end
|
288
|
+
|
289
|
+
class AlexaDevices
|
290
|
+
|
291
|
+
# devices = [[{*serialno*, *type*}, label], ...]
|
292
|
+
# note: label can be any identifier you choose e.g. kitchen
|
293
|
+
#
|
294
|
+
def initialize(devicesx=[], devices: devicesx,
|
295
|
+
domain: 'alexa.amazon.co.uk', cookie: '', customerid: '',
|
296
|
+
csrf: '')
|
297
|
+
|
298
|
+
@devices, @domain, @cookie = devices, domain, cookie
|
299
|
+
@customerid, @csrf = customerid, csrf
|
300
|
+
|
301
|
+
end
|
302
|
+
|
303
|
+
def playing()
|
304
|
+
|
305
|
+
@devices.map do |device, label|
|
306
|
+
alexa = get_alexa device
|
307
|
+
alexa.playing? ? [alexa, label] : nil
|
308
|
+
end.compact
|
309
|
+
|
310
|
+
end
|
311
|
+
|
312
|
+
def pause(id=nil)
|
313
|
+
|
314
|
+
a = playing()
|
315
|
+
|
316
|
+
if id then
|
317
|
+
|
318
|
+
alexa, _ = a.find {|_, label| label.to_sym == id.to_sym}
|
319
|
+
alexa.pause
|
320
|
+
|
321
|
+
else
|
322
|
+
|
323
|
+
a.each do |alexa, label|
|
324
|
+
puts 'Pausing @' + label.inspect
|
325
|
+
alexa.pause
|
326
|
+
end
|
327
|
+
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
def play(id=nil)
|
332
|
+
|
333
|
+
a = @devices
|
334
|
+
|
335
|
+
if id then
|
336
|
+
|
337
|
+
device, _ = a.find {|_, label| label.to_sym == id.to_sym}
|
338
|
+
alexa = get_alexa device
|
339
|
+
alexa.play
|
340
|
+
|
341
|
+
else
|
342
|
+
|
343
|
+
a.each do |device, label|
|
344
|
+
|
345
|
+
puts 'Pausing @' + label.inspect
|
346
|
+
alexa = get_alexa device
|
347
|
+
alexa.play
|
348
|
+
|
349
|
+
end
|
350
|
+
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
private
|
355
|
+
|
356
|
+
def get_alexa(device)
|
357
|
+
|
358
|
+
AlexaRemoteCtl.new(cookie: @cookie, device: device,
|
359
|
+
customerid: @customerid, csrf: @csrf)
|
360
|
+
end
|
361
|
+
|
203
362
|
end
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alexa_remotectl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Robertson
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
d/gEwBtUmduwWZNX2NOJehf8s1cnH9OBP7s1ziHjdkZCgkQm3QewRRcdfZeYwFi6
|
36
36
|
4kVEcApgAgd+04ctE6uiRn5o
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2022-05-
|
38
|
+
date: 2022-05-22 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: clipboard
|
metadata.gz.sig
CHANGED
Binary file
|