diff --git a/examples/esign.js b/examples/esign.js new file mode 100644 index 0000000..d3c6c4f --- /dev/null +++ b/examples/esign.js @@ -0,0 +1,101 @@ +// Create an Etch e-sign packet via the Anvil API and send it to a signer. +// Docs: https://www.useanvil.com/docs/api/e-signatures +// +// Run it from a project with @anvilco/anvil installed: +// ANVIL_API_KEY=yourKey node create-etch-packet.js your.real.email@example.com +// +// A signature request email is sent to the address you pass, so use your real +// email address. The new packet also appears in your dashboard's e-sign area. + +import Anvil from '@anvilco/anvil' + +// Your API key from your Anvil organization settings +const apiKey = process.env.ANVIL_API_KEY ?? '' + +// A sample PDF template available to any account. See +// https://www.useanvil.com/help/tutorials/set-up-a-pdf-template to set up your own +const pdfTemplateID = '05xXsZko33JIO6aq5Pnr' + +const signerName = 'Testy Signer' +const signerEmail = process.argv[2] ?? '' + +if (!signerEmail) { + console.log('Enter your email address as the script\'s 1st argument') + process.exit(1) +} + +async function createEtchPacket () { + const anvilClient = new Anvil({ apiKey }) + + const { statusCode, data, errors } = await anvilClient.createEtchPacket({ + variables: { + // The packet is ready to send: an email goes to the first signer. + // Use isDraft: true to review it in the dashboard first + isDraft: false, + + // Test packets use development signatures and do not count toward + // your billed packets + isTest: true, + + // Set to true for interactive signing, where signers fill fields as they + // sign. Over the API that needs the Product pack or Enterprise plan + allowUpdates: false, + + name: `Test Docs - ${signerName}`, + signatureEmailSubject: 'Custom email subject', + signatureEmailBody: 'Custom please sign these documents....', + + files: [ + { + // Your own ID for referencing this file in `data` and `signers` below + id: 'sampleTemplate', + castEid: pdfTemplateID, + }, + ], + + data: { + // This data fills the PDF before it is sent to any signers. IDs here + // match the fields configured on the PDF template + payloads: { + sampleTemplate: { + data: { + name: signerName, + email: signerEmail, + }, + }, + }, + }, + + signers: [ + // Signers sign in the order they are specified in this array + { + id: 'signer1', + name: signerName, + email: signerEmail, + signerType: 'email', + + // The fields this signer clicks through, in this order + fields: [ + { + fileId: 'sampleTemplate', + fieldId: 'signature', + }, + ], + }, + ], + }, + }) + + if (errors) { + // GraphQL can return a 200 status code even when there are errors + console.log('There were errors:', statusCode, JSON.stringify(errors, null, 2)) + } else { + const packetDetails = data?.data?.createEtchPacket + console.log('Visit the new packet on your dashboard:', packetDetails?.detailsURL) + } +} + +createEtchPacket().catch((error) => { + console.error(error) + process.exit(1) +}) diff --git a/examples/esign.ts b/examples/esign.ts new file mode 100644 index 0000000..0aab4f1 --- /dev/null +++ b/examples/esign.ts @@ -0,0 +1,101 @@ +// Create an Etch e-sign packet via the Anvil API and send it to a signer. +// Docs: https://www.useanvil.com/docs/api/e-signatures +// +// Run it from a project with @anvilco/anvil installed: +// ANVIL_API_KEY=yourKey npx tsx create-etch-packet.ts your.real.email@example.com +// +// A signature request email is sent to the address you pass, so use your real +// email address. The new packet also appears in your dashboard's e-sign area. + +import Anvil, { GraphQLResponse } from '@anvilco/anvil' + +// Your API key from your Anvil organization settings +const apiKey = process.env.ANVIL_API_KEY ?? '' + +// A sample PDF template available to any account. See +// https://www.useanvil.com/help/tutorials/set-up-a-pdf-template to set up your own +const pdfTemplateID = '05xXsZko33JIO6aq5Pnr' + +const signerName = 'Testy Signer' +const signerEmail = process.argv[2] ?? '' + +if (!signerEmail) { + console.log('Enter your email address as the script\'s 1st argument') + process.exit(1) +} + +async function createEtchPacket () { + const anvilClient = new Anvil({ apiKey }) + + const { statusCode, data, errors }: GraphQLResponse = await anvilClient.createEtchPacket({ + variables: { + // The packet is ready to send: an email goes to the first signer. + // Use isDraft: true to review it in the dashboard first + isDraft: false, + + // Test packets use development signatures and do not count toward + // your billed packets + isTest: true, + + // Set to true for interactive signing, where signers fill fields as they + // sign. Over the API that needs the Product pack or Enterprise plan + allowUpdates: false, + + name: `Test Docs - ${signerName}`, + signatureEmailSubject: 'Custom email subject', + signatureEmailBody: 'Custom please sign these documents....', + + files: [ + { + // Your own ID for referencing this file in `data` and `signers` below + id: 'sampleTemplate', + castEid: pdfTemplateID, + }, + ], + + data: { + // This data fills the PDF before it is sent to any signers. IDs here + // match the fields configured on the PDF template + payloads: { + sampleTemplate: { + data: { + name: signerName, + email: signerEmail, + }, + }, + }, + }, + + signers: [ + // Signers sign in the order they are specified in this array + { + id: 'signer1', + name: signerName, + email: signerEmail, + signerType: 'email', + + // The fields this signer clicks through, in this order + fields: [ + { + fileId: 'sampleTemplate', + fieldId: 'signature', + }, + ], + }, + ], + }, + }) + + if (errors) { + // GraphQL can return a 200 status code even when there are errors + console.log('There were errors:', statusCode, JSON.stringify(errors, null, 2)) + } else { + const packetDetails = data?.data?.createEtchPacket + console.log('Visit the new packet on your dashboard:', packetDetails?.detailsURL) + } +} + +createEtchPacket().catch((error) => { + console.error(error) + process.exit(1) +}) diff --git a/examples/fill.js b/examples/fill.js new file mode 100644 index 0000000..54e17f1 --- /dev/null +++ b/examples/fill.js @@ -0,0 +1,62 @@ +// Fill a PDF template with your data via the Anvil API. +// Docs: https://www.useanvil.com/docs/api/fill-pdf +// +// Run it from a project with @anvilco/anvil installed: +// ANVIL_API_KEY=yourKey node fill.js + +import fs from 'fs' +import Anvil from '@anvilco/anvil' + +// Your API key from your Anvil organization settings +const apiKey = process.env.ANVIL_API_KEY ?? '' + +// A sample PDF template available to any account. See +// https://www.useanvil.com/help/tutorials/set-up-a-pdf-template to set up your own +const pdfTemplateID = '05xXsZko33JIO6aq5Pnr' + +async function fillPDF () { + const anvilClient = new Anvil({ apiKey }) + + const { statusCode, data, errors } = await anvilClient.fillPDF(pdfTemplateID, { + title: 'My PDF Title', + fontSize: 10, + textColor: '#333333', + // IDs here match the fields configured on the PDF template + data: { + shortText: 'Hello World!', + date: '2024-01-15', + name: { firstName: 'Robin', mi: 'W', lastName: 'Smith' }, + email: 'testy@example.com', + phone: { num: '5554443333', region: 'US', baseRegion: 'US' }, + usAddress: { + street1: '123 Main St #234', + city: 'San Francisco', + state: 'CA', + zip: '94106', + country: 'US', + }, + ssn: '456454567', + ein: '897654321', + checkbox: true, + decimalNumber: 12345.67, + dollar: 123.45, + integer: 12345, + percent: 50.3, + longText: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + }, + }) + + if (statusCode === 200 && data) { + // `data` is the filled PDF binary; save it with no encoding or the file + // will be corrupt + fs.writeFileSync('fill-output.pdf', data, { encoding: null }) + console.log('Filled PDF saved to fill-output.pdf') + } else { + console.log('Error filling PDF:', statusCode, JSON.stringify(errors, null, 2)) + } +} + +fillPDF().catch((error) => { + console.error(error) + process.exit(1) +}) diff --git a/examples/fill.ts b/examples/fill.ts new file mode 100644 index 0000000..2055245 --- /dev/null +++ b/examples/fill.ts @@ -0,0 +1,62 @@ +// Fill a PDF template with your data via the Anvil API. +// Docs: https://www.useanvil.com/docs/api/fill-pdf +// +// Run it from a project with @anvilco/anvil installed: +// ANVIL_API_KEY=yourKey npx tsx fill.ts + +import fs from 'fs' +import Anvil from '@anvilco/anvil' + +// Your API key from your Anvil organization settings +const apiKey = process.env.ANVIL_API_KEY ?? '' + +// A sample PDF template available to any account. See +// https://www.useanvil.com/help/tutorials/set-up-a-pdf-template to set up your own +const pdfTemplateID = '05xXsZko33JIO6aq5Pnr' + +async function fillPDF () { + const anvilClient = new Anvil({ apiKey }) + + const { statusCode, data, errors } = await anvilClient.fillPDF(pdfTemplateID, { + title: 'My PDF Title', + fontSize: 10, + textColor: '#333333', + // IDs here match the fields configured on the PDF template + data: { + shortText: 'Hello World!', + date: '2024-01-15', + name: { firstName: 'Robin', mi: 'W', lastName: 'Smith' }, + email: 'testy@example.com', + phone: { num: '5554443333', region: 'US', baseRegion: 'US' }, + usAddress: { + street1: '123 Main St #234', + city: 'San Francisco', + state: 'CA', + zip: '94106', + country: 'US', + }, + ssn: '456454567', + ein: '897654321', + checkbox: true, + decimalNumber: 12345.67, + dollar: 123.45, + integer: 12345, + percent: 50.3, + longText: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', + }, + }) + + if (statusCode === 200 && data) { + // `data` is the filled PDF binary; save it with no encoding or the file + // will be corrupt + fs.writeFileSync('fill-output.pdf', data, { encoding: null }) + console.log('Filled PDF saved to fill-output.pdf') + } else { + console.log('Error filling PDF:', statusCode, JSON.stringify(errors, null, 2)) + } +} + +fillPDF().catch((error) => { + console.error(error) + process.exit(1) +}) diff --git a/examples/generate-html.js b/examples/generate-html.js new file mode 100644 index 0000000..ba87717 --- /dev/null +++ b/examples/generate-html.js @@ -0,0 +1,56 @@ +// Generate a PDF from HTML and CSS via the Anvil API. +// Docs: https://www.useanvil.com/docs/api/generate-pdf#html--css-to-pdf +// +// Run it from a project with @anvilco/anvil installed: +// ANVIL_API_KEY=yourKey node generate-html.js + +import fs from 'fs' +import Anvil from '@anvilco/anvil' + +// Your API key from your Anvil organization settings +const apiKey = process.env.ANVIL_API_KEY ?? '' + +async function generateHTMLPDF () { + const anvilClient = new Anvil({ apiKey }) + + const { statusCode, data, errors } = await anvilClient.generatePDF({ + title: 'Example HTML to PDF', + type: 'html', + data: { + html: ` +

