]> BookStack Code Mirror - api-scripts/blob - node-upload-attachment/index.js
Added node-based file attachment upload example
[api-scripts] / node-upload-attachment / index.js
1 // Libraries used
2 const fs = require('fs');
3 const path = require('path');
4 const axios = require('axios');
5 const FormData = require('form-data');
6
7 // BookStack API variables
8 // Uses values on the environment unless hardcoded
9 // To hardcode, add values to the empty strings in the below.
10 const bookStackConfig = {
11     base_url: '' || process.env.BS_URL,
12     token_id: '' || process.env.BS_TOKEN_ID,
13     token_secret: '' || process.env.BS_TOKEN_SECRET,
14 };
15
16 // Script Logic
17 ////////////////
18
19 // Check arguments provided
20 if (process.argv.length < 4) {
21     console.error('Both <page_id> and <file_path> arguments need to be provided');
22     return;
23 }
24
25 // Get arguments passed via command
26 const [_exec, _script, pageId, filePath] = process.argv;
27
28 // Check the given file exists
29 if (!fs.existsSync(filePath)) {
30     console.error(`File at "${filePath}" could not be found`);
31     return;
32 }
33
34 // Get the file name and create a read stream from the given file
35 const fileStream = fs.createReadStream(filePath);
36 const fileName = path.basename(filePath);
37
38 // Gather our form data with all the required bits
39 const formPostData = new FormData();
40 formPostData.append('file', fileStream);
41 formPostData.append('name', fileName);
42 formPostData.append('uploaded_to', pageId);
43
44 // Create an axios instance for our API
45 const api = axios.create({
46     baseURL: bookStackConfig.base_url.replace(/\/$/, '') + '/api/',
47     timeout: 30000,
48     headers: { 'Authorization' : `Token ${bookStackConfig.token_id}:${bookStackConfig.token_secret}` },
49 });
50
51 // Wrap the rest of our code in an async function, so we can await within.
52 (async function() {
53
54     // Upload the file using the gathered data
55     // Sends it with a "Content-Type: multipart/form-data" with the post
56     // body formatted as multipart/form-data content, with the "FormData" object
57     // from the "form-data" library does for us.
58     const {data: attachment} = await api.post('/attachments', formPostData, {
59         headers: formPostData.getHeaders(),
60     });
61
62     // Output the results
63     console.info(`File successfully uploaded to page ${pageId}.`);
64     console.info(` - Attachment ID: ${attachment.id}`);
65     console.info(` - Attachment Name: ${attachment.name}`);
66
67 })().catch(err => {
68     // Handle API errors
69     if (err.response) {
70         console.error(`Request failed with status ${err.response.status} [${err.response.statusText}]`);
71         console.error(JSON.stringify(err.response.data));
72         return;
73     }
74     // Output all other errors
75     console.error(err)
76 });