|
1 | | -cloudconvert-node |
2 | | -======================= |
| 1 | +# cloudconvert-node |
3 | 2 |
|
4 | | -> This is the official node.js SDK v1 or the [CloudConvert](https://cloudconvert.com/api/v1) _API v1_. |
5 | | -> For API v2, please use [v2 branch](https://github.com/cloudconvert/cloudconvert-node/tree/v2) (Beta) of this repository. |
6 | 3 |
|
| 4 | +> This is the official Node.js SDK v2 (Beta) for the [CloudConvert](https://cloudconvert.com/api/v2) _API v2_. |
| 5 | +> For API v1, please use [v1 branch](https://github.com/cloudconvert/cloudconvert-node/tree/v1) of this repository. |
7 | 6 |
|
8 | 7 | [](https://travis-ci.org/cloudconvert/cloudconvert-node) |
9 | 8 | [](https://www.npmjs.com/package/cloudconvert) |
10 | 9 | [](https://www.npmjs.com/package/cloudconvert) |
11 | 10 |
|
12 | | -Installation |
13 | | -------------------- |
| 11 | +## Installation |
14 | 12 |
|
15 | | - npm install --save cloudconvert |
| 13 | + |
| 14 | + npm install --save cloudconvert/cloudconvert-node#v2 |
16 | 15 |
|
| 16 | +Load as ESM module: |
| 17 | + |
| 18 | +```js |
| 19 | +import CloudConvert from 'cloudconvert'; |
| 20 | +``` |
| 21 | + |
| 22 | +... or via require: |
| 23 | +```js |
| 24 | +const CloudConvert = require('cloudconvert'); |
| 25 | +``` |
| 26 | + |
| 27 | + |
| 28 | +## Creating Jobs |
17 | 29 |
|
18 | | -Quickstart |
19 | | -------------------- |
20 | 30 | ```js |
21 | | -var fs = require('fs'); |
22 | | -var cloudconvert = new (require('cloudconvert'))('your_api_key'); |
23 | | - |
24 | | -fs.createReadStream('tests/input.png') |
25 | | -.pipe(cloudconvert.convert({ |
26 | | - inputformat: 'png', |
27 | | - outputformat: 'jpg', |
28 | | - converteroptions: { |
29 | | - quality : 75, |
| 31 | +import CloudConvert from 'cloudconvert'; |
| 32 | + |
| 33 | +const cloudConvert = new CloudConvert('api_key'); |
| 34 | + |
| 35 | +let job = await cloudConvert.jobs.create({ |
| 36 | + 'tasks': { |
| 37 | + 'import-my-file': { |
| 38 | + 'operation': 'import/url', |
| 39 | + 'url': 'https://my-url' |
| 40 | + }, |
| 41 | + 'convert-my-file': { |
| 42 | + 'operation': 'convert', |
| 43 | + 'input': 'import-my-file', |
| 44 | + 'output_format': 'pdf', |
| 45 | + 'some_other_option': 'value' |
| 46 | + }, |
| 47 | + 'export-my-file': { |
| 48 | + 'operation': 'export/url', |
| 49 | + 'input': 'convert-my-file' |
| 50 | + } |
30 | 51 | } |
31 | | - })) |
32 | | -.pipe(fs.createWriteStream('out.jpg')) |
33 | | -.on('finish', function() { |
34 | | - console.log('Done!'); |
35 | 52 | }); |
36 | 53 | ``` |
37 | | -You can use the [CloudConvert API Console](https://cloudconvert.com/apiconsole) to generate ready-to-use JS code snippets using this wrapper. |
38 | | - |
| 54 | +You can use the [CloudConvert Job Builder](https://cloudconvert.com/api/v2/jobs/builder) to see the available options for the various task types. |
39 | 55 |
|
| 56 | +## Downloading Files |
40 | 57 |
|
41 | | -The manual way |
42 | | -------------------- |
43 | | -``cloudconvert.convert()`` creates a Process, start it and waits until it completes. In some cases it might be necessary that you do this steps seperately, as the following example shows: |
| 58 | +CloudConvert can generate public URLs for using `export/url` tasks. You can use these URLs to download output files. |
44 | 59 |
|
45 | 60 | ```js |
| 61 | +job = await cloudConvert.jobs.wait(job.id); // Wait for job completion |
46 | 62 |
|
47 | | -var fs = require('fs'); |
48 | | -var cloudconvert = new (require('cloudconvert'))('your_api_key'); |
49 | | - |
50 | | -// create the process. see https://cloudconvert.com/apidoc#create |
51 | | -cloudconvert.createProcess({inputformat: 'png', outputformat: 'pdf'}, function(err, conversionProcess) { |
52 | | - |
53 | | - if(err) { |
54 | | - console.error('CloudConvert Process creation failed: ' + err); |
55 | | - } else { |
56 | | - |
57 | | - // start the process. see https://cloudconvert.com/apidoc#create |
58 | | - conversionProcess.start({ |
59 | | - outputformat: 'jpg', |
60 | | - converteroptions: { |
61 | | - quality : 75, |
62 | | - }, |
63 | | - input: 'upload' |
64 | | - }, function (err, conversionProcess) { |
65 | | - |
66 | | - if (err) { |
67 | | - console.error('CloudConvert Process start failed: ' + err); |
68 | | - } else { |
69 | | - |
70 | | - // upload the input file. see https://cloudconvert.com/apidoc#upload |
71 | | - conversionProcess.upload(fs.createReadStream('tests/input.png'), null, function (err, conversionProcess) { |
72 | | - |
73 | | - if (err) { |
74 | | - console.error('CloudConvert Process upload failed: ' + err); |
75 | | - } else { |
76 | | - // wait until the process is finished (or completed with an error) |
77 | | - conversionProcess.wait(function (err, conversionProcess) { |
78 | | - if (err) { |
79 | | - console.error('CloudConvert Process failed: ' + err); |
80 | | - } else { |
81 | | - console.log('Done: ' + conversionProcess.data.message); |
82 | | - |
83 | | - // download it |
84 | | - conversionProcess.download(fs.createWriteStream("out.jpg"), null, function (err, conversionProcess) { |
85 | | - if (err) { |
86 | | - console.error('CloudConvert Process download failed: ' + err); |
87 | | - } else { |
88 | | - console.log('Downloaded to out.jpg'); |
89 | | - } |
90 | | - }); |
91 | | - } |
92 | | - |
93 | | - }); |
94 | | - } |
95 | | - }); |
96 | | - |
97 | | - |
98 | | - } |
99 | | - }); |
100 | | - } |
| 63 | +const exportTask = job.tasks.filter(task => task.operation === 'export/url' && task.status === 'finished')[0]; |
| 64 | +const file = exportTask.result.files[0]; |
| 65 | + |
| 66 | +const writeStream = fs.createWriteStream('./out/' + file.filename); |
101 | 67 |
|
| 68 | +http.get(file.url, function(response) { |
| 69 | + response.pipe(writeStream); |
102 | 70 | }); |
103 | | -``` |
104 | 71 |
|
| 72 | +await new Promise((resolve, reject) => { |
| 73 | + writeStream.on('finish', resolve); |
| 74 | + writeStream.on('error', reject); |
| 75 | +}); |
| 76 | +``` |
105 | 77 |
|
106 | | -Download of multiple output files |
107 | | -------------------- |
| 78 | +## Uploading Files |
108 | 79 |
|
109 | | -In some cases it might be possible that there are multiple output files (e.g. converting a multi-page PDF to JPG). You can download them all to one directory using the ``downloadAll()`` method. |
| 80 | +Uploads to CloudConvert are done via `import/upload` tasks (see the [docs](https://cloudconvert.com/api/v2/import#import-upload-tasks)). This SDK offers a convenient upload method: |
110 | 81 |
|
111 | 82 | ```js |
112 | | -var fs = require('fs'); |
113 | | -var cloudconvert = new (require('cloudconvert'))('your_api_key'); |
114 | | - |
115 | | -fs.createReadStream('tests/input.pdf').pipe(cloudconvert.convert({ |
116 | | - inputformat: 'pdf', |
117 | | - outputformat: 'jpg', |
118 | | - converteroptions: { |
119 | | - page_range : '1-3', |
| 83 | +const job = await cloudConvert.jobs.create({ |
| 84 | + 'tasks': { |
| 85 | + 'upload-my-file': { |
| 86 | + 'operation': 'import/upload' |
| 87 | + }, |
| 88 | + // ... |
120 | 89 | } |
121 | | -}).on('error', function(err) { |
122 | | - console.error('Failed: ' + err); |
123 | | -}).on('finished', function(data) { |
124 | | - console.log('Done: ' + data.message); |
125 | | - this.downloadAll('tests/'); |
126 | | -}).on('downloaded', function(destination) { |
127 | | - console.log('Downloaded to: ' + destination.path); |
128 | | -}).on('downloadedAll', function(path) { |
129 | | - console.log('Downloaded all to: ' + path); |
130 | | -})); |
| 90 | +}); |
131 | 91 |
|
132 | | -``` |
| 92 | +const uploadTask = job.tasks.filter(task => task.name === 'upload-my-file')[0]; |
| 93 | + |
| 94 | +const inputFile = fs.createReadStream('./file.pdf'); |
133 | 95 |
|
| 96 | +await cloudConvert.tasks.upload(uploadTask, inputFile); |
| 97 | +``` |
134 | 98 |
|
135 | | -Events |
136 | | ------------------ |
137 | | -The ``Process``object emits the following Events: |
138 | 99 |
|
139 | | -Event|Description |
140 | | -------|------------ |
141 | | -``error``| The conversion failed. You should always listen for this event: If there is no listener, the error will be thrown and might crash your application. |
142 | | -``finished``| The conversion is finished (but **not** yet downloaded). This event will only be emitted, if you do ``wait()`` for the process. (``convert()`` does this automatically for you). |
143 | | -``progress``|Emitted every second with the current progress of the conversion. This event will only be emitted, if you do ``wait()`` for the process. |
144 | | -``uploaded``|The input file was uploaded. |
145 | | -``started``|The process was started. |
146 | | -``downloaded``|The output file was downloaded. |
147 | | -``downloadedAll``|Emitted after completed ``downloadAll()``. Every single file will emit a seperate ``downloaded`` event. |
| 100 | +## Websocket Events |
148 | 101 |
|
| 102 | +The node SDK can subscribe to events of the [CloudConvert socket.io API](https://cloudconvert.com/api/v2/socket#socket). |
149 | 103 |
|
150 | | -Error handling |
151 | | ------------------ |
152 | | -The following example shows how to catch the different error types which can occur at conversions: |
153 | 104 |
|
154 | 105 | ```js |
155 | | -var fs = require('fs'); |
156 | | -var cloudconvert = new (require('cloudconvert'))('your_api_key'); |
157 | | - |
158 | | -fs.createReadStream('tests/input.pdf').pipe(cloudconvert.convert({ |
159 | | - inputformat: 'pdf', |
160 | | - outputformat: 'jpg', |
161 | | -}).on('error', function(err) { |
162 | | - switch (err.code) { |
163 | | - case 400: |
164 | | - console.error('Something with your request is wrong: ' + err); |
165 | | - break; |
166 | | - case 422: |
167 | | - console.error('Conversion failed, maybe because of a broken input file: ' + err); |
168 | | - break; |
169 | | - case 503: |
170 | | - console.error('API temporary unavailable: ' + err); |
171 | | - console.error('We should retry the conversion in ' + err.retryAfter + ' seconds'); |
172 | | - break; |
173 | | - default: |
174 | | - // network problems, etc.. |
175 | | - console.error('Something else went wrong: ' + err); |
176 | | - break; |
177 | | - } |
178 | | -}).on('finished', function(data) { |
179 | | - console.log('Done: ' + data.message); |
180 | | -})); |
| 106 | +const job = await cloudConvert.jobs.create({ ... }); |
| 107 | + |
| 108 | +// Events for the job |
| 109 | +// Available events: created, updated, finished, error, deleted |
| 110 | +cloudConvert.jobs.subscribeEvent(job.id, 'finished', event => { |
| 111 | + // Job has finished |
| 112 | + console.log(event.job); |
| 113 | +}); |
| 114 | + |
| 115 | +// Events for all tasks of the job |
| 116 | +// Available events: created, updated, finished, error, deleted |
| 117 | +cloudConvert.jobs.subscribeTaskEvent(job.id, 'finished', event => { |
| 118 | + // Task has finished |
| 119 | + console.log(event.task); |
| 120 | +}); |
| 121 | +``` |
181 | 122 |
|
| 123 | +When you don't want to receive any events any more you should close the socket: |
| 124 | +```js |
| 125 | +cloudConvert.socket.close(); |
182 | 126 | ``` |
183 | 127 |
|
| 128 | +## Webhook Signing |
| 129 | + |
| 130 | +The node SDK allows to verify webhook requests received from CloudConvert. |
| 131 | + |
| 132 | +```js |
| 133 | +const payloadString = '...'; // The JSON string from the raw request body. |
| 134 | +const signature = '...'; // The value of the "CloudConvert-Signature" header. |
| 135 | +const signingSecret = '...'; // You can find it in your webhook settings. |
184 | 136 |
|
| 137 | +const isValid = cloudConvert.webhooks.verify(payloadString, signature, signingSecret); // returns true or false |
| 138 | +``` |
185 | 139 |
|
186 | | -How to run tests? |
187 | | ------------------ |
| 140 | +## Unit Tests |
188 | 141 |
|
189 | 142 | Tests are based on mocha: |
190 | 143 |
|
191 | | - git https://github.com/cloudconvert/cloudconvert-node.git |
192 | | - cd cloudconvert-node |
193 | | - npm install -d |
194 | | - npm test |
| 144 | + npm run test |
195 | 145 |
|
196 | 146 |
|
197 | 147 |
|
198 | | -How to run integration tests? |
199 | | ------------------ |
| 148 | +## Integration Tests |
200 | 149 |
|
201 | | -By default, mocha does not run integration tests against the real CloudConvert API. To run integration tests, use the `API_KEY` enviroment variable and run the integration tests: |
| 150 | + npm run test-integration |
| 151 | + |
| 152 | + |
| 153 | +By default, this runs the integration tests against the Sandbox API with an official CloudConvert account. If you would like to use your own account, you can set your API key using the `CLOUDCONVERT_API_KEY` enviroment variable. In this case you need to whitelist the following MD5 hashes for Sandbox API (using the CloudConvert dashboard). |
202 | 154 |
|
203 | | - git https://github.com/cloudconvert/cloudconvert-node.git |
204 | | - cd cloudconvert-node |
205 | | - npm install -d |
206 | | - export API_KEY="your_api_key" |
207 | | - npm run integration |
| 155 | + 53d6fe6b688c31c565907c81de625046 input.pdf |
| 156 | + 99d4c165f77af02015aa647770286cf9 input.png |
208 | 157 |
|
209 | 158 |
|
210 | | -Resources |
211 | | ---------- |
| 159 | +## Resources |
212 | 160 |
|
213 | | -* [API Documentation](https://cloudconvert.com/api) |
214 | | -* [Conversion Types](https://cloudconvert.com/formats) |
| 161 | +* [API v2 Documentation](https://cloudconvert.com/api/v2) |
215 | 162 | * [CloudConvert Blog](https://cloudconvert.com/blog) |
0 commit comments