alexa_remotectl 0.4.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d3641c9d28ab824390ab0dc3aebec594eb204fdb0d09f8536ded7a7efd541e62
4
- data.tar.gz: 8afb412ab356140e1289d1df7b49487bbc72e2b0d0593f43106f32dc8e643683
3
+ metadata.gz: f3390f693c5318ae22b5c79fbe464dacd839ef331c4d3f2a07e9aeed38229be2
4
+ data.tar.gz: adb89f569f0f47f88304c5032b963e171c556d340f928dd70de0437318c9b09f
5
5
  SHA512:
6
- metadata.gz: 7bf863c6ae5e8d4426a32d0b57b0c763aaff8534a0bc379eb3a30e0aaaebb564317d6463b4ab0025133d8b720721315a10c7dc00473c70bb79f4567d1961d1d9
7
- data.tar.gz: eb8b72c82327e56afc915dbe0ed2400a05db3ea061c5ae478e61b9cfc7f8e36e3f0f0c4b73908a97e45280f618bab40a9645a7d6f02429bc8f7400675d92e0f1
6
+ metadata.gz: 874e773c33e46ab1843c655ba49f138ffff68f9ef7a088cf550f5791c3e6fa567545f1e1a8fab52083b860c3c512ffdebd86f312059c2fc9d1e5def5a9881539
7
+ data.tar.gz: f0f91e9861f1cd68e3d2494341f6bbc28f2d482d5766b124b66f65e9cab60fa34d03f199516bc1f75936320e620096f40d9b33c9a98dfb2991575529c1736bbe
checksums.yaml.gz.sig CHANGED
Binary file
@@ -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,22 @@ 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
- def initialize(domain: 'alexa.amazon.co.uk', device: {}, cookie: '')
63
+ # note: Added the Cross-site request forgery (crsf) variable
64
+ #
65
+ def initialize(domain: 'alexa.amazon.co.uk', device: {}, cookie: '',
66
+ customerid: '', csrf: '')
62
67
 
63
- @domain, @device, @cookie = domain, device, cookie
68
+ @domain, @device, @cookie, @customerid = domain, device, cookie, customerid
69
+ @csrf = csrf
64
70
 
65
71
  end
66
72
 
@@ -68,6 +74,17 @@ class AlexaRemoteCtl
68
74
  device_player()[:playerInfo]
69
75
  end
70
76
 
77
+ def list_ebooks()
78
+ get_json '/api/ebooks/library', "mediaOwnerCustomerId=#{@customerid}" +
79
+ "&nextToken=&size=50"
80
+ end
81
+
82
+ # list historical queue (hq)
83
+ #
84
+ def list_hq()
85
+ get_json '/api/media/historical-queue', "size=50&offset=-1"
86
+ end
87
+
71
88
  def mute?()
72
89
  info()[:volume][:muted]
73
90
  end
@@ -87,6 +104,31 @@ class AlexaRemoteCtl
87
104
  pp_cmd('Play')
88
105
  end
89
106
 
107
+ def play_ebook(id)
108
+
109
+ serialno = @device[:serialno]
110
+ type = @device[:type]
111
+
112
+ url = "https://#{@domain}/api/ebooks/queue-and-play?"
113
+
114
+ body = {
115
+ 'asin' => id,
116
+ 'deviceType' => type,
117
+ 'deviceSerialNumber' => serialno,
118
+ 'mediaOwnerCustomerId' => @customerid
119
+ }.to_json
120
+
121
+ post_request url, body
122
+
123
+ end
124
+
125
+ # play historical queue
126
+ # note: You can find the queueid from an entry in the list_hq() result
127
+ #
128
+ def play_hq(queueid)
129
+ device_phq(queueid)
130
+ end
131
+
90
132
  def playing?()
91
133
  info()[:state] == 'PLAYING'
92
134
  end
@@ -136,18 +178,51 @@ class AlexaRemoteCtl
136
178
  serialno = @device[:serialno]
137
179
  type = @device[:type]
138
180
 
139
- url = "https://#{@domain}/api/np/command?deviceSerialNumber=#{serialno}&deviceType=#{type}"
181
+ url = "https://#{@domain}/api/np/command?deviceSerial" +
182
+ "Number=#{serialno}&deviceType=#{type}"
140
183
  post_command url, body
141
184
 
142
185
  end
143
186
 
