Skip to content

Commit 717cd0a

Browse files
17949 app luminpdf (#18023)
* [APP] luminpdf #17949 Actions - Get Signature Request - Send Signature Request - Cancel Signature Request - Download File as File URL - Download File - Get User Information * pnpm update * pnpm update * Update file descriptions in send-signature-request to reflect correct file type and ensure useTextTags is appended as a string * Refactor custom email handling in send-signature-request to use nested object structure for better clarity and update label for custom email title * Update components/lumin_pdf/actions/send-signature-request/send-signature-request.mjs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Add signers field to send-signature-request for enhanced signature request customization --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent ad1f8bf commit 717cd0a

File tree

10 files changed

+453
-8
lines changed

10 files changed

+453
-8
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import luminPdf from "../../lumin_pdf.app.mjs";
2+
3+
export default {
4+
key: "lumin_pdf-cancel-signature-request",
5+
name: "Cancel Signature Request",
6+
description: "Cancel a signature request. [See the documentation](https://developers.luminpdf.com/api/cancel-signature-request/)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
luminPdf,
11+
alert: {
12+
type: "alert",
13+
alertType: "info",
14+
content: "This action only works for signature requests that were created via API.",
15+
},
16+
signatureRequestId: {
17+
propDefinition: [
18+
luminPdf,
19+
"signatureRequestId",
20+
],
21+
},
22+
},
23+
async run({ $ }) {
24+
const response = await this.luminPdf.cancelSignatureRequest({
25+
$,
26+
signatureRequestId: this.signatureRequestId,
27+
});
28+
29+
$.export("$summary", `Successfully cancelled signature request with ID: ${this.signatureRequestId}`);
30+
return response;
31+
},
32+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import luminPdf from "../../lumin_pdf.app.mjs";
2+
3+
export default {
4+
name: "Download File as File URL",
5+
version: "0.0.1",
6+
key: "lumin_pdf-download-file-as-file-url",
7+
description: "Get a download URL for a file. [See the documentation](https://developers.luminpdf.com/api/download-file-as-file-url/)",
8+
type: "action",
9+
props: {
10+
luminPdf,
11+
signatureRequestId: {
12+
propDefinition: [
13+
luminPdf,
14+
"signatureRequestId",
15+
],
16+
},
17+
},
18+
async run({ $ }) {
19+
const response = await this.luminPdf.downloadFileAsFileUrl({
20+
$,
21+
signatureRequestId: this.signatureRequestId,
22+
});
23+
24+
$.export("$summary", `Successfully retrieved download URL for signature request with ID: ${this.signatureRequestId}`);
25+
return response;
26+
},
27+
};
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import fs from "fs";
2+
import stream from "stream";
3+
import { promisify } from "util";
4+
import luminPdf from "../../lumin_pdf.app.mjs";
5+
6+
export default {
7+
name: "Download File",
8+
version: "0.0.1",
9+
key: "lumin_pdf-download-file",
10+
description: "Download a file directly. [See the documentation](https://developers.luminpdf.com/api/download-file/)",
11+
type: "action",
12+
props: {
13+
luminPdf,
14+
signatureRequestId: {
15+
propDefinition: [
16+
luminPdf,
17+
"signatureRequestId",
18+
],
19+
},
20+
filePath: {
21+
type: "string",
22+
label: "File Path",
23+
description: "The path to the file you'd like to download eg. `/tmp/file.pdf`",
24+
},
25+
syncDir: {
26+
type: "dir",
27+
accessMode: "write",
28+
sync: true,
29+
},
30+
},
31+
async run({ $ }) {
32+
const response = await this.luminPdf.downloadFile({
33+
$,
34+
signatureRequestId: this.signatureRequestId,
35+
responseType: "stream",
36+
});
37+
38+
const pipeline = promisify(stream.pipeline);
39+
await pipeline(response, fs.createWriteStream(this.filePath));
40+
41+
$.export("$summary", `Successfully downloaded file for signature request with ID: ${this.signatureRequestId}`);
42+
return {
43+
filePath: this.filePath,
44+
};
45+
},
46+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import luminPdf from "../../lumin_pdf.app.mjs";
2+
3+
export default {
4+
key: "lumin_pdf-get-signature-request",
5+
name: "Get Signature Request",
6+
description: "Get details of a specific signature request. [See the documentation](https://developers.luminpdf.com/api/get-signature-request/)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
luminPdf,
11+
signatureRequestId: {
12+
propDefinition: [
13+
luminPdf,
14+
"signatureRequestId",
15+
],
16+
},
17+
},
18+
async run({ $ }) {
19+
const response = await this.luminPdf.getSignatureRequest({
20+
$,
21+
signatureRequestId: this.signatureRequestId,
22+
});
23+
24+
$.export("$summary", `Successfully retrieved signature request with ID: ${this.signatureRequestId}`);
25+
return response;
26+
},
27+
};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import luminPdf from "../../lumin_pdf.app.mjs";
2+
3+
export default {
4+
name: "Get User Information",
5+
version: "0.0.1",
6+
key: "lumin_pdf-get-user-information",
7+
description: "Get information about the current authenticated user. [See the documentation](https://developers.luminpdf.com/api/get-user-information/)",
8+
type: "action",
9+
props: {
10+
luminPdf,
11+
},
12+
async run({ $ }) {
13+
const response = await this.luminPdf.getUserInformation({
14+
$,
15+
});
16+
17+
$.export("$summary", `Successfully retrieved user information for ${response.user.email || response.user.id}`);
18+
return response;
19+
},
20+
};
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
import {
2+
ConfigurationError,
3+
getFileStreamAndMetadata,
4+
} from "@pipedream/platform";
5+
import FormData from "form-data";
6+
import { parseObject } from "../../common/utils.mjs";
7+
import luminPdf from "../../lumin_pdf.app.mjs";
8+
9+
export default {
10+
key: "lumin_pdf-send-signature-request",
11+
name: "Send Signature Request",
12+
description: "Send a signature request to signers. [See the documentation](https://developers.luminpdf.com/api/send-signature-request/)",
13+
version: "0.0.1",
14+
type: "action",
15+
props: {
16+
luminPdf,
17+
fileUrl: {
18+
type: "string",
19+
label: "File URL",
20+
description: "The URL of a single file to be downloaded and signed. This field is mutually exclusive with `file`, `files`, and `File URLs`. Only one of these fields should be provided in the request.",
21+
optional: true,
22+
},
23+
file: {
24+
type: "string",
25+
label: "File",
26+
description: "A single path to a file in the `/tmp` directory (for example, `/tmp/myFile.pdf`) to be sent for signature. This field is mutually exclusive with `File URL`, `Files`, and `File URLs`. Only one of these fields should be provided in the request.",
27+
optional: true,
28+
},
29+
fileUrls: {
30+
type: "string[]",
31+
label: "File URLs",
32+
description: "An array of URLs of files to be downloaded and signed. This field is mutually exclusive with `File`, `Files`, and `File URL`. Only one of these fields should be provided in the request.",
33+
optional: true,
34+
},
35+
files: {
36+
type: "string[]",
37+
label: "Files",
38+
description: "An array of path to files in the `/tmp` directory (for example, `/tmp/myFile.pdf`) to be sent for signature. This field is mutually exclusive with `File URL`, `Files`, and `File URLs`. Only one of these fields should be provided in the request.",
39+
optional: true,
40+
},
41+
signers: {
42+
type: "string[]",
43+
label: "Signers",
44+
description: "A list of objects of signers to add to your Signature Request. Format: `[{'email_address': '[email protected]', 'name': 'John Doe', 'group': 1}, {'email_address': '[email protected]', 'name': 'Jane Doe', 'group': 2}]`. [See the documentation](https://developers.luminpdf.com/api/send-signature-request/) for more information.",
45+
optional: true,
46+
},
47+
viewers: {
48+
type: "string[]",
49+
label: "Viewers",
50+
description: "A list of objects of viewers to add to your Signature Request. Format: `[{'email_address': '[email protected]', 'name': 'John Doe'}, {'email_address': '[email protected]', 'name': 'Jane Doe'}]`. [See the documentation](https://developers.luminpdf.com/api/send-signature-request/) for more information.",
51+
optional: true,
52+
},
53+
title: {
54+
type: "string",
55+
label: "Title",
56+
description: "The title you want to give the Signature Request.",
57+
},
58+
expiresAt: {
59+
type: "string",
60+
label: "Expires At",
61+
description: "When the Signature Request will expire. Should be later than today. In ISO 8601 format (YYYY-MM-DDTHH:MM:SSZ).",
62+
},
63+
useTextTags: {
64+
type: "boolean",
65+
label: "Use Text Tags",
66+
description: "Set to `true` to enable Text Tag parsing in your document. Your Text Tags will be converted into UI components for the user to interact with.",
67+
optional: true,
68+
},
69+
signingType: {
70+
type: "string",
71+
label: "Signing Type",
72+
description: "The signing order for the Signature Request.",
73+
options: [
74+
"SAME_TIME",
75+
"ORDER",
76+
],
77+
optional: true,
78+
},
79+
senderEmail: {
80+
type: "string",
81+
label: "Sender Email",
82+
description: "The email address of the sender.",
83+
optional: true,
84+
},
85+
subject: {
86+
type: "string",
87+
label: "Subject",
88+
description: "The subject of the email.",
89+
optional: true,
90+
},
91+
customEmailTitle: {
92+
type: "string",
93+
label: "Custom Email Title",
94+
description: "The title of the email.",
95+
optional: true,
96+
},
97+
syncDir: {
98+
type: "dir",
99+
accessMode: "read",
100+
sync: true,
101+
optional: true,
102+
},
103+
},
104+
methods: {
105+
async appendFile(formData, fieldName, file) {
106+
const {
107+
stream,
108+
metadata,
109+
} = await getFileStreamAndMetadata(file);
110+
formData.append(fieldName, stream, {
111+
contentType: metadata.contentType,
112+
knownLength: metadata.size,
113+
filename: metadata.name,
114+
});
115+
},
116+
},
117+
async run({ $ }) {
118+
const formData = new FormData();
119+
const checkFiles = {};
120+
if (this.file) checkFiles.file = this.file;
121+
if (this.files) checkFiles.files = this.files;
122+
if (this.fileUrl) checkFiles.fileUrl = this.fileUrl;
123+
if (this.fileUrls) checkFiles.fileUrls = this.fileUrls;
124+
125+
if (Object.keys(checkFiles).length > 1) {
126+
throw new ConfigurationError("Only one of `File URL`, `File`, `File URLs`, or `Files` should be provided in the request.");
127+
}
128+
if (Object.keys(checkFiles).length === 0) {
129+
throw new ConfigurationError("At least one of `File URL`, `File`, `File URLs`, or `Files` should be provided in the request.");
130+
}
131+
132+
if (this.file) {
133+
await this.appendFile(formData, "file", this.file);
134+
}
135+
if (this.files) {
136+
for (const [
137+
index,
138+
file,
139+
] of this.files.entries()) {
140+
await this.appendFile(formData, `files[${index}]`, file);
141+
}
142+
}
143+
if (this.fileUrl) {
144+
formData.append("file_url", this.fileUrl);
145+
}
146+
if (this.fileUrls) {
147+
for (const [
148+
index,
149+
fileUrl,
150+
] of this.fileUrls.entries()) {
151+
formData.append(`file_urls[${index}]`, fileUrl);
152+
}
153+
}
154+
if (this.signers) {
155+
for (const [
156+
index,
157+
signer,
158+
] of parseObject(this.signers).entries()) {
159+
for (const item of Object.keys(signer)) {
160+
formData.append(`signers[${index}][${item}]`, signer[item]);
161+
}
162+
}
163+
}
164+
if (this.viewers) {
165+
for (const [
166+
index,
167+
viewer,
168+
] of parseObject(this.viewers).entries()) {
169+
for (const item of Object.keys(viewer)) {
170+
formData.append(`viewers[${index}][${item}]`, viewer[item]);
171+
}
172+
}
173+
}
174+
if (this.title) formData.append("title", this.title);
175+
if (this.expiresAt) formData.append("expires_at", Date.parse(this.expiresAt));
176+
if (this.useTextTags) formData.append("use_text_tags", `${this.useTextTags}`);
177+
if (this.signingType) formData.append("signing_type", this.signingType);
178+
if (this.senderEmail) formData.append("custom_email[sender_email]", this.senderEmail);
179+
if (this.senderEmail) formData.append("custom_email[subject_name]", this.subject);
180+
if (this.senderEmail) formData.append("custom_email[title]", this.customEmailTitle);
181+
182+
const response = await this.luminPdf.sendSignatureRequest({
183+
$,
184+
headers: formData.getHeaders(),
185+
data: formData,
186+
});
187+
188+
if (response) {
189+
$.export("$summary", `Successfully sent signature request ${response.signature_request.signature_request_id}`);
190+
}
191+
192+
return response;
193+
},
194+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export const parseObject = (obj) => {
2+
if (!obj) return undefined;
3+
4+
if (Array.isArray(obj)) {
5+
return obj.map((item) => {
6+
if (typeof item === "string") {
7+
try {
8+
return JSON.parse(item);
9+
} catch (e) {
10+
return item;
11+
}
12+
}
13+
return item;
14+
});
15+
}
16+
if (typeof obj === "string") {
17+
try {
18+
return JSON.parse(obj);
19+
} catch (e) {
20+
return obj;
21+
}
22+
}
23+
return obj;
24+
};

0 commit comments

Comments
 (0)