FTP file uploader
Pricing
Pay per usage
Go to Store
FTP file uploader
Performs a simple upload of an array of files to an FTP.
0.0 (0)
Pricing
Pay per usage
0
Total users
7
Monthly users
2
Last modified
3 years ago
Dockerfile
# First, specify the base Docker image. You can read more about# the available images at https://sdk.apify.com/docs/guides/docker-images# You can also use any other image from Docker Hub.FROM apify/actor-node:16
# Second, copy just package.json and package-lock.json since those are the only# files that affect "npm install" in the next step, to speed up the build.COPY package*.json ./
# Install NPM packages, skip optional and development dependencies to# keep the image small. Avoid logging too much and print the dependency# tree for debuggingRUN npm --quiet set progress=false \ && npm install --only=prod --no-optional \ && echo "Installed NPM packages:" \ && (npm list || true) \ && echo "Node.js version:" \ && node --version \ && echo "NPM version:" \ && npm --version
# Next, copy the remaining files and directories with the source code.# Since we do this after NPM install, quick build will be really fast# for most source file changes.COPY . ./
# Optionally, specify how to launch the source code of your actor.# By default, Apify's base Docker images define the CMD instruction# that runs the Node.js source code using the command specified# in the "scripts.start" section of the package.json file.# In short, the instruction looks something like this:## CMD npm start
INPUT_SCHEMA.json
{ "title": "FTP file uploader", "type": "object", "schemaVersion": 1, "properties": { "username": { "title": "Username", "type": "string", "editor": "textfield", "description": "FTP username" }, "password": { "title": "Password", "type": "string", "editor": "textfield", "description": "FTP password" }, "host": { "title": "Host", "type": "string", "editor": "textfield", "description": "FTP host" }, "port": { "title": "Port", "type": "integer", "prefill": 21, "default": 21, "description": "FTP port" }, "folder": { "title": "FTP folder", "type": "string", "editor": "textfield", "prefill": "/", "default": "/", "description": "FTP folder" }, "fileUrls": { "title": "File URLs", "type": "array", "editor": "json", "prefill": [], "description": "File URLs" } }, "required": ["username", "password", "host", "fileUrls"]}
main.js
1const fs = require('fs');2const Apify = require('apify');3const FtpClient = require('ftp-client');4
5const connect = (ftpClient) => new Promise((resolve, reject) => {6 ftpClient.connect((err) => {7 if(err){reject(err);}8 else{resolve();}9 });10});11
12const upload = (ftpClient, files, outFolder) => new Promise((resolve) => {13 ftpClient.upload(files, outFolder || '/', {14 baseDir: outFolder || '/',15 overwrite: 'older'16 }, function (result) {17 resolve(result);18 });19});20
21Apify.main(async () => {22 const input = await Apify.getInput();23 if(!input.host){throw new Error('Missing "host" attribute in INPUT!');}24 if(!input.username){throw new Error('Missing "username" attribute in INPUT!');}25 if(!input.password){throw new Error('Missing "password" attribute in INPUT!');}26 if(!input.fileUrls){throw new Error('Missing "fileUrls" attribute in INPUT!');}27 28 const config = {29 host: input.host,30 port: input.port || 21,31 user: input.username,32 password: input.password33 };34
35 const options = {36 overwrite: 'older',37 logging: 'basic'38 };39
40 const client = new FtpClient(config, options);41 await connect(client);42
43 const fileNames = [];44 for(const url of input.fileUrls){45 const response = await Apify.utils.requestAsBrowser({url});46 const data = response.rawBody;47 if(data){48 const fileName = url.slice(url.lastIndexOf('/') + 1);49 fs.writeFileSync(fileName, data);50 fileNames.push(fileName)51 }52 }53 await upload(client, fileNames, input.folder);54});
package.json
{ "name": "ftp-upload", "version": "0.0.1", "dependencies": { "apify": "^2.0.2", "ftp-client": "^0.2.2" }, "scripts": { "start": "node main.js" }, "author": "Petr Čermák"}