It now downloads a file from an api and saves it under the original filename to your desired save path.
Like I said, it is based on Ken’s extension, which was based on node request. Which is deprecated, I am not sure if this is an issue or not. If it is an issue please suggest alternatives.
Right now I only made an option to change the url and add headers to the request. Because that is what I needed. If you need params or body or something, please comment below.
Also, right now it does not catch errors or response codes. I haven’t figured out how to properly do that, yet.
I actually did run into issues with the request library a while back. I can’t recall the specifics, but it was obviously time to move on from that library.
Here is a version of the action that now uses Axios:
exports.write_binary = async function (options) {
//retrieves a file via remote http request and saves the file to the local server
//names the file using a uuid
//for converting file paths provided in UI
const { toSystemPath } = require('../../../lib/core/path');
//uuid package
const { v4: uuidv4 } = require('uuid');
//required for retrieving
const axios = require('axios')
//and saving file
const fs = require('fs-extra');
//convert the user local_path provided in the API action to useable in the module
let path = toSystemPath(this.parseRequired(this.parse(options.local_path), 'string', 'fs.exists: path is required.'));
//evaluate the data binding for remoteURL
let remoteURL = this.parseRequired(options.file_url, 'string', 'parameter file_url is required.');
//generate uuid
let uuid = uuidv4(); // ⇨ '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed'
//set the filename
let file_name = path + '/' + uuid;
async function downloadImage() {
const url = remoteURL;
const writer = fs.createWriteStream(file_name)
const response = await axios({
url,
method: 'GET',
responseType: 'stream'
})
response.data.pipe(writer)
return new Promise((resolve, reject) => {
writer.on('finish', resolve)
writer.on('error', reject)
})
};
await downloadImage();
//return the file_name
return { "file_name": uuid }
};
Just playing with your extension as a test and to learn more but having a problem with the URL field.
If I use a static url (like your screenshot) the file is downloaded from the given url but if I use a dynamic variable (e.g. the response from an API with the url of the file the action fails - “Error: parameter value is required.”
This is the error detailed in the js for the URL field.
I had assumed I could use a variable/dynamic value (which is a string of a valid url) given there is a data binding icon:
I haven’t looked into this extension for a while, but I expect to be needing it in the coming weeks. I will report back with my findings and fixes, if needed.
I have done a little more work on this today and found, as usual, the issue was with my implementation
The dynamic value I was retrieving from my API call “favicon.data[0].$value” which was provided by the Wappler data binding selection was not actually giving me a value, it should have been “favicon.data[0]”
It now works and my day of trying to find an error has taught me loads about extensions
Here is an updated version that uses axios, like @mebeingken suggested.
Also an option to provide a custom filename, since some API’s do not return desirable filenames. GetFileFromAPIV04.zip (1.7 KB)
This extension seems to work well with image downloads but there seems to be an issue with urls with parameters which you would need for the api call for qr codes.
Added a new input “Force Extension” which, as the name suggests, forces the file download extension to the input value. For force extension to work a custom filename must also be specified.
Great job working on this extension! (I was on a camping trip ) @Hyperbytes, do you mind if I use your file in the original post? It seems like an improved version of the extension.