What is Lorem Ipsum?

+

+ Lorem Ipsum is simply dummy text of the printing and typesetting + industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. +

+

Where does it come from?

+

+ Contrary to popular belief, Lorem Ipsum is not simply random text. + It has roots in a piece of classical Latin literature from + 45 BC, making it over 2000 years old. +

+ `, + css: ` + body { font-size: 14px; color: #171717; } + .header-one { text-decoration: underline; } + .header-two { font-style: italic; } + `, + }, + }) + + if (statusCode === 200 && data) { + // `data` is the generated PDF binary; save it with no encoding or the file + // will be corrupt + fs.writeFileSync('generate-html-output.pdf', data, { encoding: null }) + console.log('Generated PDF saved to generate-html-output.pdf') + } else { + console.log('Error generating PDF:', statusCode, JSON.stringify(errors, null, 2)) + } +} + +generateHTMLPDF().catch((error) => { + console.error(error) + process.exit(1) +}) diff --git a/examples/generate-html.ts b/examples/generate-html.ts new file mode 100644 index 0000000..44a7f20 --- /dev/null +++ b/examples/generate-html.ts @@ -0,0 +1,56 @@ +// Generate a PDF from HTML and CSS via the Anvil API. +// Docs: https://www.useanvil.com/docs/api/generate-pdf#html--css-to-pdf +// +// Run it from a project with @anvilco/anvil installed: +// ANVIL_API_KEY=yourKey npx tsx generate-html.ts + +import fs from 'fs' +import Anvil from '@anvilco/anvil' + +// Your API key from your Anvil organization settings +const apiKey = process.env.ANVIL_API_KEY ?? '' + +async function generateHTMLPDF () { + const anvilClient = new Anvil({ apiKey }) + + const { statusCode, data, errors } = await anvilClient.generatePDF({ + title: 'Example HTML to PDF', + type: 'html', + data: { + html: ` +

What is Lorem Ipsum?

+

+ Lorem Ipsum is simply dummy text of the printing and typesetting + industry. Lorem Ipsum has been the industry's standard dummy text + ever since the 1500s, when an unknown printer took + a galley of type and scrambled it to make a type specimen book. +

+

Where does it come from?

+

+ Contrary to popular belief, Lorem Ipsum is not simply random text. + It has roots in a piece of classical Latin literature from + 45 BC, making it over 2000 years old. +

+ `, + css: ` + body { font-size: 14px; color: #171717; } + .header-one { text-decoration: underline; } + .header-two { font-style: italic; } + `, + }, + }) + + if (statusCode === 200 && data) { + // `data` is the generated PDF binary; save it with no encoding or the file + // will be corrupt + fs.writeFileSync('generate-html-output.pdf', data, { encoding: null }) + console.log('Generated PDF saved to generate-html-output.pdf') + } else { + console.log('Error generating PDF:', statusCode, JSON.stringify(errors, null, 2)) + } +} + +generateHTMLPDF().catch((error) => { + console.error(error) + process.exit(1) +}) diff --git a/examples/generate-markdown.js b/examples/generate-markdown.js new file mode 100644 index 0000000..1faa86e --- /dev/null +++ b/examples/generate-markdown.js @@ -0,0 +1,49 @@ +// Generate a PDF from Markdown-structured data via the Anvil API. +// Docs: https://www.useanvil.com/docs/api/generate-pdf#markdown-to-pdf +// +// Run it from a project with @anvilco/anvil installed: +// ANVIL_API_KEY=yourKey node generate-markdown.js + +import fs from 'fs' +import Anvil from '@anvilco/anvil' + +// Your API key from your Anvil organization settings +const apiKey = process.env.ANVIL_API_KEY ?? '' + +async function generateMarkdownPDF () { + const anvilClient = new Anvil({ apiKey }) + + const { statusCode, data, errors } = await anvilClient.generatePDF({ + title: 'Example Invoice', + data: [{ + label: 'Name', + content: 'Sally Jones', + }, { + content: 'Lorem **ipsum** dolor sit _amet_, consectetur adipiscing elit, sed [do eiusmod](https://www.useanvil.com/docs) tempor incididunt ut labore et dolore magna aliqua.\n\n* Sagittis eu volutpat odio facilisis.\n\n* Erat nam at lectus urna.', + }, { + table: { + firstRowHeaders: true, + rows: [ + ['Description', 'Quantity', 'Price'], + ['4x Large Widgets', '4', '$40.00'], + ['10x Medium Sized Widgets in dark blue', '10', '$100.00'], + ['10x Small Widgets in white', '6', '$60.00'], + ], + }, + }], + }) + + if (statusCode === 200 && data) { + // `data` is the generated PDF binary; save it with no encoding or the file + // will be corrupt + fs.writeFileSync('generate-markdown-output.pdf', data, { encoding: null }) + console.log('Generated PDF saved to generate-markdown-output.pdf') + } else { + console.log('Error generating PDF:', statusCode, JSON.stringify(errors, null, 2)) + } +} + +generateMarkdownPDF().catch((error) => { + console.error(error) + process.exit(1) +}) diff --git a/examples/generate-markdown.ts b/examples/generate-markdown.ts new file mode 100644 index 0000000..c2120d0 --- /dev/null +++ b/examples/generate-markdown.ts @@ -0,0 +1,49 @@ +// Generate a PDF from Markdown-structured data via the Anvil API. +// Docs: https://www.useanvil.com/docs/api/generate-pdf#markdown-to-pdf +// +// Run it from a project with @anvilco/anvil installed: +// ANVIL_API_KEY=yourKey npx tsx generate-markdown.ts + +import fs from 'fs' +import Anvil from '@anvilco/anvil' + +// Your API key from your Anvil organization settings +const apiKey = process.env.ANVIL_API_KEY ?? '' + +async function generateMarkdownPDF () { + const anvilClient = new Anvil({ apiKey }) + + const { statusCode, data, errors } = await anvilClient.generatePDF({ + title: 'Example Invoice', + data: [{ + label: 'Name', + content: 'Sally Jones', + }, { + content: 'Lorem **ipsum** dolor sit _amet_, consectetur adipiscing elit, sed [do eiusmod](https://www.useanvil.com/docs) tempor incididunt ut labore et dolore magna aliqua.\n\n* Sagittis eu volutpat odio facilisis.\n\n* Erat nam at lectus urna.', + }, { + table: { + firstRowHeaders: true, + rows: [ + ['Description', 'Quantity', 'Price'], + ['4x Large Widgets', '4', '$40.00'], + ['10x Medium Sized Widgets in dark blue', '10', '$100.00'], + ['10x Small Widgets in white', '6', '$60.00'], + ], + }, + }], + }) + + if (statusCode === 200 && data) { + // `data` is the generated PDF binary; save it with no encoding or the file + // will be corrupt + fs.writeFileSync('generate-markdown-output.pdf', data, { encoding: null }) + console.log('Generated PDF saved to generate-markdown-output.pdf') + } else { + console.log('Error generating PDF:', statusCode, JSON.stringify(errors, null, 2)) + } +} + +generateMarkdownPDF().catch((error) => { + console.error(error) + process.exit(1) +})