mirror of
https://github.com/thorsten-gehrig/alexa-remote-control.git
synced 2024-11-14 04:49:03 +01:00
Merge pull request #1 from adn77/adn77-cookie-automation
new script (cookie and data extraction automated)
This commit is contained in:
commit
71cbdad09d
38
README.md
38
README.md
@ -1 +1,37 @@
|
||||
see my branch adn77-ccokie-automation (https://github.com/adn77/alexa-remote-control/tree/adn77-cookie-automation) for the latest version
|
||||
|
||||
# alexa-remote-control
|
||||
control Amazon Alexa from command Line
|
||||
|
||||
```
|
||||
alexa-remote-control [-d <device>|ALL] -e <pause|play|next|prev|fwd|rwd|shuffle|vol:<0-100>> |
|
||||
-b [list|<\"AA:BB:CC:DD:EE:FF\">] | -q | -r <\"station name\"|stationid> |
|
||||
-s <trackID> | -t <ASIN> | -u <seedID> | -v <queueID> | -w <playlistId> |
|
||||
-i | -p | -a | -P | -S | -m <multiroom_device> [device_1 .. device_X] | -l | -h
|
||||
-e : run command
|
||||
-q : query queue
|
||||
-b : connect/disconnect/list bluetooth device
|
||||
-r : play tunein radio
|
||||
-s : play library track
|
||||
-t : play Prime playlist
|
||||
-u : play Prime station
|
||||
-v : play Prime historical queue
|
||||
-w : play library playlist
|
||||
-i : list imported library tracks
|
||||
-p : list purchased library tracks
|
||||
-P : list Prime playlists
|
||||
-S : list Prime stations
|
||||
-a : list available devices
|
||||
-m : delete multiroom and/or create new multiroom containing devices
|
||||
-l : logoff
|
||||
-h : help
|
||||
```
|
||||
|
||||
There's also a "plain" version, which lacks some functionality (-i, -p, -P, -S and no radio station names) but doesn't require 'jq' for JSON processing.
|
||||
|
||||
http://blog.loetzimmer.de/2017/10/amazon-alexa-hort-auf-die-shell-echo.html
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
DEVICENUMBER='G090LF1234540B82'
|
||||
DEVICETYPE='A3S5123456VAYF'
|
||||
COOKIE='Cookie: x-amzn-dat-gui-client-v=1.24.986.0; aws-target-static-id=14712345678-839972; aws-session-id=168-0412369-4130549; aws-session-id-time=2106194071l; aws-x-main=PgpqvER9Wibauhf4zfSDriNBlBILfMnk; aws-at-main=Atza|IwEBIAFsntUWFc_PZvFde5drDzPNXXXXXXXXXHPqI53aQNl-Fu83eAMUsFJmMtamv_4mLKEh6N82lqq8OHA8SKgh44X2MZwTguXNcUvd0-RVQyayT2lQ86JjoXvJrlMlrZIs7kJLWBryCGJEXXXXXXXXXXFJQpHhnGeC72ljNT_nVObL_wZoYhMFHVMXGiYjFyrb-QcjYY-I3ar-Q-kLAmzZYQIKU-mZ8GChNefKuG_x4ZZ2A06XXXXXXXXXOhX9w94vgmn2y3Qr9Q0rEi8K--UoFuTQ54GArubNsofNLh4U2dov8D7Gs3GoW6Hp2zEwt7cyumpRR_vceAz3aUjskoNKXsgDfpPZrebl-0R4bC6BfIasyoDOX9XXXXXXXXjRihKSxf4gs79p1ExYBmaBOX6glBrsKRqOXfk6Vh87_96uQ; aws-userInfo=%7B%22arn%22%3A%22arn%3Aaws%3Aiam%3A%3A314911114493%3Aroot%22%2C%22alias%22%3A%22%22%2C%22username%22%3A%22MeinUser%2520Name%22%2C%22keybase%22%3A%22dhVv%2Fmb%2BJyCH%2BJA6zwfighlgs5jc0W0mVYXkLBkb77M%5Cu003d%22%2C%22issuer%22%3A%22https%3A%2F%2Fwww.amazon.com%2Fap%2Fsignin%22%7D; __utmv=191231197.PgpqvER9Wibauhf4zfSDXXXXXXXXk; s_dslv=1475471239073; regStatus=registered; aws-target-visitor-id=1475445653051-715340.26_4; aws-target-data=%7B%22support%22%3A%221%22%7D; s_pers=%20s_ev15%3D%255B%255B%2527Typed%252FBookmarked%2527%252C%25212375474893114%2527%255D%255D%7C1632141293114%3B%20s_fid%3D0523A63XXXXXXXXX3C9679E640DA3570%7C1538547024210%3B%20s_dl%3D1%7C1475481765932%3B%20gpv_page%3Dno%2520value%7C1475481765939%3B; session-id=151-3512347-8293901; session-id-time=2106212731l; s_fid=71689F1234D6D238-299FD69294EFC3C1; s_nr=1475492764173-Repeat; aws-ubid-main=151-3388123-1263140; aws-session-token="lprp9YroXXXXXXXXXz5EFfSaPt96R0oSBWL2dR/AGFdlmk4QwRcVPXXXXXXXrmZ5kfHBdNwvSWWMKTnYU0pB5CE2XXXXXXUk6SIuaQYti17ZQ8B3NGwyCKNs7Lil+kz9qonZS5/cwtmrWHCe7SGx/QmPXXXXXXX89WbiV2xwTRkhVw6hTjO+8WUOXXXXXXXXi8MaR196v+Ewflx7dd3ouTVtY+hbJE4XSs="; __utma=194891197.1975555581.1444474071.1475495555.1475555580.5; __utmz=194555597.1475555680.5.2.utmccn=(referral)|utmcsr=console.aws.amazon.com|utmcct=/cloudwatch/home|utmcmd=referral; ubid-main=152-8362434-2710144; session-token="Y2Eoqs81+wIbanI7mPonK9t7gFvH7ZdTG2OxCZB3orqTILNY5ev4cFBWiSPTl2u8nFNXNmwtFP6RxnPBTunkdbHfpos8WYYOX7gEF52wnn5J3SknsvO99+MAT5GeyMR4JRa+ZOX+DcnIt8xtgYY2sSaEZ3JspjrQF+M9PUkuT9D4aYbZGRNa1BkFvoOt8Kettr9xxS/ODPfXEaE6xJr7qyPv0IQ3K6e+FbfGk3AWypY="; x-main=4r7ZrJJV4BT1R2sWn2W4NpiXZm9RSJLD; at-main=Atza|IwEEEEE4EikDns-CTHnGRqXXXcnnaij75AfcF1-XOBvphYTp_ATJHu6f0vDgMI7B1ApWn51cP6bqvG-XXXXeTPD8t7jl5El_FdhlYn3mmtn476FfnI5E7anoZNSKLyE-jauNJssBeGUjsSd0z8746mujYcJbKQsMMVVUlxcu4jXXxXXYcC4GasQyvOIp92wY-TPKAOys8NV0-yXH4xTGBzgJ0zzJa5JvyRz2v0x3fijvyXXXXXXSDhZtaDOZ6GOQlYrsUmudsorYUcUT52x0EYavXXXXX92cmgkMUzuTxppV1SpLk2Wk63LQQkCCZLs6_HWlnX2Saf0zgc13BdUehhSBiYHzJJeg1Ys7g68GLG5IuSGvyGe8ebmcN9KUDdD2CwphaeW34iy6dVKGbUpJ3GKVlz; sess-at-main="eSHstcxm5Krki5T1EAcQyk9XXXXXXqMbqcJqDBaA="; csrf=-2012345694'
|
||||
CSRF='csrf: -2081234594'
|
||||
|
||||
CMD='{"type":"PauseCommand"}'
|
||||
URL='https://pitangui.amazon.com/api/np/command?deviceSerialNumber='$DEVICENUMBER'&deviceType='$DEVICETYPE
|
||||
curl $URL \
|
||||
-H "$COOKIE" \
|
||||
-H "$CSRF" \
|
||||
--data "${CMD}" \
|
||||
--compressed
|
@ -1,24 +0,0 @@
|
||||
#!/bin/bash
|
||||
DEVICENUMBER='G090LF0912345B82'
|
||||
DEVICETYPE='A3S5B12345VAYF'
|
||||
CUSTOMERID='A2C7I1234559PS'
|
||||
COOKIE='Cookie: x-amzn-dat-gui-client-v=1.24.986.0; aws-target-static-id=14712345678-839972; aws-session-id=168-0412369-4130549; aws-session-id-time=2106194071l; aws-x-main=PgpqvER9Wibauhf4zfSDriNBlBILfMnk; aws-at-main=Atza|IwEBIAFsntUWFc_PZvFde5drDzPNXXXXXXXXXHPqI53aQNl-Fu83eAMUsFJmMtamv_4mLKEh6N82lqq8OHA8SKgh44X2MZwTguXNcUvd0-RVQyayT2lQ86JjoXvJrlMlrZIs7kJLWBryCGJEXXXXXXXXXXFJQpHhnGeC72ljNT_nVObL_wZoYhMFHVMXGiYjFyrb-QcjYY-I3ar-Q-kLAmzZYQIKU-mZ8GChNefKuG_x4ZZ2A06XXXXXXXXXOhX9w94vgmn2y3Qr9Q0rEi8K--UoFuTQ54GArubNsofNLh4U2dov8D7Gs3GoW6Hp2zEwt7cyumpRR_vceAz3aUjskoNKXsgDfpPZrebl-0R4bC6BfIasyoDOX9XXXXXXXXjRihKSxf4gs79p1ExYBmaBOX6glBrsKRqOXfk6Vh87_96uQ; aws-userInfo=%7B%22arn%22%3A%22arn%3Aaws%3Aiam%3A%3A314911114493%3Aroot%22%2C%22alias%22%3A%22%22%2C%22username%22%3A%22MeinUser%2520Name%22%2C%22keybase%22%3A%22dhVv%2Fmb%2BJyCH%2BJA6zwfighlgs5jc0W0mVYXkLBkb77M%5Cu003d%22%2C%22issuer%22%3A%22https%3A%2F%2Fwww.amazon.com%2Fap%2Fsignin%22%7D; __utmv=191231197.PgpqvER9Wibauhf4zfSDXXXXXXXXk; s_dslv=1475471239073; regStatus=registered; aws-target-visitor-id=1475445653051-715340.26_4; aws-target-data=%7B%22support%22%3A%221%22%7D; s_pers=%20s_ev15%3D%255B%255B%2527Typed%252FBookmarked%2527%252C%25212375474893114%2527%255D%255D%7C1632141293114%3B%20s_fid%3D0523A63XXXXXXXXX3C9679E640DA3570%7C1538547024210%3B%20s_dl%3D1%7C1475481765932%3B%20gpv_page%3Dno%2520value%7C1475481765939%3B; session-id=151-3512347-8293901; session-id-time=2106212731l; s_fid=71689F1234D6D238-299FD69294EFC3C1; s_nr=1475492764173-Repeat; aws-ubid-main=151-3388123-1263140; aws-session-token="lprp9YroXXXXXXXXXz5EFfSaPt96R0oSBWL2dR/AGFdlmk4QwRcVPXXXXXXXrmZ5kfHBdNwvSWWMKTnYU0pB5CE2XXXXXXUk6SIuaQYti17ZQ8B3NGwyCKNs7Lil+kz9qonZS5/cwtmrWHCe7SGx/QmPXXXXXXX89WbiV2xwTRkhVw6hTjO+8WUOXXXXXXXXi8MaR196v+Ewflx7dd3ouTVtY+hbJE4XSs="; __utma=194891197.1975555581.1444474071.1475495555.1475555580.5; __utmz=194555597.1475555680.5.2.utmccn=(referral)|utmcsr=console.aws.amazon.com|utmcct=/cloudwatch/home|utmcmd=referral; ubid-main=152-8362434-2710144; session-token="Y2Eoqs81+wIbanI7mPonK9t7gFvH7ZdTG2OxCZB3orqTILNY5ev4cFBWiSPTl2u8nFNXNmwtFP6RxnPBTunkdbHfpos8WYYOX7gEF52wnn5J3SknsvO99+MAT5GeyMR4JRa+ZOX+DcnIt8xtgYY2sSaEZ3JspjrQF+M9PUkuT9D4aYbZGRNa1BkFvoOt8Kettr9xxS/ODPfXEaE6xJr7qyPv0IQ3K6e+FbfGk3AWypY="; x-main=4r7ZrJJV4BT1R2sWn2W4NpiXZm9RSJLD; at-main=Atza|IwEEEEE4EikDns-CTHnGRqXXXcnnaij75AfcF1-XOBvphYTp_ATJHu6f0vDgMI7B1ApWn51cP6bqvG-XXXXeTPD8t7jl5El_FdhlYn3mmtn476FfnI5E7anoZNSKLyE-jauNJssBeGUjsSd0z8746mujYcJbKQsMMVVUlxcu4jXXxXXYcC4GasQyvOIp92wY-TPKAOys8NV0-yXH4xTGBzgJ0zzJa5JvyRz2v0x3fijvyXXXXXXSDhZtaDOZ6GOQlYrsUmudsorYUcUT52x0EYavXXXXX92cmgkMUzuTxppV1SpLk2Wk63LQQkCCZLs6_HWlnX2Saf0zgc13BdUehhSBiYHzJJeg1Ys7g68GLG5IuSGvyGe8ebmcN9KUDdD2CwphaeW34iy6dVKGbUpJ3GKVlz; sess-at-main="eSHstcxm5Krki5T1EAcQyk9XXXXXXqMbqcJqDBaA="; csrf=-2012345694'
|
||||
CSRF='csrf: -2081234594'
|
||||
|
||||
STATION=$1
|
||||
|
||||
#Check if parameter is set
|
||||
if [ -z "$STATION" ];
|
||||
then
|
||||
echo "Station Empty - ./alexa-tunein.sh s16430 "
|
||||
exit
|
||||
fi
|
||||
#echo "${STATION}"
|
||||
|
||||
URL='https://pitangui.amazon.com/api/tunein/queue-and-play?deviceSerialNumber='$DEVICENUMBER'&deviceType='$DEVICETYPE'&guideId='$STATION'&contentType=station&callSign=&mediaOwnerCustomerId='$CUSTOMERID
|
||||
curl $URL \
|
||||
-X POST \
|
||||
-H "$CSRF" \
|
||||
-H "$COOKIE" \
|
||||
--compressed
|
||||
|
@ -1,22 +0,0 @@
|
||||
#!/bin/bash
|
||||
DEVICENUMBER='G090LF1234540B82'
|
||||
DEVICETYPE='A3S5123456VAYF'
|
||||
COOKIE='Cookie: x-amzn-dat-gui-client-v=1.24.986.0; aws-target-static-id=14712345678-839972; aws-session-id=168-0412369-4130549; aws-session-id-time=2106194071l; aws-x-main=PgpqvER9Wibauhf4zfSDriNBlBILfMnk; aws-at-main=Atza|IwEBIAFsntUWFc_PZvFde5drDzPNXXXXXXXXXHPqI53aQNl-Fu83eAMUsFJmMtamv_4mLKEh6N82lqq8OHA8SKgh44X2MZwTguXNcUvd0-RVQyayT2lQ86JjoXvJrlMlrZIs7kJLWBryCGJEXXXXXXXXXXFJQpHhnGeC72ljNT_nVObL_wZoYhMFHVMXGiYjFyrb-QcjYY-I3ar-Q-kLAmzZYQIKU-mZ8GChNefKuG_x4ZZ2A06XXXXXXXXXOhX9w94vgmn2y3Qr9Q0rEi8K--UoFuTQ54GArubNsofNLh4U2dov8D7Gs3GoW6Hp2zEwt7cyumpRR_vceAz3aUjskoNKXsgDfpPZrebl-0R4bC6BfIasyoDOX9XXXXXXXXjRihKSxf4gs79p1ExYBmaBOX6glBrsKRqOXfk6Vh87_96uQ; aws-userInfo=%7B%22arn%22%3A%22arn%3Aaws%3Aiam%3A%3A314911114493%3Aroot%22%2C%22alias%22%3A%22%22%2C%22username%22%3A%22MeinUser%2520Name%22%2C%22keybase%22%3A%22dhVv%2Fmb%2BJyCH%2BJA6zwfighlgs5jc0W0mVYXkLBkb77M%5Cu003d%22%2C%22issuer%22%3A%22https%3A%2F%2Fwww.amazon.com%2Fap%2Fsignin%22%7D; __utmv=191231197.PgpqvER9Wibauhf4zfSDXXXXXXXXk; s_dslv=1475471239073; regStatus=registered; aws-target-visitor-id=1475445653051-715340.26_4; aws-target-data=%7B%22support%22%3A%221%22%7D; s_pers=%20s_ev15%3D%255B%255B%2527Typed%252FBookmarked%2527%252C%25212375474893114%2527%255D%255D%7C1632141293114%3B%20s_fid%3D0523A63XXXXXXXXX3C9679E640DA3570%7C1538547024210%3B%20s_dl%3D1%7C1475481765932%3B%20gpv_page%3Dno%2520value%7C1475481765939%3B; session-id=151-3512347-8293901; session-id-time=2106212731l; s_fid=71689F1234D6D238-299FD69294EFC3C1; s_nr=1475492764173-Repeat; aws-ubid-main=151-3388123-1263140; aws-session-token="lprp9YroXXXXXXXXXz5EFfSaPt96R0oSBWL2dR/AGFdlmk4QwRcVPXXXXXXXrmZ5kfHBdNwvSWWMKTnYU0pB5CE2XXXXXXUk6SIuaQYti17ZQ8B3NGwyCKNs7Lil+kz9qonZS5/cwtmrWHCe7SGx/QmPXXXXXXX89WbiV2xwTRkhVw6hTjO+8WUOXXXXXXXXi8MaR196v+Ewflx7dd3ouTVtY+hbJE4XSs="; __utma=194891197.1975555581.1444474071.1475495555.1475555580.5; __utmz=194555597.1475555680.5.2.utmccn=(referral)|utmcsr=console.aws.amazon.com|utmcct=/cloudwatch/home|utmcmd=referral; ubid-main=152-8362434-2710144; session-token="Y2Eoqs81+wIbanI7mPonK9t7gFvH7ZdTG2OxCZB3orqTILNY5ev4cFBWiSPTl2u8nFNXNmwtFP6RxnPBTunkdbHfpos8WYYOX7gEF52wnn5J3SknsvO99+MAT5GeyMR4JRa+ZOX+DcnIt8xtgYY2sSaEZ3JspjrQF+M9PUkuT9D4aYbZGRNa1BkFvoOt8Kettr9xxS/ODPfXEaE6xJr7qyPv0IQ3K6e+FbfGk3AWypY="; x-main=4r7ZrJJV4BT1R2sWn2W4NpiXZm9RSJLD; at-main=Atza|IwEEEEE4EikDns-CTHnGRqXXXcnnaij75AfcF1-XOBvphYTp_ATJHu6f0vDgMI7B1ApWn51cP6bqvG-XXXXeTPD8t7jl5El_FdhlYn3mmtn476FfnI5E7anoZNSKLyE-jauNJssBeGUjsSd0z8746mujYcJbKQsMMVVUlxcu4jXXxXXYcC4GasQyvOIp92wY-TPKAOys8NV0-yXH4xTGBzgJ0zzJa5JvyRz2v0x3fijvyXXXXXXSDhZtaDOZ6GOQlYrsUmudsorYUcUT52x0EYavXXXXX92cmgkMUzuTxppV1SpLk2Wk63LQQkCCZLs6_HWlnX2Saf0zgc13BdUehhSBiYHzJJeg1Ys7g68GLG5IuSGvyGe8ebmcN9KUDdD2CwphaeW34iy6dVKGbUpJ3GKVlz; sess-at-main="eSHstcxm5Krki5T1EAcQyk9XXXXXXqMbqcJqDBaA="; csrf=-2012345694'
|
||||
CSRF='csrf: -2081234594'
|
||||
|
||||
VOLUME=$1
|
||||
|
||||
#check if parameter is set
|
||||
if [ -z "$VOLUME" ];
|
||||
then
|
||||
echo "use ./alexa-volume.sh 40 # Use something between 0-100"
|
||||
exit
|
||||
fi
|
||||
|
||||
VOLUMECMD='{"type":"VolumeLevelCommand","volumeLevel":'$VOLUME'}'
|
||||
URL='https://pitangui.amazon.com/api/np/command?deviceSerialNumber='$DEVICENUMBER'&deviceType='$DEVICETYPE
|
||||
curl $URL \
|
||||
-H "$COOKIE" \
|
||||
-H "$CSRF" \
|
||||
--data "${VOLUMECMD}" \
|
||||
--compressed
|
765
alexa_remote_control.sh
Normal file
765
alexa_remote_control.sh
Normal file
@ -0,0 +1,765 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Amazon Alexa Remote Control
|
||||
# alex(at)loetzimmer.de
|
||||
#
|
||||
# 2017-10-10: v0.1 initial release
|
||||
# 2017-10-11: v0.2 TuneIn Station Search
|
||||
# 2017-10-11: v0.2a commands on special device "ALL" are executed on all ECHO+WHA
|
||||
# 2017-10-16: v0.3 added playback of library tracks
|
||||
# 2017-10-24: v0.4 added playback information
|
||||
# 2017-11-21: v0.5 added Prime station and playlist
|
||||
# 2017-11-22: v0.6 added Prime historical queue and replaced getopts
|
||||
# 2017-11-25: v0.6a cURL is now configurable
|
||||
# 2017-11-25: v0.7 added multiroom create/delete, playback of library playlist
|
||||
# 2017-11-30: v0.7a added US config, fixed device names containing spaces
|
||||
# 2017-12-07: v0.7b added Bluetooth connect/disconnect
|
||||
# 2017-12-18: v0.7c fixed US version
|
||||
# 2017-12-19: v0.7d fixed AWK csrf extraction on some systems
|
||||
# 2017-12-20: v0.7e moved get_devlist after check_status
|
||||
# 2018-01-08: v0.7f added echo-show to ALL group, TuneIn station can now be up to 6 digits
|
||||
# 2018-01-08: v0.8 added bluetooth list function
|
||||
# 2018-01-10: v0.8a abort when login was unsuccessful
|
||||
# 2018-01-25: v0.8b added echo-spot to ALL group
|
||||
# 2018-01-28: v0.8c added configurable browser string
|
||||
#
|
||||
###
|
||||
#
|
||||
# (no BASHisms were used, should run with any shell)
|
||||
# - requires cURL for web communication
|
||||
# - (GNU) sed and awk for extraction
|
||||
# - jq as command line JSON parser (optional for the fancy bits)
|
||||
#
|
||||
##########################################
|
||||
|
||||
EMAIL='amazon_account@email.address'
|
||||
PASSWORD='Very_Secret_Amazon_Account_Password'
|
||||
|
||||
LANGUAGE="de,en"
|
||||
#LANGUAGE="en-us"
|
||||
|
||||
AMAZON='amazon.de'
|
||||
#AMAZON='amazon.com'
|
||||
|
||||
ALEXA='layla.amazon.de'
|
||||
#ALEXA='pitangui.amazon.com'
|
||||
|
||||
# cURL binary
|
||||
CURL='/usr/bin/curl'
|
||||
|
||||
# cURL options
|
||||
# -k : if your cURL cannot verify CA certificates, you'll have to trust any
|
||||
# --compressed : if your cURL was compiled with libz you may use compression
|
||||
OPTS='--compressed'
|
||||
#OPTS='-k --compressed'
|
||||
|
||||
# browser identity
|
||||
BROWSER='Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0'
|
||||
|
||||
###########################################
|
||||
# nothing to configure below here
|
||||
#
|
||||
TMP="/tmp"
|
||||
COOKIE="${TMP}/.alexa.cookie"
|
||||
DEVLIST="${TMP}/.alexa.devicelist.json"
|
||||
|
||||
GUIVERSION=0
|
||||
|
||||
LIST=""
|
||||
LOGOFF=""
|
||||
COMMAND=""
|
||||
STATIONID=""
|
||||
QUEUE=""
|
||||
SONG=""
|
||||
TYPE=""
|
||||
ASIN=""
|
||||
SEEDID=""
|
||||
HIST=""
|
||||
LEMUR=""
|
||||
CHILD=""
|
||||
PLIST=""
|
||||
BLUETOOTH=""
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "$0 [-d <device>|ALL] -e <pause|play|next|prev|fwd|rwd|shuffle|vol:<0-100>> | -b [list|<\"AA:BB:CC:DD:EE:FF\">] | -q | -r <\"station name\"|stationid> | -s <trackID> | -t <ASIN> |"
|
||||
echo " -u <seedID> | -v <queueID> | -w <playlistId> | -i | -p | -P | -S | -a | -m <multiroom_device> [device_1 .. device_X] | -l | -h"
|
||||
echo " -e : run command"
|
||||
echo " -b : connect/disconnect/list bluetooth device"
|
||||
echo " -q : query queue"
|
||||
echo " -r : play tunein radio"
|
||||
echo " -s : play library track"
|
||||
echo " -t : play Prime playlist"
|
||||
echo " -u : play Prime station"
|
||||
echo " -v : play Prime historical queue"
|
||||
echo " -w : play library playlist"
|
||||
echo " -i : list imported library tracks"
|
||||
echo " -p : list purchased library tracks"
|
||||
echo " -P : list Prime playlists"
|
||||
echo " -S : list Prime stations"
|
||||
echo " -a : list available devices"
|
||||
echo " -m : delete multiroom and/or create new multiroom containing devices"
|
||||
echo " -l : logoff"
|
||||
echo " -h : help"
|
||||
}
|
||||
|
||||
while [ "$#" -gt 0 ] ; do
|
||||
case "$1" in
|
||||
-d)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
DEVICE=$2
|
||||
shift
|
||||
;;
|
||||
-e)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
COMMAND=$2
|
||||
shift
|
||||
;;
|
||||
-b)
|
||||
if [ "${2#-}" = "${2}" -a -n "$2" ] ; then
|
||||
BLUETOOTH=$2
|
||||
shift
|
||||
else
|
||||
BLUETOOTH="null"
|
||||
fi
|
||||
;;
|
||||
-m)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
LEMUR=$2
|
||||
shift
|
||||
while [ "${2#-}" = "${2}" -a -n "$2" ] ; do
|
||||
CHILD="${CHILD} ${2}"
|
||||
shift
|
||||
done
|
||||
;;
|
||||
-r)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
STATIONID=$2
|
||||
shift
|
||||
# stationIDs are "s1234" or "s12345"
|
||||
if [ -n "${STATIONID##s[0-9][0-9][0-9][0-9]}" -a -n "${STATIONID##s[0-9][0-9][0-9][0-9][0-9]}" -a -n "${STATIONID##s[0-9][0-9][0-9][0-9][0-9][0-9]}" ] ; then
|
||||
# search for station name
|
||||
STATIONID=$(${CURL} ${OPTS} -s --data-urlencode "query=${STATIONID}" -G "https://api.tunein.com/profiles?fullTextSearch=true" | jq -r '.Items[] | select(.ContainerType == "Stations") | .Children[] | select( .Index==1 ) | .GuideId')
|
||||
if [ -z "$STATIONID" ] ; then
|
||||
echo "ERROR: no Station \"$2\" found on TuneIn"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
-s)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
SONG=$2
|
||||
shift
|
||||
;;
|
||||
-t)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
ASIN=$2
|
||||
shift
|
||||
;;
|
||||
-u)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
SEEDID=$2
|
||||
shift
|
||||
;;
|
||||
-v)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
HIST=$2
|
||||
shift
|
||||
;;
|
||||
-w)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
PLIST=$2
|
||||
shift
|
||||
;;
|
||||
-l)
|
||||
LOGOFF="true"
|
||||
;;
|
||||
-a)
|
||||
LIST="true"
|
||||
;;
|
||||
-i)
|
||||
TYPE="IMPORTED"
|
||||
;;
|
||||
-p)
|
||||
TYPE="PURCHASES"
|
||||
;;
|
||||
-P)
|
||||
PRIME="prime-playlist-browse-nodes"
|
||||
;;
|
||||
-S)
|
||||
PRIME="prime-sections"
|
||||
;;
|
||||
-q)
|
||||
QUEUE="true"
|
||||
;;
|
||||
-h|-\?|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: unknown option ${1}"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
case "$COMMAND" in
|
||||
pause)
|
||||
COMMAND='{"type":"PauseCommand"}'
|
||||
;;
|
||||
play)
|
||||
COMMAND='{"type":"PlayCommand"}'
|
||||
;;
|
||||
next)
|
||||
COMMAND='{"type":"NextCommand"}'
|
||||
;;
|
||||
prev)
|
||||
COMMAND='{"type":"PreviousCommand"}'
|
||||
;;
|
||||
fwd)
|
||||
COMMAND='{"type":"ForwardCommand"}'
|
||||
;;
|
||||
rwd)
|
||||
COMMAND='{"type":"RewindCommand"}'
|
||||
;;
|
||||
shuffle)
|
||||
COMMAND='{"type":"ShuffleCommand","shuffle":"true"}'
|
||||
;;
|
||||
vol:*)
|
||||
VOL=${COMMAND##*:}
|
||||
# volume as integer!
|
||||
if [ $VOL -le 100 -a $VOL -ge 0 ] ; then
|
||||
COMMAND='{"type":"VolumeLevelCommand","volumeLevel":'${VOL}'}'
|
||||
else
|
||||
echo "ERROR: volume should be an integer between 0 and 100"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
"")
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: unknown command \"${COMMAND}\"!"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
#
|
||||
# Amazon Login
|
||||
#
|
||||
log_in()
|
||||
{
|
||||
################################################################
|
||||
#
|
||||
# following headers are required:
|
||||
# Accept-Language (possibly for determining login region)
|
||||
# User-Agent (cURL wouldn't store cookies without)
|
||||
#
|
||||
################################################################
|
||||
|
||||
rm -f ${DEVLIST}
|
||||
rm -f ${COOKIE}
|
||||
rm -f ${TMP}/.alexa.*.list
|
||||
|
||||
#
|
||||
# get first cookie and write redirection target into referer
|
||||
#
|
||||
${CURL} ${OPTS} -s -D "${TMP}/.alexa.header" -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "Accept-Language: ${LANGUAGE}" -H "DNT: 1" -H "Connection: keep-alive" -H "Upgrade-Insecure-Requests: 1" -L\
|
||||
https://alexa.${AMAZON} | grep "hidden" | sed 's/hidden/\n/g' | grep "value=\"" | sed -r 's/^.*name="([^"]+)".*value="([^"]+)".*/\1=\2\&/g' > "${TMP}/.alexa.postdata"
|
||||
|
||||
#
|
||||
# login empty to generate sessiion
|
||||
#
|
||||
${CURL} ${OPTS} -s -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "Accept-Language: ${LANGUAGE}" -H "DNT: 1" -H "Connection: keep-alive" -H "Upgrade-Insecure-Requests: 1" -L\
|
||||
-H "$(grep 'Location: ' ${TMP}/.alexa.header | sed 's/Location: /Referer: /')" -d "@${TMP}/.alexa.postdata" https://www.${AMAZON}/ap/signin | grep "hidden" | sed 's/hidden/\n/g' | grep "value=\"" | sed -r 's/^.*name="([^"]+)".*value="([^"]+)".*/\1=\2\&/g' > "${TMP}/.alexa.postdata2"
|
||||
|
||||
#
|
||||
# login with filled out form
|
||||
# !!! referer now contains session in URL
|
||||
#
|
||||
${CURL} ${OPTS} -s -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "Accept-Language: ${LANGUAGE}" -H "DNT: 1" -H "Connection: keep-alive" -H "Upgrade-Insecure-Requests: 1" -L\
|
||||
-H "Referer: https://www.${AMAZON}/ap/signin/$(awk "\$0 ~/.${AMAZON}.*session-id[ \\s\\t]+/ {print \$7}" ${COOKIE})" --data-urlencode "email=${EMAIL}" --data-urlencode "password=${PASSWORD}" -d "@${TMP}/.alexa.postdata2" https://www.${AMAZON}/ap/signin > /dev/null
|
||||
|
||||
#
|
||||
# get CSRF
|
||||
#
|
||||
${CURL} ${OPTS} -s -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
https://${ALEXA}/api/language > /dev/null
|
||||
|
||||
rm -f "${TMP}/.alexa.header"
|
||||
rm -f "${TMP}/.alexa.postdata"
|
||||
rm -f "${TMP}/.alexa.postdata2"
|
||||
}
|
||||
|
||||
#
|
||||
# get JSON device list
|
||||
#
|
||||
get_devlist()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})"\
|
||||
"https://${ALEXA}/api/devices-v2/device?cached=false" > ${DEVLIST}
|
||||
}
|
||||
|
||||
check_status()
|
||||
{
|
||||
#
|
||||
# bootstrap with GUI-Version writes GUI version to cookie
|
||||
# returns among other the current authentication state
|
||||
#
|
||||
AUTHSTATUS=$(${CURL} ${OPTS} -s -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L https://${ALEXA}/api/bootstrap?version=${GUIVERSION} | sed -r 's/^.*"authenticated":([^,]+),.*$/\1/g')
|
||||
|
||||
if [ "$AUTHSTATUS" = "true" ] ; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#
|
||||
# set device specific variables from JSON device list
|
||||
#
|
||||
set_var()
|
||||
{
|
||||
DEVICE=$(echo ${DEVICE} | sed -r 's/%20/ /g')
|
||||
|
||||
if [ -z "${DEVICE}" ] ; then
|
||||
# if no device was supplied, use the first Echo(dot) in device list
|
||||
echo "setting default device to:"
|
||||
DEVICE=$(jq -r '[ .devices[] | select(.deviceFamily == "ECHO" or .deviceFamily == "KNIGHT" or .deviceFamily == "ROOK" ) | .accountName] | .[0]' ${DEVLIST})
|
||||
echo ${DEVICE}
|
||||
fi
|
||||
|
||||
DEVICETYPE=$(jq --arg device "${DEVICE}" -r '.devices[] | select(.accountName == $device) | .deviceType' ${DEVLIST})
|
||||
DEVICESERIALNUMBER=$(jq --arg device "${DEVICE}" -r '.devices[] | select(.accountName == $device) | .serialNumber' ${DEVLIST})
|
||||
MEDIAOWNERCUSTOMERID=$(jq --arg device "${DEVICE}" -r '.devices[] | select(.accountName == $device) | .deviceOwnerCustomerId' ${DEVLIST})
|
||||
|
||||
if [ -z "${DEVICESERIALNUMBER}" ] ; then
|
||||
echo "ERROR: unkown device dev:${DEVICE}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# list available devices from JSON device list
|
||||
#
|
||||
list_devices()
|
||||
{
|
||||
jq -r '.devices[].accountName' ${DEVLIST}
|
||||
}
|
||||
|
||||
#
|
||||
# execute command
|
||||
#
|
||||
run_cmd()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d ${COMMAND}\
|
||||
"https://${ALEXA}/api/np/command?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}"
|
||||
}
|
||||
|
||||
#
|
||||
# play TuneIn radio station
|
||||
#
|
||||
play_radio()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST\
|
||||
"https://${ALEXA}/api/tunein/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&guideId=${STATIONID}&contentType=station&callSign=&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}"
|
||||
}
|
||||
|
||||
#
|
||||
# play library track
|
||||
#
|
||||
play_song()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "{\"trackId\":\"${SONG}\",\"playQueuePrime\":true}"\
|
||||
"https://${ALEXA}/api/cloudplayer/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}&shuffle=false"
|
||||
}
|
||||
|
||||
#
|
||||
# play library playlist
|
||||
#
|
||||
play_playlist()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "{\"playlistId\":\"${PLIST}\",\"playQueuePrime\":true}"\
|
||||
"https://${ALEXA}/api/cloudplayer/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}&shuffle=false"
|
||||
}
|
||||
|
||||
#
|
||||
# play PRIME playlist
|
||||
#
|
||||
play_prime_playlist()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "{\"asin\":\"${ASIN}\"}"\
|
||||
"https://${ALEXA}/api/prime/prime-playlist-queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}"
|
||||
}
|
||||
|
||||
#
|
||||
# play PRIME station
|
||||
#
|
||||
play_prime_station()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "{\"seed\":\"{\\\"type\\\":\\\"KEY\\\",\\\"seedId\\\":\\\"${SEEDID}\\\"}\",\"stationName\":\"none\",\"seedType\":\"KEY\"}"\
|
||||
"https://${ALEXA}/api/gotham/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}"
|
||||
}
|
||||
|
||||
#
|
||||
# play PRIME historical queue
|
||||
#
|
||||
play_prime_hist_queue()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "{\"deviceType\":\"${DEVICETYPE}\",\"deviceSerialNumber\":\"${DEVICESERIALNUMBER}\",\"mediaOwnerCustomerId\":\"${MEDIAOWNERCUSTOMERID}\",\"queueId\":\"${HIST}\",\"service\":null,\"trackSource\":\"TRACK\"}"\
|
||||
"https://${ALEXA}/api/media/play-historical-queue"
|
||||
}
|
||||
|
||||
#
|
||||
# show library tracks
|
||||
#
|
||||
show_library()
|
||||
{
|
||||
OFFSET="";
|
||||
SIZE=50;
|
||||
TOTAL=0;
|
||||
FILE=${TMP}/.alexa.${TYPE}.list
|
||||
|
||||
if [ ! -f ${FILE} ] ; then
|
||||
echo -n '{"playlist":{"entryList":[' > ${FILE}
|
||||
|
||||
while [ 50 -le ${SIZE} ] ; do
|
||||
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X GET \
|
||||
"https://${ALEXA}/api/cloudplayer/playlists/${TYPE}-V0-OBJECTID?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&size=${SIZE}&offset=${OFFSET}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}" > ${FILE}.tmp
|
||||
|
||||
OFFSET=$(jq -r '.nextResultsToken' ${FILE}.tmp)
|
||||
SIZE=$(jq -r '.playlist | .trackCount' ${FILE}.tmp)
|
||||
jq -r -c '.playlist | .entryList' ${FILE}.tmp >> ${FILE}
|
||||
echo "," >> ${FILE}
|
||||
TOTAL=$((TOTAL+SIZE))
|
||||
done
|
||||
echo "[]],\"trackCount\":\"${TOTAL}\"}}" >> ${FILE}
|
||||
rm -f ${FILE}.tmp
|
||||
fi
|
||||
jq -r '.playlist.trackCount' ${FILE}
|
||||
jq '.playlist.entryList[] | .[]' ${FILE}
|
||||
}
|
||||
|
||||
#
|
||||
# show Prime stations and playlists
|
||||
#
|
||||
show_prime()
|
||||
{
|
||||
FILE=${TMP}/.alexa.${PRIME}.list
|
||||
|
||||
if [ ! -f ${FILE} ] ; then
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X GET \
|
||||
"https://${ALEXA}/api/prime/{$PRIME}?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}" > ${FILE}
|
||||
|
||||
if [ "$PRIME" = "prime-playlist-browse-nodes" ] ; then
|
||||
for I in $(jq -r '.primePlaylistBrowseNodeList[].subNodes[].nodeId' ${FILE} 2>/dev/null) ; do
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X GET \
|
||||
"https://${ALEXA}/api/prime/prime-playlists-by-browse-node?browseNodeId=${I}&deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}" >> ${FILE}
|
||||
done
|
||||
fi
|
||||
fi
|
||||
jq '.' ${FILE}
|
||||
}
|
||||
|
||||
#
|
||||
# current queue
|
||||
#
|
||||
show_queue()
|
||||
{
|
||||
PARENT=""
|
||||
PARENTID=$(jq --arg device "${DEVICE}" -r '.devices[] | select(.accountName == $device) | .parentClusters[0]' ${DEVLIST})
|
||||
if [ "$PARENTID" != "null" ] ; then
|
||||
PARENTDEVICE=$(jq --arg serial ${PARENTID} -r '.devices[] | select(.serialNumber == $serial) | .deviceType' ${DEVLIST})
|
||||
PARENT="&lemurId=${PARENTID}&lemurDeviceType=${PARENTDEVICE}"
|
||||
fi
|
||||
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X GET \
|
||||
"https://${ALEXA}/api/np/player?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}${PARENT}" | jq '.'
|
||||
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X GET \
|
||||
"https://${ALEXA}/api/media/state?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}" | jq '.'
|
||||
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X GET \
|
||||
"https://${ALEXA}/api/np/queue?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}" | jq '.'
|
||||
}
|
||||
|
||||
#
|
||||
# deletes a multiroom device
|
||||
#
|
||||
delete_multiroom()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X DELETE \
|
||||
"https://${ALEXA}/api/lemur/tail/${DEVICESERIALNUMBER}"
|
||||
}
|
||||
|
||||
#
|
||||
# creates a multiroom device
|
||||
#
|
||||
create_multiroom()
|
||||
{
|
||||
JSON="{\"id\":null,\"name\":\"${LEMUR}\",\"members\":["
|
||||
for DEVICE in $CHILD ; do
|
||||
set_var
|
||||
JSON="${JSON}{\"dsn\":\"${DEVICESERIALNUMBER}\",\"deviceType\":\"${DEVICETYPE}\"},"
|
||||
done
|
||||
JSON="${JSON%,}]}"
|
||||
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "${JSON}" \
|
||||
"https://${ALEXA}/api/lemur/tail"
|
||||
}
|
||||
|
||||
#
|
||||
# list bluetooth devices
|
||||
#
|
||||
list_bluetooth()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X GET \
|
||||
"https://${ALEXA}/api/bluetooth?cached=false" | jq --arg serial "${DEVICESERIALNUMBER}" -r '.bluetoothStates[] | select(.deviceSerialNumber == $serial) | "\(.pairedDeviceList[]?.address) \(.pairedDeviceList[]?.friendlyName)"'
|
||||
}
|
||||
|
||||
#
|
||||
# connect bluetooth device
|
||||
#
|
||||
connect_bluetooth()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "{\"bluetoothDeviceAddress\":\"${BLUETOOTH}\"}"\
|
||||
"https://${ALEXA}/api/bluetooth/pair-sink/${DEVICETYPE}/${DEVICESERIALNUMBER}"
|
||||
}
|
||||
|
||||
#
|
||||
# disconnect bluetooth device
|
||||
#
|
||||
disconnect_bluetooth()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST \
|
||||
"https://${ALEXA}/api/bluetooth/disconnect-sink/${DEVICETYPE}/${DEVICESERIALNUMBER}"
|
||||
}
|
||||
|
||||
#
|
||||
# logout
|
||||
#
|
||||
log_off()
|
||||
{
|
||||
${CURL} ${OPTS} -s -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
https://${ALEXA}/logout > /dev/null
|
||||
|
||||
rm -f ${DEVLIST}
|
||||
rm -f ${COOKIE}
|
||||
rm -f ${TMP}/.alexa.*.list
|
||||
}
|
||||
|
||||
if [ -z "$BLUETOOTH" -a -z "$LEMUR" -a -z "$PLIST" -a -z "$HIST" -a -z "$SEEDID" -a -z "$ASIN" -a -z "$PRIME" -a -z "$TYPE" -a -z "$QUEUE" -a -z "$LIST" -a -z "$COMMAND" -a -z "$STATIONID" -a -z "$SONG" -a -n "$LOGOFF" ] ; then
|
||||
echo "only logout option present, logging off ..."
|
||||
log_off
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -f ${COOKIE} ] ; then
|
||||
echo "cookie do not exist. logging in ..."
|
||||
log_in
|
||||
fi
|
||||
|
||||
check_status
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo "cookie expired, logging in again ..."
|
||||
log_in
|
||||
check_status
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo "log in failed, aborting"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f ${DEVLIST} ] ; then
|
||||
echo "device list do not exist. downloading ..."
|
||||
get_devlist
|
||||
if [ ! -f ${DEVLIST} ] ; then
|
||||
echo "failed to download device list, aborting"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$COMMAND" -o -n "$QUEUE" ] ; then
|
||||
if [ "${DEVICE}" = "ALL" ] ; then
|
||||
for DEVICE in $(jq -r '.devices[] | select( .deviceFamily == "ECHO" or .deviceFamily == "KNIGHT" or .deviceFamily == "ROOK" or .deviceFamily == "WHA") | .accountName' ${DEVLIST} | sed -r 's/ /%20/g') ; do
|
||||
set_var
|
||||
if [ -n "$COMMAND" ] ; then
|
||||
echo "sending cmd:${COMMAND} to dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}"
|
||||
run_cmd
|
||||
else
|
||||
echo "queue info for dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}"
|
||||
show_queue
|
||||
fi
|
||||
done
|
||||
else
|
||||
set_var
|
||||
if [ -n "$COMMAND" ] ; then
|
||||
echo "sending cmd:${COMMAND} to dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}"
|
||||
run_cmd
|
||||
else
|
||||
echo "queue info for dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}"
|
||||
show_queue
|
||||
fi
|
||||
fi
|
||||
elif [ -n "$LEMUR" ] ; then
|
||||
DEVICESERIALNUMBER=$(jq --arg device "${LEMUR}" -r '.devices[] | select(.accountName == $device and .deviceFamily == "WHA") | .serialNumber' ${DEVLIST})
|
||||
if [ -n "$DEVICESERIALNUMBER" ] ; then
|
||||
delete_multiroom
|
||||
else
|
||||
if [ -z "$CHILD" ] ; then
|
||||
echo "ERROR: ${LEMUR} is no multiroom device. Cannot delete ${LEMUR}".
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [ -z "$CHILD" ] ; then
|
||||
echo "Deleted multi room dev:${LEMUR} serial:${DEVICESERIALNUMBER}"
|
||||
else
|
||||
echo "Creating multi room dev:${LEMUR} member_dev(s):${CHILD}"
|
||||
create_multiroom
|
||||
fi
|
||||
rm -f ${DEVLIST}
|
||||
get_devlist
|
||||
elif [ -n "$BLUETOOTH" ] ; then
|
||||
if [ "$BLUETOOTH" = "list" -o "$BLUETOOTH" = "List" -o "$BLUETOOTH" = "LIST" ] ; then
|
||||
if [ "${DEVICE}" = "ALL" ] ; then
|
||||
for DEVICE in $(jq -r '.devices[] | select( .deviceFamily == "ECHO" or .deviceFamily == "KNIGHT" or .deviceFamily == "ROOK" or .deviceFamily == "WHA") | .accountName' ${DEVLIST} | sed -r 's/ /%20/g') ; do
|
||||
set_var
|
||||
echo "bluetooth devices for dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}:"
|
||||
list_bluetooth
|
||||
done
|
||||
else
|
||||
set_var
|
||||
echo "bluetooth devices for dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}:"
|
||||
list_bluetooth
|
||||
fi
|
||||
elif [ "$BLUETOOTH" = "null" ] ; then
|
||||
set_var
|
||||
echo "disconnecting dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} from bluetooth"
|
||||
disconnect_bluetooth
|
||||
else
|
||||
set_var
|
||||
echo "connecting dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} to bluetooth device:${BLUETOOTH}"
|
||||
connect_bluetooth
|
||||
fi
|
||||
elif [ -n "$STATIONID" ] ; then
|
||||
set_var
|
||||
echo "playing stationID:${STATIONID} on dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} mediaownerid:${MEDIAOWNERCUSTOMERID}"
|
||||
play_radio
|
||||
elif [ -n "$SONG" ] ; then
|
||||
set_var
|
||||
echo "playing library track:${SONG} on dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} mediaownerid:${MEDIAOWNERCUSTOMERID}"
|
||||
play_song
|
||||
elif [ -n "$PLIST" ] ; then
|
||||
set_var
|
||||
echo "playing library playlist:${PLIST} on dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} mediaownerid:${MEDIAOWNERCUSTOMERID}"
|
||||
play_playlist
|
||||
elif [ -n "$LIST" ] ; then
|
||||
echo "the following devices exist in your account:"
|
||||
list_devices
|
||||
elif [ -n "$TYPE" ] ; then
|
||||
set_var
|
||||
echo -n "the following songs exist in your ${TYPE} library: "
|
||||
show_library
|
||||
elif [ -n "$PRIME" ] ; then
|
||||
set_var
|
||||
echo "the following songs exist in your PRIME ${PRIME}:"
|
||||
show_prime
|
||||
elif [ -n "$ASIN" ] ; then
|
||||
set_var
|
||||
echo "playing PRIME playlist ${ASIN}"
|
||||
play_prime_playlist
|
||||
elif [ -n "$SEEDID" ] ; then
|
||||
set_var
|
||||
echo "playing PRIME station ${SEEDID}"
|
||||
play_prime_station
|
||||
elif [ -n "$HIST" ] ; then
|
||||
set_var
|
||||
echo "playing PRIME historical queue ${HIST}"
|
||||
play_prime_hist_queue
|
||||
else
|
||||
echo "no alexa command received"
|
||||
fi
|
||||
|
||||
if [ -n "$LOGOFF" ] ; then
|
||||
echo "logout option present, logging off ..."
|
||||
log_off
|
||||
fi
|
695
alexa_remote_control_plain.sh
Normal file
695
alexa_remote_control_plain.sh
Normal file
@ -0,0 +1,695 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Amazon Alexa Remote Control (PLAIN shell)
|
||||
# alex(at)loetzimmer.de
|
||||
#
|
||||
# 2018-01-10: v0.8c (for updates see http://blog.loetzimmer.de/2017/10/amazon-alexa-hort-auf-die-shell-echo.html)
|
||||
#
|
||||
###
|
||||
#
|
||||
# (no BASHisms were used, should run with any shell)
|
||||
# - requires cURL for web communication
|
||||
# - (GNU) sed and awk for extraction
|
||||
#
|
||||
##########################################
|
||||
|
||||
EMAIL='amazon_account@email.address'
|
||||
PASSWORD='Very_Secret_Amazon_Account_Password'
|
||||
|
||||
|
||||
LANGUAGE="de,en"
|
||||
#LANGUAGE="en-us"
|
||||
|
||||
AMAZON='amazon.de'
|
||||
#AMAZON='amazon.com'
|
||||
|
||||
ALEXA='layla.amazon.de'
|
||||
#ALEXA='pitangui.amazon.com'
|
||||
|
||||
# cURL binary
|
||||
CURL='/usr/bin/curl'
|
||||
|
||||
# cURL options
|
||||
# -k : if your cURL cannot verify CA certificates, you'll have to trust any
|
||||
# --compressed : if your cURL was compiled with libz you may use compression
|
||||
OPTS='--compressed'
|
||||
#OPTS='-k --compressed'
|
||||
|
||||
# browser identity
|
||||
BROWSER='Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0'
|
||||
|
||||
###########################################
|
||||
# nothing to configure below here
|
||||
#
|
||||
TMP="/tmp"
|
||||
COOKIE="${TMP}/.alexa.cookie"
|
||||
DEVLIST="${TMP}/.alexa.devicelist.json"
|
||||
DEVTXT="${TMP}/.alexa.devicelist.txt"
|
||||
|
||||
GUIVERSION=0
|
||||
|
||||
LIST=""
|
||||
LOGOFF=""
|
||||
COMMAND=""
|
||||
STATIONID=""
|
||||
QUEUE=""
|
||||
SONG=""
|
||||
ASIN=""
|
||||
SEEDID=""
|
||||
HIST=""
|
||||
LEMUR=""
|
||||
CHILD=""
|
||||
PLIST=""
|
||||
BLUETOOTH=""
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "$0 [-d <device>] -e <pause|play|next|prev|fwd|rwd|shuffle|vol:<0-100>> | -b [list|<\"AA:BB:CC:DD:EE:FF\">] | -q | -r <stationid> | -s <trackID> | -t <ASIN> |"
|
||||
echo " -u <seedID> | -v <queueID> | -w <playlistId> | -a | -m <multiroom_device> [device_1 .. device_X] | -l | -h"
|
||||
echo " -e : run command"
|
||||
echo " -q : query queue"
|
||||
echo " -b : connect/disconnect/list bluetooth device"
|
||||
echo " -r : play tunein radio"
|
||||
echo " -s : play library track"
|
||||
echo " -t : play Prime playlist"
|
||||
echo " -u : play Prime station"
|
||||
echo " -v : play Prime historical queue"
|
||||
echo " -w : play library playlist"
|
||||
echo " -a : list available devices"
|
||||
echo " -m : delete multiroom and/or create new multiroom containing devices"
|
||||
echo " -l : logoff"
|
||||
echo " -h : help"
|
||||
}
|
||||
|
||||
while [ "$#" -gt 0 ] ; do
|
||||
case "$1" in
|
||||
-d)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
DEVICE=$2
|
||||
shift
|
||||
;;
|
||||
-e)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
COMMAND=$2
|
||||
shift
|
||||
;;
|
||||
-b)
|
||||
if [ "${2#-}" = "${2}" -a -n "$2" ] ; then
|
||||
BLUETOOTH=$2
|
||||
shift
|
||||
else
|
||||
BLUETOOTH="null"
|
||||
fi
|
||||
;;
|
||||
-m)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
LEMUR=$2
|
||||
shift
|
||||
while [ "${2#-}" = "${2}" -a -n "$2" ] ; do
|
||||
CHILD="${CHILD} ${2}"
|
||||
shift
|
||||
done
|
||||
;;
|
||||
-r)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
STATIONID=$2
|
||||
shift
|
||||
;;
|
||||
-s)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
SONG=$2
|
||||
shift
|
||||
;;
|
||||
-t)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
ASIN=$2
|
||||
shift
|
||||
;;
|
||||
-u)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
SEEDID=$2
|
||||
shift
|
||||
;;
|
||||
-v)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
HIST=$2
|
||||
shift
|
||||
;;
|
||||
-w)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
PLIST=$2
|
||||
shift
|
||||
;;
|
||||
-d)
|
||||
if [ "${2#-}" != "${2}" -o -z "$2" ] ; then
|
||||
echo "ERROR: missing argument for ${1}"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
DEVICE=$2
|
||||
shift
|
||||
;;
|
||||
-l)
|
||||
LOGOFF="true"
|
||||
;;
|
||||
-a)
|
||||
LIST="true"
|
||||
;;
|
||||
-q)
|
||||
QUEUE="true"
|
||||
;;
|
||||
-h|-\?|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: unknown option ${1}"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
case "$COMMAND" in
|
||||
pause)
|
||||
COMMAND='{"type":"PauseCommand"}'
|
||||
;;
|
||||
play)
|
||||
COMMAND='{"type":"PlayCommand"}'
|
||||
;;
|
||||
next)
|
||||
COMMAND='{"type":"NextCommand"}'
|
||||
;;
|
||||
prev)
|
||||
COMMAND='{"type":"PreviousCommand"}'
|
||||
;;
|
||||
fwd)
|
||||
COMMAND='{"type":"ForwardCommand"}'
|
||||
;;
|
||||
rwd)
|
||||
COMMAND='{"type":"RewindCommand"}'
|
||||
;;
|
||||
shuffle)
|
||||
COMMAND='{"type":"ShuffleCommand","shuffle":"true"}'
|
||||
;;
|
||||
vol:*)
|
||||
VOL=${COMMAND##*:}
|
||||
# volume as integer!
|
||||
if [ $VOL -le 100 -a $VOL -ge 0 ] ; then
|
||||
COMMAND='{"type":"VolumeLevelCommand","volumeLevel":'${VOL}'}'
|
||||
else
|
||||
echo "ERROR: volume should be an integer between 0 and 100"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
"")
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: unknown command \"${COMMAND}\"!"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
#
|
||||
# Amazon Login
|
||||
#
|
||||
log_in()
|
||||
{
|
||||
################################################################
|
||||
#
|
||||
# following headers are required:
|
||||
# Accept-Language (possibly for determining login region)
|
||||
# User-Agent (CURL wouldn't store cookies without)
|
||||
#
|
||||
################################################################
|
||||
|
||||
rm -f ${DEVLIST}
|
||||
rm -f ${DEVTXT}
|
||||
rm -f ${COOKIE}
|
||||
|
||||
#
|
||||
# get first cookie and write redirection target into referer
|
||||
#
|
||||
${CURL} ${OPTS} -s -D "${TMP}/.alexa.header" -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "Accept-Language: ${LANGUAGE}" -H "DNT: 1" -H "Connection: keep-alive" -H "Upgrade-Insecure-Requests: 1" -L\
|
||||
https://alexa.${AMAZON} | grep "hidden" | sed 's/hidden/\n/g' | grep "value=\"" | sed -r 's/^.*name="([^"]+)".*value="([^"]+)".*/\1=\2\&/g' > "${TMP}/.alexa.postdata"
|
||||
|
||||
#
|
||||
# login empty to generate sessiion
|
||||
#
|
||||
${CURL} ${OPTS} -s -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "Accept-Language: ${LANGUAGE}" -H "DNT: 1" -H "Connection: keep-alive" -H "Upgrade-Insecure-Requests: 1" -L\
|
||||
-H "$(grep 'Location: ' ${TMP}/.alexa.header | sed 's/Location: /Referer: /')" -d "@${TMP}/.alexa.postdata" https://www.${AMAZON}/ap/signin | grep "hidden" | sed 's/hidden/\n/g' | grep "value=\"" | sed -r 's/^.*name="([^"]+)".*value="([^"]+)".*/\1=\2\&/g' > "${TMP}/.alexa.postdata2"
|
||||
|
||||
#
|
||||
# login with filled out form
|
||||
# !!! referer now contains session in URL
|
||||
#
|
||||
${CURL} ${OPTS} -s -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "Accept-Language: ${LANGUAGE}" -H "DNT: 1" -H "Connection: keep-alive" -H "Upgrade-Insecure-Requests: 1" -L\
|
||||
-H "Referer: https://www.${AMAZON}/ap/signin/$(awk "\$0 ~/.${AMAZON}.*session-id[ \\s\\t]+/ {print \$7}" ${COOKIE})" --data-urlencode "email=${EMAIL}" --data-urlencode "password=${PASSWORD}" -d "@${TMP}/.alexa.postdata2" https://www.${AMAZON}/ap/signin > /dev/null
|
||||
|
||||
#
|
||||
# get CSRF
|
||||
#
|
||||
${CURL} ${OPTS} -s -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
https://${ALEXA}/api/language > /dev/null
|
||||
|
||||
rm -f "${TMP}/.alexa.header"
|
||||
rm -f "${TMP}/.alexa.postdata"
|
||||
rm -f "${TMP}/.alexa.postdata2"
|
||||
}
|
||||
|
||||
#
|
||||
# get JSON device list
|
||||
#
|
||||
get_devlist()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})"\
|
||||
"https://${ALEXA}/api/devices-v2/device?cached=false" > ${DEVLIST}
|
||||
|
||||
if [ ! -f ${DEVTXT} ] ; then
|
||||
cat ${DEVLIST}| sed 's/\\\\\//\//g' | sed 's/[{}]//g' | awk -v k="text" '{n=split($0,a,","); for (i=1; i<=n; i++) print a[i]}' | sed 's/\"\:\"/\|/g' | sed 's/[\,]/ /g' | sed 's/\"//g' > ${DEVTXT}
|
||||
fi
|
||||
}
|
||||
|
||||
check_status()
|
||||
{
|
||||
#
|
||||
# bootstrap with GUI-Version writes GUI version to cookie
|
||||
# returns among other the current authentication state
|
||||
#
|
||||
AUTHSTATUS=$(${CURL} ${OPTS} -s -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L https://${ALEXA}/api/bootstrap?version=${GUIVERSION} | sed -r 's/^.*"authenticated":([^,]+),.*$/\1/g')
|
||||
|
||||
if [ "$AUTHSTATUS" = "true" ] ; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#
|
||||
# set device specific variables from JSON device list
|
||||
#
|
||||
set_var()
|
||||
{
|
||||
ATTR="accountName"
|
||||
NAME=`grep ${ATTR}\| ${DEVTXT} | sed "s/^.*${ATTR}|//" | sed 's/ /_/g'`
|
||||
|
||||
ATTR="deviceType"
|
||||
TYPE=`grep ${ATTR}\| ${DEVTXT} | sed "s/^.*${ATTR}|//" | sed 's/ /_/g'`
|
||||
|
||||
ATTR="serialNumber"
|
||||
SERIAL=`grep ${ATTR}\| ${DEVTXT} | sed "s/^.*${ATTR}|//" | sed 's/ /_/g'`
|
||||
|
||||
ATTR="deviceOwnerCustomerId"
|
||||
MEDIAID=`grep ${ATTR}\| ${DEVTXT} | sed "s/^.*${ATTR}|//" | sed 's/ /_/g'`
|
||||
|
||||
ATTR="deviceFamily"
|
||||
FAMILY=`grep ${ATTR}\| ${DEVTXT} | sed "s/^.*${ATTR}|//" | sed 's/ /_/g'`
|
||||
|
||||
|
||||
if [ -z "${DEVICE}" ] ; then
|
||||
# if no device was supplied, use the first Echo(dot) in device list
|
||||
IDX=0
|
||||
for I in $FAMILY ; do
|
||||
if [ "$I" = "ECHO" -o "$I" = "KNIGHT" -o "$I" = "ROOK" ] ; then
|
||||
break;
|
||||
fi
|
||||
IDX=$((IDX+1))
|
||||
done
|
||||
|
||||
C=0
|
||||
for I in $NAME ; do
|
||||
if [ $C -eq $IDX ] ; then
|
||||
DEVICE=$I
|
||||
break
|
||||
fi
|
||||
C=$((C+1))
|
||||
done
|
||||
echo "setting default device to:"
|
||||
echo ${DEVICE}
|
||||
else
|
||||
DEVICE=`echo $DEVICE | sed 's/ /_/g'`
|
||||
IDX=0
|
||||
for I in $NAME ; do
|
||||
if [ "$I" = "$DEVICE" ] ; then
|
||||
break;
|
||||
fi
|
||||
IDX=$((IDX+1))
|
||||
done
|
||||
fi
|
||||
|
||||
C=0
|
||||
for I in $MEDIAID ; do
|
||||
if [ $C -eq $IDX ] ; then
|
||||
MEDIAOWNERCUSTOMERID=$I
|
||||
break
|
||||
fi
|
||||
C=$((C+1))
|
||||
done
|
||||
|
||||
C=0
|
||||
for I in $TYPE ; do
|
||||
if [ $C -eq $IDX ] ; then
|
||||
DEVICETYPE=$I
|
||||
break
|
||||
fi
|
||||
C=$((C+1))
|
||||
done
|
||||
|
||||
C=0
|
||||
for I in $SERIAL ; do
|
||||
if [ $C -eq $IDX ] ; then
|
||||
DEVICESERIALNUMBER=$I
|
||||
break
|
||||
fi
|
||||
C=$((C+1))
|
||||
done
|
||||
|
||||
if [ -z "${DEVICESERIALNUMBER}" ] ; then
|
||||
echo "ERROR: unkown device dev:${DEVICE}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# execute command
|
||||
#
|
||||
run_cmd()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d ${COMMAND}\
|
||||
"https://${ALEXA}/api/np/command?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}"
|
||||
}
|
||||
|
||||
#
|
||||
# play TuneIn radio station
|
||||
#
|
||||
play_radio()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST\
|
||||
"https://${ALEXA}/api/tunein/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&guideId=${STATIONID}&contentType=station&callSign=&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}"
|
||||
}
|
||||
|
||||
#
|
||||
# play library track
|
||||
#
|
||||
play_song()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "{\"trackId\":\"${SONG}\",\"playQueuePrime\":true}"\
|
||||
"https://${ALEXA}/api/cloudplayer/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}&shuffle=false"
|
||||
}
|
||||
|
||||
#
|
||||
# play library playlist
|
||||
#
|
||||
play_playlist()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "{\"playlistId\":\"${PLIST}\",\"playQueuePrime\":true}"\
|
||||
"https://${ALEXA}/api/cloudplayer/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}&shuffle=false"
|
||||
}
|
||||
|
||||
#
|
||||
# play PRIME playlist
|
||||
#
|
||||
play_prime_playlist()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "{\"asin\":\"${ASIN}\"}"\
|
||||
"https://${ALEXA}/api/prime/prime-playlist-queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}"
|
||||
}
|
||||
|
||||
#
|
||||
# play PRIME station
|
||||
#
|
||||
play_prime_station()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "{\"seed\":\"{\\\"type\\\":\\\"KEY\\\",\\\"seedId\\\":\\\"${SEEDID}\\\"}\",\"stationName\":\"none\",\"seedType\":\"KEY\"}"\
|
||||
"https://${ALEXA}/api/gotham/queue-and-play?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}&mediaOwnerCustomerId=${MEDIAOWNERCUSTOMERID}"
|
||||
}
|
||||
|
||||
#
|
||||
# play PRIME historical queue
|
||||
#
|
||||
play_prime_hist_queue()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "{\"deviceType\":\"${DEVICETYPE}\",\"deviceSerialNumber\":\"${DEVICESERIALNUMBER}\",\"mediaOwnerCustomerId\":\"${MEDIAOWNERCUSTOMERID}\",\"queueId\":\"${HIST}\",\"service\":null,\"trackSource\":\"TRACK\"}"\
|
||||
"https://${ALEXA}/api/media/play-historical-queue"
|
||||
}
|
||||
|
||||
#
|
||||
# current queue
|
||||
#
|
||||
show_queue()
|
||||
{
|
||||
echo "/api/np/player"
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X GET \
|
||||
"https://${ALEXA}/api/np/player?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}"
|
||||
echo
|
||||
echo "/api/np/queue"
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X GET \
|
||||
"https://${ALEXA}/api/np/queue?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}"
|
||||
echo
|
||||
echo "/api/media/state"
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X GET \
|
||||
"https://${ALEXA}/api/media/state?deviceSerialNumber=${DEVICESERIALNUMBER}&deviceType=${DEVICETYPE}"
|
||||
echo
|
||||
}
|
||||
|
||||
#
|
||||
# deletes a multiroom device
|
||||
#
|
||||
delete_multiroom()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X DELETE \
|
||||
"https://${ALEXA}/api/lemur/tail/${DEVICESERIALNUMBER}"
|
||||
}
|
||||
|
||||
#
|
||||
# creates a multiroom device
|
||||
#
|
||||
create_multiroom()
|
||||
{
|
||||
JSON="{\"id\":null,\"name\":\"${LEMUR}\",\"members\":["
|
||||
for DEVICE in $CHILD ; do
|
||||
set_var
|
||||
JSON="${JSON}{\"dsn\":\"${DEVICESERIALNUMBER}\",\"deviceType\":\"${DEVICETYPE}\"},"
|
||||
done
|
||||
JSON="${JSON%,}]}"
|
||||
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "${JSON}" \
|
||||
"https://${ALEXA}/api/lemur/tail"
|
||||
}
|
||||
|
||||
#
|
||||
# list bluetooth devices
|
||||
#
|
||||
list_bluetooth()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X GET \
|
||||
"https://${ALEXA}/api/bluetooth?cached=false"
|
||||
}
|
||||
|
||||
#
|
||||
# connect bluetooth device
|
||||
#
|
||||
connect_bluetooth()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST -d "{\"bluetoothDeviceAddress\":\"${BLUETOOTH}\"}"\
|
||||
"https://${ALEXA}/api/bluetooth/pair-sink/${DEVICETYPE}/${DEVICESERIALNUMBER}"
|
||||
}
|
||||
|
||||
#
|
||||
# disconnect bluetooth device
|
||||
#
|
||||
disconnect_bluetooth()
|
||||
{
|
||||
${CURL} ${OPTS} -s -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
-H "Content-Type: application/json; charset=UTF-8" -H "Referer: https://alexa.${AMAZON}/spa/index.html" -H "Origin: https://alexa.${AMAZON}"\
|
||||
-H "csrf: $(awk "\$0 ~/.${AMAZON}.*csrf[ \\s\\t]+/ {print \$7}" ${COOKIE})" -X POST \
|
||||
"https://${ALEXA}/api/bluetooth/disconnect-sink/${DEVICETYPE}/${DEVICESERIALNUMBER}"
|
||||
}
|
||||
|
||||
#
|
||||
# logout
|
||||
#
|
||||
log_off()
|
||||
{
|
||||
${CURL} ${OPTS} -s -c ${COOKIE} -b ${COOKIE} -A "${BROWSER}" -H "DNT: 1" -H "Connection: keep-alive" -L\
|
||||
https://${ALEXA}/logout > /dev/null
|
||||
|
||||
rm -f ${DEVLIST}
|
||||
rm -f ${DEVTXT}
|
||||
rm -f ${COOKIE}
|
||||
}
|
||||
|
||||
if [ -z "$BLUETOOTH" -a -z "$LEMUR" -a -z "$PLIST" -a -z "$HIST" -a -z "$SEEDID" -a -z "$ASIN" -a -z "$QUEUE" -a -z "$COMMAND" -a -z "$STATIONID" -a -z "$SONG" -a -n "$LOGOFF" ] ; then
|
||||
echo "only logout option present, logging off ..."
|
||||
log_off
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -f ${COOKIE} ] ; then
|
||||
echo "cookie do not exist. logging in ..."
|
||||
log_in
|
||||
fi
|
||||
|
||||
check_status
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo "cookie expired, logging in again ..."
|
||||
log_in
|
||||
check_status
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo "log in failed, aborting"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f ${DEVTXT} ] ; then
|
||||
echo "device list do not exist. downloading ..."
|
||||
get_devlist
|
||||
if [ ! -f ${DEVTXT} ] ; then
|
||||
echo "failed to download device list, aborting"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$COMMAND" ] ; then
|
||||
set_var
|
||||
if [ -n "$COMMAND" ] ; then
|
||||
echo "sending cmd:${COMMAND} to dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}"
|
||||
run_cmd
|
||||
fi
|
||||
elif [ -n "$LEMUR" ] ; then
|
||||
DEVICE="${LEMUR}"
|
||||
set_var
|
||||
if [ -n "$DEVICESERIALNUMBER" ] ; then
|
||||
delete_multiroom
|
||||
fi
|
||||
if [ -z "$CHILD" ] ; then
|
||||
echo "Deleted multi room dev:${LEMUR} serial:${DEVICESERIALNUMBER}"
|
||||
else
|
||||
echo "Creating multi room dev:${LEMUR} member_dev(s):${CHILD}"
|
||||
create_multiroom
|
||||
fi
|
||||
rm -f ${DEVLIST}
|
||||
rm -f ${DEVTXT}
|
||||
get_devlist
|
||||
elif [ -n "$BLUETOOTH" ] ; then
|
||||
set_var
|
||||
if [ "$BLUETOOTH" = "null" ] ; then
|
||||
echo "disconnecting dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} from bluetooth"
|
||||
disconnect_bluetooth
|
||||
elif [ "$BLUETOOTH" = "list" -o "$BLUETOOTH" = "List" -o "$BLUETOOTH" = "LIST" ] ; then
|
||||
echo "bluetooth api list:"
|
||||
list_bluetooth
|
||||
else
|
||||
echo "connecting dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} to bluetooth device:${BLUETOOTH}"
|
||||
connect_bluetooth
|
||||
fi
|
||||
elif [ -n "$STATIONID" ] ; then
|
||||
set_var
|
||||
echo "playing stationID:${STATIONID} on dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} mediaownerid:${MEDIAOWNERCUSTOMERID}"
|
||||
play_radio
|
||||
elif [ -n "$SONG" ] ; then
|
||||
set_var
|
||||
echo "playing library track:${SONG} on dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} mediaownerid:${MEDIAOWNERCUSTOMERID}"
|
||||
play_song
|
||||
elif [ -n "$PLIST" ] ; then
|
||||
set_var
|
||||
echo "playing library playlist:${PLIST} on dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER} mediaownerid:${MEDIAOWNERCUSTOMERID}"
|
||||
play_playlist
|
||||
elif [ -n "$ASIN" ] ; then
|
||||
set_var
|
||||
echo "playing PRIME playlist ${ASIN}"
|
||||
play_prime_playlist
|
||||
elif [ -n "$SEEDID" ] ; then
|
||||
set_var
|
||||
echo "playing PRIME station ${SEEDID}"
|
||||
play_prime_station
|
||||
elif [ -n "$HIST" ] ; then
|
||||
set_var
|
||||
echo "playing PRIME historical queue ${HIST}"
|
||||
play_prime_hist_queue
|
||||
elif [ -n "$QUEUE" ]; then
|
||||
set_var
|
||||
echo "queue info for dev:${DEVICE} type:${DEVICETYPE} serial:${DEVICESERIALNUMBER}"
|
||||
show_queue
|
||||
elif [ -n "$LIST" ] ; then
|
||||
ATTR="accountName"
|
||||
echo "the following devices exist in your account:"
|
||||
grep ${ATTR}\| ${DEVTXT} | sed "s/^.*${ATTR}|//" | sed 's/ /_/g'
|
||||
else
|
||||
echo "no alexa command received"
|
||||
fi
|
||||
|
||||
if [ -n "$LOGOFF" ] ; then
|
||||
echo "logout option present, logging off ..."
|
||||
log_off
|
||||
fi
|
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
DEVICENUMBER='G090LF1234540B82'
|
||||
DEVICETYPE='A3S5123456VAYF'
|
||||
COOKIE='Cookie: x-amzn-dat-gui-client-v=1.24.986.0; aws-target-static-id=14712345678-839972; aws-session-id=168-0412369-4130549; aws-session-id-time=2106194071l; aws-x-main=PgpqvER9Wibauhf4zfSDriNBlBILfMnk; aws-at-main=Atza|IwEBIAFsntUWFc_PZvFde5drDzPNXXXXXXXXXHPqI53aQNl-Fu83eAMUsFJmMtamv_4mLKEh6N82lqq8OHA8SKgh44X2MZwTguXNcUvd0-RVQyayT2lQ86JjoXvJrlMlrZIs7kJLWBryCGJEXXXXXXXXXXFJQpHhnGeC72ljNT_nVObL_wZoYhMFHVMXGiYjFyrb-QcjYY-I3ar-Q-kLAmzZYQIKU-mZ8GChNefKuG_x4ZZ2A06XXXXXXXXXOhX9w94vgmn2y3Qr9Q0rEi8K--UoFuTQ54GArubNsofNLh4U2dov8D7Gs3GoW6Hp2zEwt7cyumpRR_vceAz3aUjskoNKXsgDfpPZrebl-0R4bC6BfIasyoDOX9XXXXXXXXjRihKSxf4gs79p1ExYBmaBOX6glBrsKRqOXfk6Vh87_96uQ; aws-userInfo=%7B%22arn%22%3A%22arn%3Aaws%3Aiam%3A%3A314911114493%3Aroot%22%2C%22alias%22%3A%22%22%2C%22username%22%3A%22MeinUser%2520Name%22%2C%22keybase%22%3A%22dhVv%2Fmb%2BJyCH%2BJA6zwfighlgs5jc0W0mVYXkLBkb77M%5Cu003d%22%2C%22issuer%22%3A%22https%3A%2F%2Fwww.amazon.com%2Fap%2Fsignin%22%7D; __utmv=191231197.PgpqvER9Wibauhf4zfSDXXXXXXXXk; s_dslv=1475471239073; regStatus=registered; aws-target-visitor-id=1475445653051-715340.26_4; aws-target-data=%7B%22support%22%3A%221%22%7D; s_pers=%20s_ev15%3D%255B%255B%2527Typed%252FBookmarked%2527%252C%25212375474893114%2527%255D%255D%7C1632141293114%3B%20s_fid%3D0523A63XXXXXXXXX3C9679E640DA3570%7C1538547024210%3B%20s_dl%3D1%7C1475481765932%3B%20gpv_page%3Dno%2520value%7C1475481765939%3B; session-id=151-3512347-8293901; session-id-time=2106212731l; s_fid=71689F1234D6D238-299FD69294EFC3C1; s_nr=1475492764173-Repeat; aws-ubid-main=151-3388123-1263140; aws-session-token="lprp9YroXXXXXXXXXz5EFfSaPt96R0oSBWL2dR/AGFdlmk4QwRcVPXXXXXXXrmZ5kfHBdNwvSWWMKTnYU0pB5CE2XXXXXXUk6SIuaQYti17ZQ8B3NGwyCKNs7Lil+kz9qonZS5/cwtmrWHCe7SGx/QmPXXXXXXX89WbiV2xwTRkhVw6hTjO+8WUOXXXXXXXXi8MaR196v+Ewflx7dd3ouTVtY+hbJE4XSs="; __utma=194891197.1975555581.1444474071.1475495555.1475555580.5; __utmz=194555597.1475555680.5.2.utmccn=(referral)|utmcsr=console.aws.amazon.com|utmcct=/cloudwatch/home|utmcmd=referral; ubid-main=152-8362434-2710144; session-token="Y2Eoqs81+wIbanI7mPonK9t7gFvH7ZdTG2OxCZB3orqTILNY5ev4cFBWiSPTl2u8nFNXNmwtFP6RxnPBTunkdbHfpos8WYYOX7gEF52wnn5J3SknsvO99+MAT5GeyMR4JRa+ZOX+DcnIt8xtgYY2sSaEZ3JspjrQF+M9PUkuT9D4aYbZGRNa1BkFvoOt8Kettr9xxS/ODPfXEaE6xJr7qyPv0IQ3K6e+FbfGk3AWypY="; x-main=4r7ZrJJV4BT1R2sWn2W4NpiXZm9RSJLD; at-main=Atza|IwEEEEE4EikDns-CTHnGRqXXXcnnaij75AfcF1-XOBvphYTp_ATJHu6f0vDgMI7B1ApWn51cP6bqvG-XXXXeTPD8t7jl5El_FdhlYn3mmtn476FfnI5E7anoZNSKLyE-jauNJssBeGUjsSd0z8746mujYcJbKQsMMVVUlxcu4jXXxXXYcC4GasQyvOIp92wY-TPKAOys8NV0-yXH4xTGBzgJ0zzJa5JvyRz2v0x3fijvyXXXXXXSDhZtaDOZ6GOQlYrsUmudsorYUcUT52x0EYavXXXXX92cmgkMUzuTxppV1SpLk2Wk63LQQkCCZLs6_HWlnX2Saf0zgc13BdUehhSBiYHzJJeg1Ys7g68GLG5IuSGvyGe8ebmcN9KUDdD2CwphaeW34iy6dVKGbUpJ3GKVlz; sess-at-main="eSHstcxm5Krki5T1EAcQyk9XXXXXXqMbqcJqDBaA="; csrf=-2012345694'
|
||||
CSRF='csrf: -2081234594'
|
||||
|
||||
CMD='{"type":"NextCommand"}'
|
||||
URL='https://pitangui.amazon.com/api/np/command?deviceSerialNumber='$DEVICENUMBER'&deviceType='$DEVICETYPE
|
||||
curl $URL \
|
||||
-H "$COOKIE" \
|
||||
-H "$CSRF" \
|
||||
--data "${CMD}" \
|
||||
--compressed
|
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
DEVICENUMBER='G090LF1234540B82'
|
||||
DEVICETYPE='A3S5123456VAYF'
|
||||
COOKIE='Cookie: x-amzn-dat-gui-client-v=1.24.986.0; aws-target-static-id=14712345678-839972; aws-session-id=168-0412369-4130549; aws-session-id-time=2106194071l; aws-x-main=PgpqvER9Wibauhf4zfSDriNBlBILfMnk; aws-at-main=Atza|IwEBIAFsntUWFc_PZvFde5drDzPNXXXXXXXXXHPqI53aQNl-Fu83eAMUsFJmMtamv_4mLKEh6N82lqq8OHA8SKgh44X2MZwTguXNcUvd0-RVQyayT2lQ86JjoXvJrlMlrZIs7kJLWBryCGJEXXXXXXXXXXFJQpHhnGeC72ljNT_nVObL_wZoYhMFHVMXGiYjFyrb-QcjYY-I3ar-Q-kLAmzZYQIKU-mZ8GChNefKuG_x4ZZ2A06XXXXXXXXXOhX9w94vgmn2y3Qr9Q0rEi8K--UoFuTQ54GArubNsofNLh4U2dov8D7Gs3GoW6Hp2zEwt7cyumpRR_vceAz3aUjskoNKXsgDfpPZrebl-0R4bC6BfIasyoDOX9XXXXXXXXjRihKSxf4gs79p1ExYBmaBOX6glBrsKRqOXfk6Vh87_96uQ; aws-userInfo=%7B%22arn%22%3A%22arn%3Aaws%3Aiam%3A%3A314911114493%3Aroot%22%2C%22alias%22%3A%22%22%2C%22username%22%3A%22MeinUser%2520Name%22%2C%22keybase%22%3A%22dhVv%2Fmb%2BJyCH%2BJA6zwfighlgs5jc0W0mVYXkLBkb77M%5Cu003d%22%2C%22issuer%22%3A%22https%3A%2F%2Fwww.amazon.com%2Fap%2Fsignin%22%7D; __utmv=191231197.PgpqvER9Wibauhf4zfSDXXXXXXXXk; s_dslv=1475471239073; regStatus=registered; aws-target-visitor-id=1475445653051-715340.26_4; aws-target-data=%7B%22support%22%3A%221%22%7D; s_pers=%20s_ev15%3D%255B%255B%2527Typed%252FBookmarked%2527%252C%25212375474893114%2527%255D%255D%7C1632141293114%3B%20s_fid%3D0523A63XXXXXXXXX3C9679E640DA3570%7C1538547024210%3B%20s_dl%3D1%7C1475481765932%3B%20gpv_page%3Dno%2520value%7C1475481765939%3B; session-id=151-3512347-8293901; session-id-time=2106212731l; s_fid=71689F1234D6D238-299FD69294EFC3C1; s_nr=1475492764173-Repeat; aws-ubid-main=151-3388123-1263140; aws-session-token="lprp9YroXXXXXXXXXz5EFfSaPt96R0oSBWL2dR/AGFdlmk4QwRcVPXXXXXXXrmZ5kfHBdNwvSWWMKTnYU0pB5CE2XXXXXXUk6SIuaQYti17ZQ8B3NGwyCKNs7Lil+kz9qonZS5/cwtmrWHCe7SGx/QmPXXXXXXX89WbiV2xwTRkhVw6hTjO+8WUOXXXXXXXXi8MaR196v+Ewflx7dd3ouTVtY+hbJE4XSs="; __utma=194891197.1975555581.1444474071.1475495555.1475555580.5; __utmz=194555597.1475555680.5.2.utmccn=(referral)|utmcsr=console.aws.amazon.com|utmcct=/cloudwatch/home|utmcmd=referral; ubid-main=152-8362434-2710144; session-token="Y2Eoqs81+wIbanI7mPonK9t7gFvH7ZdTG2OxCZB3orqTILNY5ev4cFBWiSPTl2u8nFNXNmwtFP6RxnPBTunkdbHfpos8WYYOX7gEF52wnn5J3SknsvO99+MAT5GeyMR4JRa+ZOX+DcnIt8xtgYY2sSaEZ3JspjrQF+M9PUkuT9D4aYbZGRNa1BkFvoOt8Kettr9xxS/ODPfXEaE6xJr7qyPv0IQ3K6e+FbfGk3AWypY="; x-main=4r7ZrJJV4BT1R2sWn2W4NpiXZm9RSJLD; at-main=Atza|IwEEEEE4EikDns-CTHnGRqXXXcnnaij75AfcF1-XOBvphYTp_ATJHu6f0vDgMI7B1ApWn51cP6bqvG-XXXXeTPD8t7jl5El_FdhlYn3mmtn476FfnI5E7anoZNSKLyE-jauNJssBeGUjsSd0z8746mujYcJbKQsMMVVUlxcu4jXXxXXYcC4GasQyvOIp92wY-TPKAOys8NV0-yXH4xTGBzgJ0zzJa5JvyRz2v0x3fijvyXXXXXXSDhZtaDOZ6GOQlYrsUmudsorYUcUT52x0EYavXXXXX92cmgkMUzuTxppV1SpLk2Wk63LQQkCCZLs6_HWlnX2Saf0zgc13BdUehhSBiYHzJJeg1Ys7g68GLG5IuSGvyGe8ebmcN9KUDdD2CwphaeW34iy6dVKGbUpJ3GKVlz; sess-at-main="eSHstcxm5Krki5T1EAcQyk9XXXXXXqMbqcJqDBaA="; csrf=-2012345694'
|
||||
CSRF='csrf: -2081234594'
|
||||
|
||||
CMD='{"type":"PlayCommand"}'
|
||||
URL='https://pitangui.amazon.com/api/np/command?deviceSerialNumber='$DEVICENUMBER'&deviceType='$DEVICETYPE
|
||||
curl $URL \
|
||||
-H "$COOKIE" \
|
||||
-H "$CSRF" \
|
||||
--data "${CMD}" \
|
||||
--compressed
|
Loading…
Reference in New Issue
Block a user