187
+ # play historical queue (PHQ)
188
+ #
189
+ def device_phq(queueid)
190
+
191
+ serialno = @device[:serialno]
192
+ type = @device[:type]
193
+
194
+ url = "https://#{@domain}/api/media/play-historical-queue"
195
+
196
+ body = {
197
+ 'deviceType' => type,
198
+ 'deviceSerialNumber' => serialno,
199
+ 'queueId' => queueid,
200
+ 'startTime' => nil,
201
+ 'service' => nil,
202
+ 'trackSource' => nil,
203
+ 'mediaOwnerCustomerId' => @customerid
204
+ }.to_json
205
+
206
+ post_request url, body
207
+
208
+ end
209
+
144
210
  def device_player()
211
+ get_json '/api/np/player'
212
+ end
213
+
214
+ def get_json(uri, params='')
215
+
145
216
  serialno = @device[:serialno]
146
217
  type = @device[:type]
147
218
 
148
- url = "https://#{@domain}/api/np/player?deviceSerialNumber=#{serialno}&deviceType=#{type}"
149
- r = post_request url
219
+ url = "https://#{@domain}#{uri}?deviceSerial" +
220
+ "Number=#{serialno}&deviceType=#{type}"
221
+ url += '&' + params if params.length > 1
222
+
223
+ r = get_request url
150
224
  JSON.parse(r.body, symbolize_names: true)
225
+
151
226
  end
152
227
 
153
228
  def make_response(uri, request)
@@ -155,16 +230,17 @@ class AlexaRemoteCtl
155
230
  request["Accept"] = "application/json, text/javascript, */*; q=0.01"
156
231
  request["Accept-Language"] = "en-GB,en-US;q=0.9,en;q=0.8"
157
232
  request["Connection"] = "keep-alive"
