Downloading songs and podcast episodes from Spotify

I am trying to build a workflow step where I download a specific song or podcast episode from Spotify. There is some npm packages out there that seem to be able to do that but I am struggling to integrate them:

It seems that on the one authenticating/access token might be one issue even though I connected my spotify account as well as certain packages such as ffmpeg not being there…

Any help, appreciated.

1 Like

Hi @domdewom

First off, welcome to the Pipedream community. Happy to have you!

Can you provide more details like the error specifically that you’re seeing?

1 Like

This is the error I am getting now:

TypeError
Error While writing to File: ./spotifydl-core.mp3

This is the code step:

import { axios } from "@pipedream/platform"; 
import fs from "fs-extra";
import { Spotify } from "spotifydl-core";

import ffmpeg from "fluent-ffmpeg"; 
import ffmpegInstaller from "@ffmpeg-installer/ffmpeg";


export default defineComponent({
  props: {
    spotify: {
      type: 'app',
      app: 'spotify'
    }
  },

  async run({ steps, $ }) {

    console.log(this.spotify.$auth)
    const accessToken = this.spotify.$auth;

    const credentials = { 
      clientId: 'xxx', //your own clientId
      clientSecret: 'xxx' //your own clientSecret'
    }

    const spotifydl = new Spotify(credentials)
     
    
    // Declaring the respective url in 'links' object 
    const links = {
      artist: steps.trigger.event.track.artists[0].name, 
      album: steps.trigger.event.track.album.name,
      song: steps.trigger.event.track.external_urls.spotify 
    };

    try {
        console.log(ffmpegInstaller);
        ffmpeg.setFfmpegPath(ffmpegInstaller.path, {timeout: 60000});

        const tmpPath = `/tmp/song.mp3`
        const mime = `mp3`

        const data = await spotifydl.getTrack(links.song) 
        console.log('Downloading: ', data.name, 'by:', data.artists.join(' ')) 
        
        const song = await spotifydl.downloadTrack(links.song, tmpPath)

        fs.writeFileSync(tmpPath, song)
           
        // Create a results object
        const results = {
        "tmpPath": tmpPath,
        "mimetype": mime
        }
        
        return results
    } catch (error) {
        // Log the error and return an error message or handle the error as required
        console.log('ERROR:')
        console.error(error);
        throw error;
    }
  }
})

Essentially I would like to be able to download songs/episodes from Spotify with my premium Spotify account. I am not entirely sure What is happening now? Initially it didnt recognize ffmpeg, apparently the ffmpeg.setFfmpegPath(ffmpegInstaller.path) fixes this…

The root of the filesystem is not accessible for writing, it looks like even though have you have specified filePath to use a the /tmp directory, that your path is ignored by the library.

Perhaps try double checking the documentation for specifying a path on this library, I suspect that there’s either a bug in the library not respecting paths properly or the option is in a slightly different place.

I just realized I might have used the wrong ’ character for the path:

const tmpPath = `/tmp/song.mp3`
const mime = `mp3`

to

const tmpPath = '/tmp/song.mp3'
const mime = 'mp3'

Interestingly enough, now I am getting a different error. So for songs it seems to work but for podcast episodes (which is my actual goal) it doesnt seem to work:

WebapiRegularError
An error occurred while communicating with Spotify’s Web API. Details: Non existing id: ‘spotify:track:0PxnFMpnXVCwkDHY8YT3FV’.

DETAILS

    at null._toError (/tmp/__pdg__/dist/code/d197d6afc3d3393f22f3a3b9a6a9ad4bb13739519c247bf1d6e056693c67a6e0/node_modules/.pnpm/spotify-web-api-node@5.0.2/node_modules/spotify-web-api-node/src/http-manager.js:39:12)
    at null.null (/tmp/__pdg__/dist/code/d197d6afc3d3393f22f3a3b9a6a9ad4bb13739519c247bf1d6e056693c67a6e0/node_modules/.pnpm/spotify-web-api-node@5.0.2/node_modules/spotify-web-api-node/src/http-manager.js:71:25)
    at Request.Request.callback (/tmp/__pdg__/dist/code/d197d6afc3d3393f22f3a3b9a6a9ad4bb13739519c247bf1d6e056693c67a6e0/node_modules/.pnpm/superagent@6.1.0/node_modules/superagent/lib/node/index.js:905:3)
    at null.null (/tmp/__pdg__/dist/code/d197d6afc3d3393f22f3a3b9a6a9ad4bb13739519c247bf1d6e056693c67a6e0/node_modules/.pnpm/superagent@6.1.0/node_modules/superagent/lib/node/index.js:1127:20)
    at IncomingMessage.null (/tmp/__pdg__/dist/code/d197d6afc3d3393f22f3a3b9a6a9ad4bb13739519c247bf1d6e056693c67a6e0/node_modules/.pnpm/superagent@6.1.0/node_modules/superagent/lib/node/parsers/json.js:22:7)
    at Stream.emit (events.js:400:28)
    at Unzip.null (/tmp/__pdg__/dist/code/d197d6afc3d3393f22f3a3b9a6a9ad4bb13739519c247bf1d6e056693c67a6e0/node_modules/.pnpm/superagent@6.1.0/node_modules/superagent/lib/node/unzip.js:53:12)
    at Unzip.emit (events.js:400:28)
    at null.endReadableNT (internal/streams/readable.js:1333:12)
    at process.processTicksAndRejections (internal/process/task_queues.js:82:21)

Digging into the above error, I actually think it has something to do with the spotifydl-core library. Given it works for songs but doesnt work for podcast episodes, it seems to assume each spotify url is a track and tries to make a spotify web api call up using spotify:track:xxx instead of spotify:episode:xxx…

Not sure how to fix this. Probably would need to go to the original npm library? Or any other suggestions?