Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Lucky

    NEWS

    • 15. 05. Wartungsarbeiten am ioBroker Forum

    • Monatsrückblick - April 2025

    • Minor js-controller 7.0.7 Update in latest repo

    L
    • Profile
    • Following 0
    • Followers 0
    • Topics 11
    • Posts 117
    • Best 1
    • Groups 0

    Lucky

    @Lucky

    1
    Reputation
    38
    Profile views
    117
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    Lucky Follow

    Best posts made by Lucky

    • [Vorlage] Spotify Skript

      Moin,

      ich habe mal ein Skript begonnen mit dem Spotify gesteuert werden kann,

      Damit das Skript genutzt werden kann ist folgendes vorher zutun

      • Es muß das NPM Modul querystring im Javascript Adapter hinzugefügt werden !
      • Es wird ein Premium Account benötigt, mit Spotify Family sollte es auch laufen (gem. Angaben von Leuten die es getestet haben)
      • Sonos Geräte werden NICHT zu 100% unterstützt, was durch die API bedingt ist !

      1.Registriere dich auch https://developer.spotify.com

      2.Erstelle einen Application, du erhällst einen Client ID und eine Client Secret

      3.trage in den App Settings deiner Application bei Redirect URIs 'http://localhost' ein

      4.trage hier in diesem Skript deine Cliend ID und Client Secret ein

      5.Starte dieses Skript

      6.wechsle zum Tap Objekte und klicke unter javascript.0.Spotify.Authorization.Authorized auf den Button Get_Authorization

      7.Kopiere die unter javascript.0.Spotify.Authorization.Authorization_URL angezeigte URL in einen Webbrowser und rufe sie auf.

      8.Der Browser wird die Verbindung ablehnen und in der Adresszeile eine URL zurückgeben

      9.kopiere jetzt wider diese URL und füge sie im State 'javascript.0.Spotify.Authorization.Authorization_Return_URI' ein

      ab jetzt gibte es die neueste Version nur noch hier !

      change log

      0.5.3

      -Stabilität verbessert

      -Tracks zusätzlich als Listenstring

      Version 0.5.3 getestet mit JS 3.6.3 (edited by Bluefox)

      /*Version 0.5.3
      letzte änderung 11.02.2018 19:25
      Read Me !!!!!!!
      wie bekomme ich dieses Skript zum laufen ? 
      Es muß das NPM Modul querystring im Javascript Adapter hinzugefügt werden !
      1.Registriere dich auch https://developer.spotify.com
      2.Erstelle einen application, du erhällst einen Client ID und eine Client Secret
      3.trage in den App Settings deiner application bei Redirect URIs 'http://localhost' ein
      4.trage hier in diesem Skript deine Cliend ID und Client Secret ein
      5.Starte dieses Skript
      6.wechsle zum Tap Objekte und klicke unter 'javascript.0.Spotify.Authorization.Authorized' auf den Button Get_Authorization
      7.Kopiere die unter 'javascript.0.Spotify.Authorization.Authorization_URL' angezeigte URL in einen  Webbrowser und rufe sie auf.
      8.Der Browser wird die Verbindung ablehnen und in der Adresszeile eine URL zurückgeben
      9.kopiere jetzt wider diese URL und füge sie im State 'javascript.0.Spotify.Authorization.Authorization_Return_URI' ein
      10.wenn alles funktioniert hat wechselt 'javascript.0.Spotify.Authorization.Authorized' auf true 
      */
      const request = require('request');
      const querystring = require('querystring');
      const fs = require('fs');
      
      createState('javascript.0.Spotify.Player.Play', false, {type: 'boolean', role: 'button'});
      createState('javascript.0.Spotify.Player.Pause', false, {type: 'boolean', role: 'button'});
      createState('javascript.0.Spotify.Player.Skip_Plus', false, {type: 'boolean', role: 'button'});
      createState('javascript.0.Spotify.Player.Skip_Minus', false, {type: 'boolean', role: 'button'});
      createState('javascript.0.Spotify.Player.Repeat_Track', false, {type: 'boolean', role: 'button'});
      createState('javascript.0.Spotify.Player.Repeat_Context', false, {type: 'boolean', role: 'button'});
      createState('javascript.0.Spotify.Player.Repeat_off', false, {type: 'boolean', role: 'button'});
      createState('javascript.0.Spotify.Player.Volume', 0, {type: 'number', role: 'Volume %'});
      createState('javascript.0.Spotify.Player.TrackId', '', {type: 'string', role: 'Track Id to Play'});
      createState('javascript.0.Spotify.Player.Playlist_ID', '', {type: 'string', role: 'Playlist Id to Play'});
      createState('javascript.0.Spotify.Player.Seek', 0, {type: 'number', role: 'Seek To Position (s)'});
      createState('javascript.0.Spotify.Player.Shuffle', false, {type: 'boolean', role: 'Shuffle'});
      createState('javascript.0.Spotify.Devices.Get_Devices', false, {type: 'boolean', role: 'button'});
      //createState('javascript.0.Spotify.Authorization.Login', false,{type: 'boolean', role: 'button'});
      createState('javascript.0.Spotify.Authorization.Get_Authorization', false, {type: 'boolean', role: 'button'});
      createState('javascript.0.Spotify.Authorization.Authorization_URL', '', {
          type: 'string',
          role: 'Authorization_URL',
          write: false
      });
      createState('javascript.0.Spotify.Authorization.Authorization_Return_URI', '', {
          type: 'string',
          role: 'Authorization_Return_URI'
      });
      createState('javascript.0.Spotify.Authorization.User_ID', '', {type: 'string', role: 'User ID', write: false});
      createState('javascript.0.Spotify.Authorization.Authorized', false, {
          type: 'boolean',
          role: 'Authorized',
          write: false
      });
      createState('javascript.0.Spotify.Get_User_Playlists', false, {type: 'boolean', role: 'button'});
      createState('javascript.0.Spotify.PlaybackInfo.Track_Id', '', {type: 'string', role: 'Track Id', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.Artist_Name', '', {type: 'string', role: 'Artist Name', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.Type', '', {type: 'string', role: 'Type', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.Album', '', {type: 'string', role: 'Album', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.timestamp', 0, {type: 'number', role: 'Timestamp', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.progress_ms', 0, {type: 'number', role: 'progress_ms', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.progress', 0, {type: 'string', role: 'progress', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.is_playing', false, {type: 'boolean', role: 'is_playing', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.image_url', '', {type: 'string', role: 'Image URL', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.Track_Name', '', {type: 'string', role: 'Track_Name', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.duration_ms', 0, {type: 'number', role: 'Duration ms', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.duration', 0, {type: 'string', role: 'duration', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.Playlist', '', {type: 'string', role: 'Playlist', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.Device.id', '', {type: 'string', role: 'id', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.Device.is_active', false, {
          type: 'boolean',
          role: 'is active',
          write: false
      });
      createState('javascript.0.Spotify.PlaybackInfo.Device.is_restricted', false, {
          type: 'boolean',
          role: 'is restricted',
          write: false
      });
      createState('javascript.0.Spotify.PlaybackInfo.Device.name', '', {type: 'string', role: 'Name', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.Device.type', '', {type: 'string', role: 'Type', write: false});
      createState('javascript.0.Spotify.PlaybackInfo.Device.volume_percent', 0, {
          type: 'number',
          role: 'volume_percent',
          write: false
      });
      //createState('javascript.0.Spotify.Playlist_Names','',{type: 'string', role: 'String of Playlist Names',write:false});
      //createState('javascript.0.Spotify.Playlist_Index',0 ,{type: 'number', role: 'Playlist_Index'});
      const application = {
          User_ID: '',//Nichts eintragen !!
          BaseURL: 'https://api.spotify.com',
          Client_ID: 'HIER DEINE CLIENT ID !!',
          Client_Secret: 'HIER DEIN CLIENT SECRET',
          redirect_uri: 'http://localhost',   // in älteren Versionen wird 'https://example.com/callback/' verwendet, 'http://localhost' ist eine Sichere Variante
          Token: '', //Nichts eintragen !!
          refresh_token: '',//Nichts eintragen !!
          code: '',//Nichts eintragen !!
          State: '',//Nichts eintragen !!
          TokenFilePath: '/opt/Spotify.token'
      };
      
      const deviceData = {
          last_active_device_id: '',
          last_select_device_id: '',
      };
      
      let interval;
      
      //############### Initial ##########
      readTokenFiles((err, Token) => { //23.01.2018 Funktion überarbeitet 
          if (!err) {
              application.Token = Token.AccessToken;
              application.refresh_token = Token.RefreshToken;
              sendRequest('/v1/me', 'GET', '', (err, data) => {
                  if (!err) {
                      GetUserInformation(data);
                      setState('javascript.0.Spotify.Authorization.Authorized', true, true);
      
                      sendRequest('/v1/me/player/devices', 'GET', '', (err, data) => !err && createDevices(data));
                  } else {
                      setState('javascript.0.Spotify.Authorization.Authorized', false, true);
                      console.error('sendRequest in readTokenFiles ' + err);
                  }
              });
          } else {
              setState('javascript.0.Spotify.Authorization.Authorized', false, true);
              console.warn(err);
          }
      });
      
      //#################################
      function readTokenFiles(callback) {
          fs.readFile(application.TokenFilePath, 'utf8', (err, data) => {
              if (!err) { //wenn keine Fehler
      
                  const Token = JSON.parse(data);
                  const ATF = 'undefined' !== typeof  Token.AccessToken && (Token.AccessToken !== '');
                  const RTF = 'undefined' !== typeof  Token.RefreshToken && (Token.RefreshToken !== '');
      
                  if (ATF && RTF) {
                      console.log('Spotify Token aus Datei gelesen !');
                      return callback(null, Token);
                  } else {
                      return callback('Keine Token in Datei gefunden !', null)
                  }
              } else {
                  console.log(err);
                  return callback('keine Token-Datei gefunden !, wird erstellt nach Autorisierung  ', null);
              }
          });
      }// End of Function readTokenFiles 
      
      //###################################################################################### FUNCTION SEND REQUEST ###################################################################################
      function sendRequest(endPoint, method, body, callback) {
          method = method || 'PUT';
          body = body || '';
          
          const options = {
              url: application.BaseURL + endPoint,
              method: method,
              headers: {Authorization: 'Bearer ' + application.Token},
              form: body
          };
          // console.log(options.form);
          // console.log('Spotify API Call...'+ endPoint);
          request(options, (error, response, body) => {
              if (!error) {
                  switch (response.statusCode) {
                      case 200: // OK
                          return callback && callback(null, JSON.parse(body));
      
                      case 202: //Accepted, processing has not been completed.
                          return callback && callback(response.statusCode, null);
                      case 204: // OK, No Content
                          return callback && callback(null, null);
      
                      case 400: //Bad Request, message body will contain more information
                      case 500: //Server Error
                      case 503: //Service Unavailable
                      case 404: //Not Found
                      case 502: //Bad Gateway
                          return callback && callback(response.statusCode, null);
      
                      case 401: //Unauthorized 
                          if (JSON.parse(body).error.message === 'The access token expired') {
                              console.log('Access Token Abgelaufen!!');
                              setState('javascript.0.Spotify.Authorization.Authorized', false, true);  // neu 05.02.2018
      
                              refreshToken(err => {
                                  if (!err) {
                                      setState('javascript.0.Spotify.Authorization.Authorized', true, true);
      
                                      sendRequest(endPoint, method, body, (err, data) => { // dieser Request holt die Daten die zuvor mit altem Token gefordert wurden
                                          if (!err) {
                                              console.log('Daten mit neuem Token');
                                              return callback && callback(null, data);
                                          } else if (err == 202) {
                                              console.log(err + ' Anfrage akzeptiert, keine Daten in Antwort, veruch es nochnal ;-)');
                                              return callback && callback(err, null);
                                          } else {
                                              console.error('FEHLER BEIM ERNEUTEN DATEN ANFORDERN ! ' + err);
                                              return callback && callback(err, null);
                                          }
                                      });
      
                                  } else {  //05.02.2018 19:43
                                      console.error(err);
                                      return callback && callback(err, null);
                                  }
                              });
                          } else { //wenn anderer Fehler mit Code 401
                              setState('javascript.0.Spotify.Authorization.Authorized', false, true);  // neu 05.01.2018
                              console.error(JSON.parse(body).error.message);
                              return callback && callback(response.statusCode, null);
                          }
                          break;
      
                      default:
                          console.warn('HTTP Request Fehler wird nicht behandelt, bitte Debuggen !!');
                          return callback && callback(response.statusCode, null);
                  }
              } else {
                  console.error('erron in Request');
                  return callback && callback(0, null);
              }
          });//end Request
      }//End of Function sendRequest
      //###################################################################################### END OF FUNCTION SEND REQUEST ###################################################################################
      
      function createPlaybackInfo(pBody) {
      
          //console.log(JSON.stringify(pBody))
      
          if (pBody.hasOwnProperty('device')) {
              deviceData.last_active_device_id = pBody.device.id;
              setState('javascript.0.Spotify.PlaybackInfo.Device.id', pBody.device.id, true);
          }
      
          if (pBody.hasOwnProperty('is_playing')) {
              setState('javascript.0.Spotify.PlaybackInfo.is_playing', pBody.is_playing, true);
              if (pBody.is_playing === true) {
      
                  setState('javascript.0.Spotify.PlaybackInfo.Track_Id', pBody.item.id, true);
                  setState('javascript.0.Spotify.PlaybackInfo.Artist_Name', pBody.item.artists[0].name, true);
                  if (pBody.context !== null) {
      
                      setState('javascript.0.Spotify.PlaybackInfo.Type', pBody.context.type, true);
      
                      if (pBody.context.type === 'playlist') {
                          const IndexOfUser = pBody.context.uri.indexOf('user:') + 5;
                          const EndIndexOfUser = pBody.context.uri.indexOf(':', IndexOfUser);
      
                          const IndexOfPlaylistID = pBody.context.uri.indexOf('playlist:') + 9;
      
                          const query = {
                              fields: 'name',
                          };
      
                          sendRequest('/v1/users/' + pBody.context.uri.substring(IndexOfUser, EndIndexOfUser) + '/playlists/' + pBody.context.uri.slice(IndexOfPlaylistID) + '?' + querystring.stringify(query), 'GET', '', (err, pBody) => {
                              if (!err && pBody.hasOwnProperty('name')) {
                                  setState('javascript.0.Spotify.PlaybackInfo.Playlist', pBody.name, true);
                                  //console.log(JSON.stringify(pBody))
                              } else {
                                  console.warn(err + ' function createPlaybackInfo')
                              }
                          });
                      }
                      else {
                          setState('javascript.0.Spotify.PlaybackInfo.Playlist', '', true)
                      }
      
                  }
                  else {
                      setState('javascript.0.Spotify.PlaybackInfo.Type', pBody.item.type, true);
                      setState('javascript.0.Spotify.PlaybackInfo.Playlist', '', true);
                  }
      
                  setState('javascript.0.Spotify.PlaybackInfo.Album', pBody.item.album.name, true);
                  setState('javascript.0.Spotify.PlaybackInfo.timestamp', pBody.timestamp, true);
                  setState('javascript.0.Spotify.PlaybackInfo.progress_ms', pBody.progress_ms, true);
                  setState('javascript.0.Spotify.PlaybackInfo.image_url', pBody.item.album.images[0].url, true);
                  setState('javascript.0.Spotify.PlaybackInfo.Track_Name', pBody.item.name, true);
                  setState('javascript.0.Spotify.PlaybackInfo.duration_ms', pBody.item.duration_ms, true);
      
                  setState('javascript.0.Spotify.PlaybackInfo.duration', digiClock(pBody.item.duration_ms), true);
                  setState('javascript.0.Spotify.PlaybackInfo.progress', digiClock(pBody.progress_ms), true);
      
                  setState('javascript.0.Spotify.PlaybackInfo.Device.is_active', pBody.device.is_active, true);
                  setState('javascript.0.Spotify.PlaybackInfo.Device.is_restricted', pBody.device.is_restricted, true);
                  setState('javascript.0.Spotify.PlaybackInfo.Device.name', pBody.device.name, true);
                  setState('javascript.0.Spotify.PlaybackInfo.Device.type', pBody.device.type, true);
                  setState('javascript.0.Spotify.PlaybackInfo.Device.volume_percent', pBody.device.volume_percent, true);
      
              }
          }
      }//End of Function createPlaybackInfo
      
      function digiClock(ms) {
          // Milisekunden zu Digitaluhr, Beispiel 3:59=238759
          let Min = Math.floor(ms / 60000);
          let Sec = Math.floor(((ms % 360000) % 60000) / 1000);
          if (Min < 10) {
              Min = '0' + Min
          }
          if (Sec < 10) {
              Sec = '0' + Sec
          }
          return Min + ':' + Sec;
      }//End Function digiClock
      
      function GetUserInformation(pBody) {
          application.User_ID = pBody.id;
          setState('javascript.0.Spotify.Authorization.User_ID', pBody.id, true);
      
      }//End of Function GetUserInformation
      
      function GetUsersPlaylist(offset) {
      
          let PlaylistString;
      
          if (application.User_ID !== '') {
              const query = {
                  limit: 30,
                  offset: offset
              };
      
              sendRequest('/v1/users/' + application.User_ID + '/playlists?' + querystring.stringify(query), 'GET', '', (err, pBody) => {
                  if (!err) {
                      for (let i = 0; i < pBody.items.length; i++) {
                          const Pfad = 'javascript.0.Spotify.Playlists.' + pBody.items[i].name.replace(/\s+/g, '');
                          PlaylistString = pBody.items[i].name + ';' + PlaylistString;
      
                          if (getObject(Pfad + '.id') === null) {
                              createState(Pfad + '.Play_this_List', false, {type: 'boolean', role: 'button'});
                              createState(Pfad + '.id', pBody.items[i].id, {type: 'string', role: 'id', write: false});
                              createState(Pfad + '.owner', pBody.items[i].owner.id, {
                                  type: 'string',
                                  role: 'owner',
                                  write: false
                              });
                              createState(Pfad + '.name', pBody.items[i].name, {type: 'string', role: 'Name', write: false});
                              createState(Pfad + '.tracks_total', pBody.items[i].tracks.total, {
                                  type: 'number',
                                  role: 'tracks_total',
                                  write: false
                              });
      
                          } else {
                              setState(Pfad + '.id', pBody.items[i].id, true);
                              setState(Pfad + '.owner', pBody.items[i].owner.id, true);
                              setState(Pfad + '.name', pBody.items[i].name, true);
                              setState(Pfad + '.tracks_total', pBody.items[i].tracks.total, true);
                          }
                          getPlaylistTracks(pBody.items[i].owner.id, pBody.items[i].id, Pfad);
                      }
                      if (pBody.items.length !== 0 && (pBody['next'] !== null)) {
                          GetUsersPlaylist(pBody.offset + pBody.limit)
                      }
      
                      //setState('javascript.0.Spotify.Playlist_Names',PlaylistString);
                  }
      
              });
          }
      } // End of Function GetUsersPlaylist
      function deviceHandel(deviceData) {
          if (deviceData.last_select_device_id === '') {
              return deviceData.last_active_device_id;
          } else {
              return deviceData.last_select_device_id;
          }
      }
      
      function getPlaylistTracks(owner, id, Pfad) {   //NEU
          const reg_param = owner + '/playlists/' + id + '/tracks';
          const query = {
              fields: 'items.track.name,items.track.id,items.track.artists.name,total,offset',
              limit: 100,
              offset: 0
          };
      
          sendRequest('/v1/users/' + reg_param + '?' + querystring.stringify(query), 'GET', '', (err, data) => {
              if (!err) {
                  let StateString = '';
                  let ListString = '';
                  let Track_ID_String = '';
      
                  for (let i = 0; i < data.items.length; i++) {
      
                      StateString = StateString + i.toString() + ':' + data.items[i].track.name + '-' + data.items[i].track.artists[0].name + ';';
                      ListString = ListString + data.items[i].track.name + '-' + data.items[i].track.artists[0].name + ';';
                      Track_ID_String = Track_ID_String + i.toString() + ':' + data.items[i].track.id + ';';
                  }
                  if (getObject(Pfad + '.Track_List') === null) {
                      createState(Pfad + '.Track_List', -1, {
                          type: 'number',
                          role: 'Tracks',
                          states: StateString,
                          Track_ID: Track_ID_String
                      });
                  } else {
                      //setState(Pfad+'.Track_List',StateString,Track_ID=Track_ID_String,akt=true);
                  }
      
                  if (getObject(Pfad + '.Track_List_String') === null) {
                      createState(Pfad + '.Track_List_String', ListString, {type: 'string', role: 'Tracks List String'});
                  } else {
                      setState(Pfad + '.Track_List_String', ListString, true);
                  }
      
              }
      
          });
      }//End of Function getPlaylistTracks
      function createDevices(pBody) {
      
          for (i = 0; i < pBody.devices.length; i++) {
      
              for (const ObjName in pBody.devices[i]) {
      
                  if (!getObject('javascript.0.Spotify.Devices.' + pBody.devices[i].name.replace(/\s+/g, '') + '.' + ObjName)) {
      
                      createState('javascript.0.Spotify.Devices.' + pBody.devices[i].name.replace(/\s+/g, '') + '.' + ObjName, pBody.devices[i][ObjName], {
                          type: typeof pBody.devices[i][ObjName],
                          role: ObjName
                      });
                      createState('javascript.0.Spotify.Devices.' + pBody.devices[i].name.replace(/\s+/g, '') + '.' + 'Use_for_Playback', false, {
                          type: 'boolean',
                          role: 'button'
                      });
                  } else {
                      setState('javascript.0.Spotify.Devices.' + pBody.devices[i].name.replace(/\s+/g, '') + '.' + ObjName, pBody.devices[i][ObjName], true);
                  }
              }
          }
      }//End of Function createDevices 
      function generateRandomString(length) {
          let text = '';
          const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
          for (let i = 0; i < length; i++) {
              text += possible.charAt(Math.floor(Math.random() * possible.length));
          }
          return text;
      }
      
      function requestAuthorization() {
          application.State = generateRandomString(20);
      
          const query = {
              client_id: application.Client_ID,
              response_type: 'code',
              redirect_uri: application.redirect_uri,
              state: application.State,
              scope: 'user-modify-playback-state user-read-playback-state user-read-currently-playing playlist-read-private'
          };
      
          const options = {
              url: 'https://accounts.spotify.com/de/authorize/?' + querystring.stringify(query),
              method: 'GET',
              followAllRedirects: true,
          };
          setState('javascript.0.Spotify.Authorization.Authorization_URL', options.url);
          const debug = false;
          if (debug) {
              request(options, (error, response, body, formData) => {
                  // console.log(options.url);
                  console.log('STATUS_CODE ' + response.statusCode);
                  //console.log('RESPONSE*************'+JSON.stringify(response));
                  //console.log('BODY*****'+body);
                  //console.log('ERROR'+error);
                  //console.log('FORM'+request.form);
                  //console.log('HEADERS   *****'+JSON.stringify(response.headers));
                  //console.log('HTML   *****'+JSON.stringify(response.html));
              });
          }
      }// End of Function requestAuthorization
      
      function getToken() {
          const options = {
              url: 'https://accounts.spotify.com/api/token',
              method: 'POST',
              headers: {Authorization: 'Basic ' + Buffer.from(application.Client_ID + ':' + application.Client_Secret).toString('base64')},
              form: {grant_type: 'authorization_code', code: application.code, redirect_uri: application.redirect_uri}
          };
          request(options, function (error, response, body) {
      
              saveToken(JSON.parse(body), function (err, Token) {
                  if (!err) {
                      setState('javascript.0.Spotify.Authorization.Authorization_URL', '', true);
                      setState('javascript.0.Spotify.Authorization.Authorization_Return_URI', '', true);
                      setState('javascript.0.Spotify.Authorization.Authorized', true, true);
      
                      application.Token = Token.AccessToken;
                      application.refresh_token = Token.RefreshToken;
                  }
                  else {
                      console.log(err)
                  }
              });
          });
      }//End of Function getToken
      
      function refreshToken(callback) {
          console.log('Token wird erneut angefordert ! ');
      
          const options = {
              url: 'https://accounts.spotify.com/api/token',
              method: 'POST',
              headers: {Authorization: 'Basic ' + Buffer.from(application.Client_ID + ':' + application.Client_Secret).toString('base64')},
              form: {grant_type: 'refresh_token', refresh_token: application.refresh_token}
          };
      
          if (application.refresh_token !== '') {
              request(options, (error, response, body) => { // dieser Request holt den neuen Token
                  if (response.statusCode === 200) {
                      console.log('neuer Token eingetroffen');
                      //console.log(body);
                      const pBody = JSON.parse(body);
                      if (!pBody.hasOwnProperty('refresh_token')) {
                          pBody.refresh_token = application.refresh_token
                      }
                      //console.log(JSON.stringify(pBody))
      
                      saveToken(pBody, (err, Token) => {
                          if (!err) {
                              application.Token = Token.AccessToken;
                              return callback(null);
                              //application.refresh_token=Token.refresh_token;
                          } else {
                              console.log(err);
                              return callback(err);
                          }
                      });
                  } else {
                      return callback(response.statusCode)
                  }    //05.02.2018 19:37
              });
          }// end if   
      }//End of Function refreshToken
      
      function saveToken(pBody, callback) {
          //const ParsedBody=JSON.parse(Body);
          //console.log(ParsedBody.hasOwnProperty('access_token'))
          if (pBody.access_token && pBody.refresh_token) {
              const Token = {
                  AccessToken: pBody.access_token,
                  RefreshToken: pBody.refresh_token
              };
              fs.writeFile(application.TokenFilePath, JSON.stringify(Token), 'utf8', err => {
                  if (!err) {
                      console.log('Token Saved!');
                      return callback(null, Token);
                  } else {
                      return callback('Fehler beim Token Speichern', null)
                  }
              });
          } else {
              return callback('keine Token in Serverantwort gefunden ! ', null)
          }
      
      }//End of Function saveToken
      on({id: 'javascript.0.Spotify.Authorization.Authorization_Return_URI', change: 'any'}, obj => {
          if (!obj.state.ack) {
              const return_uri = querystring.parse(obj.state.val.slice(obj.state.val.search('[?]') + 1, obj.state.val.length));
              if (return_uri.state == application.State) {
                  application.code = return_uri.code;
                  getToken();
              }
          }
      
      });
      on({id: 'javascript.0.Spotify.Authorization.Get_Authorization', val: true}, obj => {
          requestAuthorization();
          setState('javascript.0.Spotify.Authorization.Authorized', false, true);
      });
      
      on({id: /\.Use_for_Playback$/, val: true}, obj => {
          deviceData.last_select_device_id = getState(obj.id.slice(0, obj.id.lastIndexOf('.')) + '.id').val;
      
          const send = {
              device_ids: [deviceData.last_select_device_id],  //Divice IDs als Array !
              //play:false  //True = Wiedergabe startet sofort auf diesem Gerät, FALSE = Wiedergabe anhängig von Playback State
          };
          sendRequest('/v1/me/player', 'PUT', JSON.stringify(send), (err, data) => {
              //if(!err){deviceData.last_select_device_id=getState(obj.id.slice(0,obj.id.lastIndexOf('.'))+'.id').val}
          });
      });
      
      on({id: /\.Track_List$/, valGe: 0, valNe: null, ack: false}, obj => { //eine bestimmten Track aus Playliste  sofort abspielen
      
          const StateName = obj.common.Track_ID.split(';');
          const StateArr = [];
          for (let i = 0; i < StateName.length; i++) {
              const ele = StateName[i].split(':');
              StateArr[ele[0]] = ele[1];
          }
          if (StateArr[obj.state.val] !== '' && (StateArr[obj.state.val] !== null)) {
              const send = {
                  uris: ['spotify:track:' + StateArr[obj.state.val]],
                  offset: {
                      position: 0
                  }
              };
      
              sendRequest('/v1/me/player/play', 'PUT', JSON.stringify(send), err =>
                  !err && setState(obj.id, obj.state.val, true));
          }
      });
      
      on({id: /\.Play_this_List$/, val: true}, obj => { //eine bestimmte Playlist sofort abspielen
          const send = {
              context_uri: 'spotify:user:' + getState(obj.id.slice(0, obj.id.lastIndexOf('.')) + '.owner').val + ':playlist:' + getState(obj.id.slice(0, obj.id.lastIndexOf('.')) + '.id').val,
              offset: {
                  position: 1
              }
          };
      
          const query = {device_id: deviceHandel(deviceData)};
          sendRequest('/v1/me/player/play?' + querystring.stringify(query), 'PUT', JSON.stringify(send), () => 
              sendRequest('/v1/me/player', 'GET', '', (err, data) => !err && createPlaybackInfo(data)));
      });
      
      on({id: 'javascript.0.Spotify.Player.Play', val: true}, obj => {
          const query = {device_id: deviceHandel(deviceData)};
          console.log(deviceHandel(deviceData));
          sendRequest('/v1/me/player/play?' + querystring.stringify(query));
      });
      on({id: 'javascript.0.Spotify.Player.Pause', val: true}, obj => {
          const query = {device_id: deviceHandel(deviceData)};
          sendRequest('/v1/me/player/pause?' + querystring.stringify(query));
      });
      
      on({id: 'javascript.0.Spotify.Player.Skip_Plus', val: true}, obj => {
          const query = {device_id: deviceHandel(deviceData)};
          sendRequest('/v1/me/player/next?' + querystring.stringify(query), 'POST');
      });
      
      on({id: 'javascript.0.Spotify.Player.Skip_Minus', val: true}, obj => {
          const query = {device_id: deviceHandel(deviceData)};
          sendRequest('/v1/me/player/previous?' + querystring.stringify(query), 'POST');
      });
      
      on({id: 'javascript.0.Spotify.Player.Repeat_Track', val: true}, obj => 
          sendRequest('/v1/me/player/repeat?state=track'));
      
      on({id: 'javascript.0.Spotify.Player.Repeat_Context', val: true}, obj => 
          sendRequest('/v1/me/player/repeat?state=context'));
      
      on({id: 'javascript.0.Spotify.Player.Repeat_off', val: true}, obj => 
          sendRequest('/v1/me/player/repeat?state=off'));
      
      on({id: 'javascript.0.Spotify.Player.Volume'}, obj => {
          sendRequest('/v1/me/player/volume?volume_percent=' + obj.state.val, 'PUT', '', err => {
              // !err && setState('javascript.0.Spotify.Player.Volume', true/*ack*/)
          });
      });
      
      on({id: 'javascript.0.Spotify.Player.Seek'}, obj => 
          sendRequest('/v1/me/player/seek?position_ms=' + obj.state.val * 1000));
      
      on({id: 'javascript.0.Spotify.Player.Shuffle'}, obj => {
          if (obj.state.val === true) {
              sendRequest('/v1/me/player/shuffle?state=true');
          } else {
              sendRequest('/v1/me/player/shuffle?state=false');
          }
      });
      
      on({id: 'javascript.0.Spotify.Player.TrackId'}, obj => {
          const send = {
              uris: ['spotify:track:' + obj.state.val],
              offset: {
                  position: 0
              }
          };
      
          sendRequest('/v1/me/player/play', 'PUT', JSON.stringify(send));
      });
      
      on({id: 'javascript.0.Spotify.Player.Playlist_ID'}, obj => {
          const send = {
              context_uri: 'spotify:user:' + application.User_ID + ':playlist:' + obj.state.val,
              offset: {
                  position: 1
              }
          };
      
          sendRequest('/v1/me/player/play', 'PUT', JSON.stringify(send));
      });
      
      on({id: 'javascript.0.Spotify.Get_User_Playlists'}, () => GetUsersPlaylist(0));
      
      on({id: 'javascript.0.Spotify.Devices.Get_Devices'}, () => 
          sendRequest('/v1/me/player/devices', 'GET', '', (err, data) => !err && createDevices(data)));
      
      on({id: 'javascript.0.Spotify.Get_Playback_Info'}, () => 
          sendRequest('/v1/me/player', 'GET', '', (err, data) => !err && createPlaybackInfo(data)));
      
      on({id: 'javascript.0.Spotify.Authorization.Authorized'}, obj => {
          if (obj.state.val === true) {
              interval = setInterval(() => {
                  sendRequest('/v1/me/player', 'GET', '', (err, data) => {
                      //console.log('interval'+err)
      
                      if (!err) {
                          createPlaybackInfo(data)
                      } else if (err == 202 || (err == 502) || (err == 401)) {  //202,401 und 502 lassen den Interval  weiter laufen
                          DummyBody = {is_playing: false}; // tritt ein wenn kein Player geöffnet ist
                          createPlaybackInfo(DummyBody)
                      } else {  // andere Fehler stoppen den interval
                          clearInterval(interval);
                          console.warn('Spotify interval gestoppt !');
                      }
      
                  });
      
              }, 5000);
          } else {
              interval && clearInterval(interval);
              interval = null;
          }
      });
      
      // on({id:'javascript.0.Spotify.Authorization.Login'}, function (obj){});
      
      onStop(() => {
          setState('javascript.0.Spotify.Authorization.Authorization_URL', '', true);
          setState('javascript.0.Spotify.Authorization.Authorization_Return_URI', '', true);
          setState('javascript.0.Spotify.Player.TrackId', '', true);
          setState('javascript.0.Spotify.Player.Playlist_ID', '', true);
          setState('javascript.0.Spotify.Authorization.User_ID', '', true);
          setState('javascript.0.Spotify.Authorization.Authorized', false, true);
          interval && clearInterval(interval);
          interval = null;
      }, 1000 /*ms*/);
      
      posted in Skripten / Logik
      L
      Lucky

    Latest posts made by Lucky

    • RE: Neuer Adapter: iobroker.alexa2

      @apollon77:

      GitHub issue bitte … vielleicht geht sowas in der Art ... verspreche aber nichts.

      Und ich weiß auch nicht ob man das unbedingt will. So oft wie alexa bei uns beim Fernsehen oder auch mal nebenher an geht ... hm ...

      Gesendet vom Handy ... `

      ok mach ich !

      wofür man es nutzt ist ja jedem selbst überlassen, man könnte damit auch z.b. das optische Feedback des Echo auf eine Hue Leute auslagern usw..

      posted in Cloud Dienste
      L
      Lucky
    • RE: Neuer Adapter: iobroker.alexa2

      Sehr schöne Arbeit, vielen dank dafür !

      ich würde mir wünschen, (falls möglich) einen Datenpunkt der mit true oder false den jeweiligen Aktivzustand eines Device anzeigt.

      Also wenn ich "Alexa" sage und der Statusring am Gerät leuchtet, das der Datenpunkt auf true wechselt und wider zurück

      Ein nutzen wäre z.b. das kurzfristige Stumm schalten z.b. des Fernsehers oder Verstärkers zum besseren Verständnis des gesprochenen

      posted in Cloud Dienste
      L
      Lucky
    • RE: [Vorlage] Spotify Skript

      bei mir gehts..hast du mal deine Datenpunkte aktualisiert ?

      posted in Skripten / Logik
      L
      Lucky
    • RE: [Vorlage] Spotify Skript

      @twonky:

      Sry, immer noch ein Sting drin 😉 Das war an 2 Stellen. `
      Ach verdammt :roll: jetzt aber! 😄

      posted in Skripten / Logik
      L
      Lucky
    • RE: [Vorlage] Spotify Skript

      Danke! Habs geändert! 😄

      posted in Skripten / Logik
      L
      Lucky
    • RE: [Vorlage] Spotify Skript

      oben jetzt Version 0.5.3 !

      Stabilität verbessert

      Tacks jetzt auch als Listenstring

      posted in Skripten / Logik
      L
      Lucky
    • RE: [gelöst] HTTP Post JSON Daten
      var request = require('request');
      
          var options = {
          url: 'http://192.168.178.10/setdata.php',
          method: 'POST',
          form:myObj 
      };
      
      request(options,function (error, response, body){
      
      //....
      
      });
      
      
      posted in Skripten / Logik
      L
      Lucky
    • RE: [Vorlage] Spotify Skript

      neue Versionen gibt es ab sofort nur noch im ersten Post auf Seite 1 !!!
      @wendy2702:

      Oder kann man eventuell eine solche Funktion in das Script einbauen, also ein Datenpunkt in dem die Aktuelle Playlist steht? `

      ist in Version 0.5.1 eingebaut ! teste mal

      @wendy2702:

      Heute morgen kleiner Rückschlag…nichts geht mehr beim starten von Spotify über VIS und das steht im log:

      javascript.0	2018-02-04 11:31:31.192	error	script.js.Spotify.Spotify_Controll_v050: Fehler 202 Function Refresh_Token
      javascript.0	2018-02-04 11:31:31.192	error	script.js.Spotify.Spotify_Controll_v050: FEHLER BEIM ERNEUTEN DATEN ANFORDERN !
      javascript.0	2018-02-04 11:31:31.049	info	script.js.Spotify.Spotify_Controll_v050: Token Saved!
      javascript.0	2018-02-04 11:31:31.048	info	script.js.Spotify.Spotify_Controll_v050: neuer Token eingetroffen
      javascript.0	2018-02-04 11:31:30.895	info	script.js.Spotify.Spotify_Controll_v050: Token wird erneut angefordert !
      javascript.0	2018-02-04 11:31:30.893	info	script.js.Spotify.Spotify_Controll_v050: Access Token Abgelaufen!!
      ```` `  
      

      202 bedeutet das der Server die Anfrage angenommen hat, aber sie zur zeit nicht verarbeiten kann, in diesem Fall die Aktion nochmal ausfühen

      ist aber auch in 0.5.1 verbessert !

      posted in Skripten / Logik
      L
      Lucky
    • RE: [Vorlage] Spotify Skript

      ups :lol:

      Edit:

      ehrlich gesagt überlege ich noch wie ich das am besten anstelle, es würde zwar gehen einen Datenpunkt als Number mit den Playlisten als States anzulegen, um diese zur Laufzeit zu ändern würde man aber die Option 'SetObjekt' aktivieren müssen, das würde es für ungeübte wieder schwieriger machen das Skript zum laufen zu bringen.

      alternativ könnte man einen Datenpunkt als String anlegen der die Namen der Playlisten enthält und dazu einen Nummerischen Index, würde dir das helfen ?

      posted in Skripten / Logik
      L
      Lucky
    • RE: [Vorlage] Spotify Skript

      ok, hatte Default noch drin, habe jetzt JS 3.6.3 bis lang läufts

      posted in Skripten / Logik
      L
      Lucky
    Community
    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
    The ioBroker Community 2014-2023
    logo