158
- request["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8"
159
233
  request["Cookie"] = @cookie
160
234
 
161
235
  request["Referer"] = "https://#{@domain}/spa/index.html"
162
236
  request["Sec-Fetch-Dest"] = "empty"
163
237
  request["Sec-Fetch-Mode"] = "cors"
164
238
  request["Sec-Fetch-Site"] = "same-origin"
165
- request["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36"
239
+ request["User-Agent"] = "Mozilla/5.0 (X11; Linux x86_64) " +
240
+ "AppleWebKit/537.36 (KHTML, like Gecko) " +
241
+ "Chrome/101.0.4951.64 Safari/537.36"
166
242
  request["X-Requested-With"] = "XMLHttpRequest"
167
- request["csrf"] = "-990908140"
243
+ request["csrf"] = @csrf
168
244
  request["dnt"] = "1"
169
245
  request["sec-ch-ua"] = "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"101\""
170
246
  request["sec-ch-ua-mobile"] = "?0"
@@ -181,6 +257,7 @@ class AlexaRemoteCtl
181
257
  end
182
258
 
183
259
  def post_command(url, body='')
260
+
184
261
  uri = URI.parse(url)
185
262
  request = Net::HTTP::Post.new(uri)
186
263
  request.body = body
@@ -193,7 +270,7 @@ class AlexaRemoteCtl
193
270
  # response.body
194
271
  end
195
272
 
196
- def post_request(url)
273
+ def get_request(url)
197
274
 
198
275
  uri = URI.parse(url)
199
276
  request = Net::HTTP::Get.new(uri)
@@ -204,6 +281,19 @@ class AlexaRemoteCtl
204
281
 
205
282
  end
206
283
 
284
+
285
+ def post_request(url, body='')
286
+
287
+ uri = URI.parse(url)
288
+ request = Net::HTTP::Post.new(uri)
289
+ request.body = body
290
+ response = make_response(uri, request)
291
+
292
+ # response.code
293
+ # response.body
294
+
295
+ end
296
+
207
297
  end
208
298
 
209
299
  class AlexaDevices
@@ -212,59 +302,85 @@ class AlexaDevices
212
302
  # note: label can be any identifier you choose e.g. kitchen
213
303
  #
214
304
  def initialize(devicesx=[], devices: devicesx,
215
- domain: 'alexa.amazon.co.uk', cookie: '')
305
+ domain: 'alexa.amazon.co.uk', cookie: '', customerid: '',
306
+ csrf: '', debug: false)
216
307
 
217
308
  @devices, @domain, @cookie = devices, domain, cookie
309
+ @customerid, @csrf, @debug = customerid, csrf, debug
218
310
 
219
311
  end
220
312
 
313
+ def info(id=nil) invoke(:info, id) end
314
+ def list_ebooks(id) invoke(:list_ebooks, id) end
315
+ def list_hq(id=nil) invoke(:list_hq, id) end
316
+ def mute?(id=nil) invoke2(:mute?, id) end
317
+ def next(id) invoke2(:next, id) end
318
+
221
319
  def playing()
222
320
 
223
- @devices.map do |device, label|
224
- alexa = AlexaRemoteCtl.new(cookie: @cookie, device: device)
225
- alexa.playing? ? [alexa, label] : nil
226
- end.compact
321
+ devices = @devices.map do |device, label|
227
322
 
228
- end
323
+ puts 'label: ' + label.inspect if @debug
324
+ puts 'device: ' + device.inspect if @debug
229
325
 
230
- def pause(id=nil)
326
+ alexa = get_alexa device
327
+ alexa.playing? ? [alexa, label] : nil
231
328
 
232
- a = playing()
329
+ end.compact
233
330
 
234
- if id then
331
+ puts 'devices: ' + devices.inspect if @debug
332
+ return devices
235
333
 
236
- alexa, _ = a.find {|_, label| label.to_sym == id.to_sym}
237
- alexa.pause
334
+ end
238
335
 
239
- else
336
+ def pause(id=nil) invoke2(:pause, id) end
337
+ def play(id) invoke(:play, id) end
338
+ def play_ebook(id) invoke(:list_hq, id) end
339
+ def play_hq(id,qid) invoke(:play_hq, id, qid) end
340
+ def playing?(id=nil) invoke(:playing, id) end
341
+ def text1(id=nil) invoke2(:text1, id) end
342
+ def text2(id=nil) invoke2(:text2, id) end
343
+ def title(id=nil) invoke2(:title, id) end
344
+ def vol(id=nil) invoke(:vol, id) end
345
+ def vol=(id=nil) invoke(:vol=, id) end
240
346
 
241
- a.each do |alexa, label|
242
- puts 'Pausing @' + label.inspect
243
- alexa.pause
244
- end
347
+ private
245
348
 
246
- end
247
- end
349
+ def get_alexa(device)
248
350
 
249
- def play(id=nil)
351
+ AlexaRemoteCtl.new(cookie: @cookie, device: device,
352
+ customerid: @customerid, csrf: @csrf)
353
+ end
250
354
 
251
- a = @devices
355
+ def apply_cmd(a, cmd, id, args)
252
356
 
253
357
  if id then
254
358
 
255
359
  device, _ = a.find {|_, label| label.to_sym == id.to_sym}
256
- alexa = AlexaRemoteCtl.new(cookie: @cookie, device: device)
257
- alexa.play
360
+ alexa = get_alexa device
361
+ alexa.method(cmd).call(*args)
258
362
 
259
363
  else
260
364
 
261
- a.each do |device, label|
262
- puts 'Pausing @' + label.inspect
263
- alexa = AlexaRemoteCtl.new(cookie: @cookie, device: device)
264
- alexa.play
365
+ a.map do |device, label|
366
+
367
+ puts cmd.to_s + ' @' + label.inspect
368
+ alexa = get_alexa device
369
+ alexa.method(cmd).call(*args)
370
+
265
371
  end
266
372
 
267
373
  end
268
374
  end
269
375
 
376
+ def invoke(cmd, id, *args)
377
+ apply_cmd(@devices, cmd, id, args)
378
+ end
379
+
380
+ # apply command to an Alexa device which is currently playing
381
+ #
382
+ def invoke2(cmd, id, *args)
383
+ apply_cmd(playing(), cmd, id, args)
384
+ end
385
+
270
386
  end
data.tar.gz.sig CHANGED
@@ -1,2 +1,3 @@
1
- q�!O��,>�n���$�}���1t�?(��y���?��Ҥ��d]R
2
- ���]],�\]��v4#�K^²Ed�ϟ�LO��WT�ո{�|ݬrCRR� P���[�����,alxm�Ł�<�q���T���_
1
+ :�c>j<�;Iy6A�-=�i)�+4��b�
2
+ "M�b�*��+�jM`|����L_WM�+ѫ�5�GX�T�E>u�T�ehK�[oO�P�ф�^e�)�MƢฮ�$����k�I�9�~b��Ӭ*�Ȩ+�22��,GA-��*ϑ`�[V��83ݽ�snf�՜L
3
+
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.0
4
+ version: 0.4.3
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-22 00:00:00.000000000 Z
38
+ date: 2022-05-23 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: clipboard
metadata.gz.sig CHANGED
Binary file