Code Monkey home page Code Monkey logo

pdf-bot's Introduction

๐Ÿค– pdf-bot

npm Build Status Coverage Status

Easily create a microservice for generating PDFs using headless Chrome.

pdf-bot is installed on a server and will receive URLs to turn into PDFs through its API or CLI. pdf-bot will manage a queue of PDF jobs. Once a PDF job has run it will notify you using a webhook so you can fetch the API. pdf-bot supports storing PDFs on S3 out of the box. Failed PDF generations and Webhook pings will be retried after a configurable decaying schedule.

How to use the pdf-bot CLI

pdf-bot uses html-pdf-chrome under the hood and supports all the settings that it supports. Major thanks to @westy92 for making this possible.

How does it work?

Imagine you have an app that creates invoices. You want to save those invoices as PDF. You install pdf-bot on a server as an API. Your app server sends the URL of the invoice to the pdf-bot server. A cronjob on the pdf-bot server keeps checking for new jobs, generates a PDF using headless Chrome and sends the location back to the application server using a webhook.

Prerequisites

  • Node.js v6 or later

Installation

$ npm install -g pdf-bot
$ pdf-bot install

Make sure the node path is in your $PATH

pdf-bot install will prompt for some basic configurations and then create a storage folder where your database and pdf files will be saved.

Configuration

pdf-bot comes packaged with sensible defaults. At the very minimum you must have a config file in the same folder from which you are executing pdf-bot with a storagePath given. However, in reality what you probably want to do is use the pdf-bot install command to generate a configuration file and then use an alias ALIAS pdf-bot = "pdf-bot -c /home/pdf-bot.config.js"

pdf-bot.config.js

var htmlPdf = require('html-pdf-chrome')

module.exports = {
  api: {
    token: 'crazy-secret'
  },
  generator: {
    completionTrigger: new htmlPdf.CompletionTrigger.Timer(1000) // 1 sec timeout
  },
  storagePath: 'storage'
}
$ pdf-bot -c ./pdf-bot.config.js push https://esbenp.github.io

See a full list of the available configuration options.

Usage guide

Structure and concept

pdf-bot is meant to be a microservice that runs a server to generate PDFs for you. That usually means you will send requests from your application server to the PDF server to request an url to be generated as a PDF. pdf-bot will manage a queue and retry failed generations. Once a job is successfully generated a path to it will be sent back to your application server.

Let us check out the flow for an app that generates PDF invoices.

1. (App server): An invoice is created ----> Send URL to invoice to pdf-bot server
2. (pdf-bot server): Put the URL in the queue
3. (pdf-bot server): PDF is generated using headless Chrome
4. (pdf-bot server): (if failed try again using 1 min, 3 min, 10 min, 30 min, 60 min delay)
5. (pdf-bot server): Upload PDF to storage (e.g. Amazon S3)
6. (pdf-bot server): Send S3 location of PDF back to the app server
7. (App server): Receive S3 location of PDF -> Check signature sum matches for security
8. (App server): Handle PDF however you see fit (move it, download it, save it etc.)

You can send meta data to the pdf-bot server that will be sent back to the application. This can help you identify what PDF you are receiving.

Setup

On your pdf-bot server start by creating a config file pdf-bot.config.js. You can see an example file here

pdf-bot.config.js

module.exports = {
  api: {
    port: 3000,
    token: 'api-token'
  },
  storage: {
    's3': createS3Config({
      bucket: '',
      accessKeyId: '',
      region: '',
      secretAccessKey: ''
    })
  },
  webhook: {
    secret: '1234',
    url: 'http://localhost:3000/webhooks/pdf'
  }
}

As a minimum you should configure an access token for your API. This will be used to authenticate jobs sent to your pdf-bot server. You also need to add a webhook configuration to have pdf notifications sent back to your application server. You should add a secret that will be used to generate a signature used to check that the request has not been tampered with during transfer.

Start your API using

pdf-bot -c ./pdf-bot.config.js api

This will start an express server that listens for new jobs on port 3000.

Setting up Chrome

pdf-bot uses html-pdf-chrome which in turns uses chrome-launcher to launch chrome. You should check out those two resources on how to properly setup Chrome. However, with chrome-launcher Chrome should be started automatically. Otherwise, html-pdf-chrome has a small guide on how to have it running as a process using pm2.

You can install chrome on Ubuntu using

sudo apt-get update && apt-get install chromium-browser

If you are testing things on OSX or similar, chrome-launcher should be able to find and automatically startup Chrome for you.

Setting up the receiving API

In the examples folder there is a small example on how the application API could look. Basically, you just have to define an endpoint that will receive the webhook and check that the signature matches.

api.post('/hook', function (req, res) {
  var signature = req.get('X-PDF-Signature', 'sha1=')

  var bodyCrypted = require('crypto')
    .createHmac('sha1', '12345')
    .update(JSON.stringify(req.body))
    .digest('hex')

  if (bodyCrypted !== signature) {
    res.status(401).send()
    return
  }

  console.log('PDF webhook received', JSON.stringify(req.body))

  res.status(204).send()
})

Setup production environment

Follow the guide under production/ to see how to setup pdf-bot using pm2 and nginx

Setup crontab

We setup our crontab to continuously look for jobs that have not yet been completed.

* * * * * node $(npm bin -g)/pdf-bot -c ./pdf-bot.config.js shift:all >> /var/log/pdfbot.log 2>&1
* * * * * node $(npm bin -g)/pdf-bot -c ./pdf-bot.config.js ping:retry-failed >> /var/log/pdfbot.log 2>&1

Quick example using the CLI

Let us assume I want to generate a PDF for https://esbenp.github.io. I can add the job using the pdf-bot CLI.

$ pdf-bot -c ./pdf-bot.config.js push https://esbenp.github.io --meta '{"id":1}'

Next, if my crontab is not setup to run it automatically I can run it using the shift:all command

$ pdf-bot -c ./pdf-bot.config.js shift:all

This will look for the oldest uncompleted job and run it.

How can I generate PDFs for sites that use Javascript?

This is a common issue with PDF generation. Luckily, html-pdf-chrome has a really awesome API for dealing with Javascript. You can specify a timeout in milliseconds, wait for elements or custom events. To add a wait simply configure the generator key in your configuration. Below are a few examples.

Wait for 5 seconds

var htmlPdf = require('html-pdf-chrome')

module.exports = {
  api: {
    token: 'api-token'
  },
  // html-pdf-chrome options
  generator: {
    completionTrigger: new htmlPdf.CompletionTrigger.Timer(5000), // waits for 5 sec
  },
  webhook: {
    secret: '1234',
    url: 'http://localhost:3000/webhooks/pdf'
  }
}

Wait for event

var htmlPdf = require('html-pdf-chrome')

module.exports = {
  api: {
    token: 'api-token'
  },
  // html-pdf-chrome options
  generator: {
    completionTrigger: new htmlPdf.CompletionTrigger.Event(
      'myEvent', // name of the event to listen for
      '#myElement', // optional DOM element CSS selector to listen on, defaults to body
      5000 // optional timeout (milliseconds)
    )
  },
  webhook: {
    secret: '1234',
    url: 'http://localhost:3000/webhooks/pdf'
  }
}

In your Javascript trigger the event when rendering is complete

document.getElementById('myElement').dispatchEvent(new CustomEvent('myEvent'));

Wait for variable

var htmlPdf = require('html-pdf-chrome')

module.exports = {
  api: {
    token: 'api-token'
  },
  // html-pdf-chrome options
  generator: {
    completionTrigger: new htmlPdf.CompletionTrigger.Variable(
      'myVarName', // optional, name of the variable to wait for.  Defaults to 'htmlPdfDone'
      5000 // optional, timeout (milliseconds)
    )
  },
  webhook: {
    secret: '1234',
    url: 'http://localhost:3000/webhooks/pdf'
  }
}

In your Javascript set the variable when the rendering is complete

window.myVarName = true;

You can find more completion triggers in html-pdf-chrome's documentation

API

Below are given the endpoints that are exposed by pdf-server's REST API

Push URL to queue: POST /

key type required description
url string yes The URL to generate a PDF from
meta object Optional meta data object to send back to the webhook url

Example

curl -X POST -H 'Authorization: Bearer api-token' -H 'Content-Type: application/json' http://pdf-bot.com/ -d '
  {
    "url":"https://esbenp.github.io",
    "meta":{
      "type":"invoice",
      "id":1
    }
  }'

Database

LowDB (file-database) (default)

If you have low conurrency (run a job every now and then) you can use the default database driver that uses LowDB.

var LowDB = require('pdf-bot/src/db/lowdb')

module.exports = {
  api: {
    token: 'api-token'
  },
  db: LowDB({
    lowDbOptions: {},
    path: '' // defaults to $storagePath/db/db.json
  }),
  webhook: {
    secret: '1234',
    url: 'http://localhost:3000/webhooks/pdf'
  }
}

PostgreSQL

var pgsql = require('pdf-bot/src/db/pgsql')

module.exports = {
  api: {
    token: 'api-token'
  },
  db: pgsql({
    database: 'pdfbot',
    username: 'pdfbot',
    password: 'pdfbot',
    port: 5432
  }),
  webhook: {
    secret: '1234',
    url: 'http://localhost:3000/webhooks/pdf'
  }
}

Optionally, you can specify a database url by specifying a connectionString.

To install the necessary database tables, run db:migrate. You can also destroy the database by running db:destroy.

Storage

Currently pdf-bot comes bundled with build-in support for storing PDFs on Amazon S3.

Feel free to contribute a PR if you want to see other storage plugins in pdf-bot!

Amazon S3

To install S3 storage add a key to the storage configuration. Notice, you can add as many different locations you want by giving them different keys.

var createS3Config = require('pdf-bot/src/storage/s3')

module.exports = {
  api: {
    token: 'api-token'
  },
  storage: {
    'my_s3': createS3Config({
      bucket: '[YOUR BUCKET NAME]',
      accessKeyId: '[YOUR ACCESS KEY ID]',
      region: '[YOUR REGION]',
      secretAccessKey: '[YOUR SECRET ACCESS KEY]'
    })
  },
  webhook: {
    secret: '1234',
    url: 'http://localhost:3000/webhooks/pdf'
  }
}

Options

var decaySchedule = [
  1000 * 60, // 1 minute
  1000 * 60 * 3, // 3 minutes
  1000 * 60 * 10, // 10 minutes
  1000 * 60 * 30, // 30 minutes
  1000 * 60 * 60 // 1 hour
];

module.exports = {
  // The settings of the API
  api: {
    // The port your express.js instance listens to requests from. (default: 3000)
    port: 3000,
    // Spawn command when a job has been pushed to the API
    postPushCommand: ['/home/user/.npm-global/bin/pdf-bot', ['-c', './pdf-bot.config.js', 'shift:all']],
    // The token used to validate requests to your API. Not required, but 100% recommended.
    token: 'api-token'
  },
  db: LowDB(), // see other drivers under Database
  // html-pdf-chrome
  generator: {
    // Triggers that specify when the PDF should be generated
    completionTrigger: new htmlPdf.CompletionTrigger.Timer(1000), // waits for 1 sec
    // The port to listen for Chrome (default: 9222)
    port: 9222
  },
  queue: {
    // How frequent should pdf-bot retry failed generations?
    // (default: 1 min, 3 min, 10 min, 30 min, 60 min)
    generationRetryStrategy: function(job, retries) {
      return decaySchedule[retries - 1] ? decaySchedule[retries - 1] : 0
    },
    // How many times should pdf-bot try to generate a PDF?
    // (default: 5)
    generationMaxTries: 5,
    // How many generations to run at the same time when using shift:all
    parallelism: 4,
    // How frequent should pdf-bot retry failed webhook pings?
    // (default: 1 min, 3 min, 10 min, 30 min, 60 min)
    webhookRetryStrategy: function(job, retries) {
      return decaySchedule[retries - 1] ? decaySchedule[retries - 1] : 0
    },
    // How many times should pdf-bot try to ping a webhook?
    // (default: 5)
    webhookMaxTries: 5
  },
  storage: {
    's3': createS3Config({
      bucket: '',
      accessKeyId: '',
      region: '',
      secretAccessKey: ''
    })
  },
  webhook: {
    // The prefix to add to all pdf-bot headers on the webhook response.
    // I.e. X-PDF-Transaction and X-PDF-Signature. (default: X-PDF-)
    headerNamespace: 'X-PDF-',
    // Extra request options to add to the Webhook ping.
    requestOptions: {

    },
    // The secret used to generate the hmac-sha1 signature hash.
    // !Not required, but should definitely be included!
    secret: '1234',
    // The endpoint to send PDF messages to.
    url: 'http://localhost:3000/webhooks/pdf'
  }
}

CLI

pdf-bot comes with a full CLI included! Use -c to pass a configuration to pdf-bot. You can also use --help to get a list of all commands. An example is given below.

$ pdf-bot.js --config ./examples/pdf-bot.config.js --help


  Usage: pdf-bot [options] [command]


  Options:

    -V, --version        output the version number
    -c, --config <path>  Path to configuration file
    -h, --help           output usage information


  Commands:

    api                   Start the API
    db:migrate
    db:destroy
    install
    generate [jobID]      Generate PDF for job
    jobs [options]        List all completed jobs
    ping [jobID]          Attempt to ping webhook for job
    ping:retry-failed
    pings [jobId]         List pings for a job
    purge [options]       Will remove all completed jobs
    push [options] [url]  Push new job to the queue
    shift                 Run the next job in the queue
    shift:all             Run all unfinished jobs in the queue

Debug mode

pdf-bot uses debug for debug messages. You can turn on debugging by setting the environment variable DEBUG=pdf:* like so

DEBUG=pdf:* pdf-bot jobs

Tests

$ npm run test

Issues

Please report issues to the issue tracker

License

The MIT License (MIT). Please see License File for more information.

pdf-bot's People

Contributors

axxag avatar bhageena avatar danielwestendorf avatar dependabot[bot] avatar esbenp avatar nassimkirouane avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pdf-bot's Issues

Realtime Support

I think it would be useful to have a real time pdf generation feature where user hits the api and gets pdf in return instead of inserting it in the queue.

Add FTP storage support

It would be interesting (and probably practical) to add FTP support using the excellent jsftp library for example. Judging from the src/storage/s3.js implementation, it shouldn't be too hard.

lowdb -> queue.addToQueue(...).then is not a function

Hi,

I've tried to get this working on a Dockerised node image and natively on a Windows 10 machine. The error is consistent.

TypeError: queue.addToQueue(...).then is not a function
    at /usr/local/lib/node_modules/pdf-bot/src/api.js:30:10
    at Layer.handle [as handle_request] (/usr/local/lib/node_modules/pdf-bot/node_modules/express/lib/router/layer.js:95:5)
    at next (/usr/local/lib/node_modules/pdf-bot/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/usr/local/lib/node_modules/pdf-bot/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/usr/local/lib/node_modules/pdf-bot/node_modules/express/lib/router/layer.js:95:5)
    at /usr/local/lib/node_modules/pdf-bot/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/usr/local/lib/node_modules/pdf-bot/node_modules/express/lib/router/index.js:335:12)
    at next (/usr/local/lib/node_modules/pdf-bot/node_modules/express/lib/router/index.js:275:10)
    at jsonParser (/usr/local/lib/node_modules/pdf-bot/node_modules/body-parser/lib/types/json.js:119:7)
    at Layer.handle [as handle_request] (/usr/local/lib/node_modules/pdf-bot/node_modules/express/lib/router/layer.js:95:5)

The config is:

var htmlPdf = require('html-pdf-chrome')
var lowDB = require('/usr/local/lib/node_modules/pdf-bot/src/db/lowdb')

module.exports = {
    api: {
        port: process.env.PDF_BOT_PORT,
        token: process.env.PDF_BOT_TOKEN
    },
    generator: {
        // Triggers that specify when the PDF should be generated
        completionTrigger: new htmlPdf.CompletionTrigger.Timer(process.env.PDF_BOT_COMPLETION_TIMER),
        // The port to listen for Chrome (default: 9222)
        port: process.env.CHROME_DEBUG_PORT
    },
    storagePath: 'storage',
    db:lowDB({
        lowdDbOptions: {},
//        path:'./storage'
    })
}

Docker image - node version: v10.5.0
Windows node: v8.9.4
pdf-bot: 0.5.4

With and without db options in the config but to with no luck, what am I doing wrong?

Thanks

Webhook Url is interpreted as lowercase if prefixed by http

The Url for webhooks are lower-cased when resolving dns if prefixed with http.

var LowDB = require('./src/db/lowdb.js')
var htmlPdf = require('html-pdf-chrome')

module.exports = {
  api: {
    port: 3000,
    token: 'api-token'
  },
  db: LowDB({
    lowDbOptions: {},
    path: 'pdf-storage/db/db'
  }),
  storagePath: "pdf-storage",
  webhook: {
    secret: '1234',
    url: 'http://MY_URL:5000/api/internals/webhooks/pdf'
  },
  generator: {
    // Triggers that specify when the PDF should be generated
    completionTrigger: new htmlPdf.CompletionTrigger.Timer(1000), // waits for 1 sec
    // The port to listen for Chrome (default: 9222)
    port: 9222,
    printOptions: {
        printBackground: true
    }
  }
}

Will result with error

Ping failed: {"id":"8de73c3c-21ef-47e7-91b2-cbb64c1a4d80","method":"POST","payload":{"id":"75db4451-ad57-49af-9265-a547855c7ff1","url":"https://test","meta":{"scheduledreporttaskid":"5fdbf776-c35d-45ad-9e44-0be5688d3a9d"},"storage":{"local":"pdf-storage/pdf/38cfee13-4d43-418e-ac34-bc70880995d1.pdf"}},"response":{"name":"FetchError","message":"request to http://MY_URL:5000/api/internals/webhooks/pdf failed, reason: getaddrinfo ENOTFOUND my_url my_url:5000","type":"system","errno":"ENOTFOUND","code":"ENOTFOUND"},"url":"http://MY_URL:5000/api/internals/webhooks/pdf","sent_at":"Tue, 15 Oct 2019 07:38:03 GMT","error":true}

Shift command with AWS S3 URL not working

I tried executing the pdf-bot shift with aws s3 URL but it's not working. It is stuck on blinking the cmd cursor and nothing happens. But when I tried to execute the pdf-bot shift command with another website URL, it is working. Is there any problem with my configs or setup?Please help me..Thanks..

UPDATE: Already solved this issue. Just added "ContentType": "text/html" property on my s3.upload options.

Docker build?

Any chance of a docker build to use. It would be great

pdf-bot limited to one machine rendering pdf's

I'm looking for feedback from @esbenp before I dig into a PR for this.

Goal:

I'd like to adapt pdf-bot to be a scaleable pdf rendering microservice which can have resources added/removed on demand to handle workload fluctuations.

Problem:

Because of pdf-bot's PostgreSQL database wide queue locking, only one machine can render pdf's for the given API endpoint at a time.

Because PG is a shared database, it' possible to scale the work load horizontally across many machines in parallel. To accomplish this, we would need to change the queue locking mechanism to be on a per-job basis, and adapt the generation commands (shift:all comes to mind) to support this.

There are a few concerns here:

  1. This would require a database migration of some sort to support
  2. Process crashes, unhandled errors, etc could result in jobs never being processed if implemented poorly
  3. ?

Purposed implementation:

  • Add a processing_started_at date column to the jobs table
  • Adapt getAllUnfinished to select jobs where they aren't completed and processing_started_at is greater than a given a configurable amount (30 sec default maybe)
  • Make isBusy calls return false always (maybe?)
  • Adapt cli scripts (shift, shift:all, etc) to handle the possibility of getting an empty array of jobs instead of relying on an isBusy call (maybe?)
  • Remove setIsBusy calls (maybe?)
  • Add changes to LowDb as well (maybe?)
  • Remove worker table
id processing_started_at completed_at
1 2018-01-08 17:31:17.825153 2018-01-08 17:31:48.925153
2 2018-01-08 17:31:17.825153 null
3 2018-01-08 17:31:47.925153 null
4 2018-01-08 17:31:48.925153 null
5 null null
6 null null

Given this sample data, jobs 2, 5, and 6 would be eligible for the next generation worker to start processing, while jobs 3 and 4 are assumed to be currently processing.

If this all sounds like too big of an overhaul, I'd be open to other suggestions. I'd also be willing to add the support to a new Redis database adapter instead as well.

FunctionApp

I am creating function app for pushing iot hub messages to application, using nodejs. But some times messages are grouping together. Can U please look at this issue.

"Job not found" error using Lowdb as a storage of queue

I have been trying a lot of variants to push a job and then generate PDF file, however haven't succeeded in. It seems like db.json is not used at all, it's being stayed empty. I don't know what is in Postgres regard, perhaps there is the same issue. Could you check the reason please?

Add custom header and footer to generated pdf

I see that htmlpdfchrome has this option with:

const pdf = await htmlPdf.create(html, {
  port,
  printOptions: {
    displayHeaderFooter: true,
    headerTemplate: `
      <div class="text center">
        Page <span class="pageNumber"></span> of <span class="totalPages"></span>
      </div>
    `,
    footerTemplate: '<div class="text center">Custom footer!</div>',
  },
});

Can I do this on pdf-bot generation?

Shift all?

Hi cool lib!

I was wondering how to go about doing something like shift all? I have a group of PDFs i send in quick succession and would like to get them generated and saved to S3 consecutively.

I'm not familiar with the commands inside the bin folder. but i'm guessing looping through the queue and calling shift each time?

Possibility to send html instead of url?

Hi,
Thanks for the wonderful library and all the effort that you invested. I have a situation where I'd prefer to send raw html to the bot and get back pdf in return, so no urls just html in POST request, is that possible? Thanks.

Run faster than once per minute?

Since cron runs at most once per minute, a PDF job sent to pdf-bot may take one minute to process even if pdf-bot is not busy at the time.

Is there a way to have a shift:all run automatically when an API push is triggered? Or is there a trick to getting pdf-bot to process more quickly?

Typo in docs

var pgsql = require('pdf-bot/src/db/pgsql')

module.exports = {
  api: {
    token: 'api-token'
  },
  db: pgsql({
    database: 'pdfbot',
    username: 'pdfbot',
    password: 'pdfbot',
    port: 5432
  }),
  webhook: {
    secret: '1234',
    url: 'http://localhost:3000/webhooks/pdf'
  }
}

Can you change pls "username" to "user" cause it's the the correct option there?

Returns 201 even if nothing created

This is really an issue with me getting pdf-bot to work at all. Right now I can send POSTs and they get added to the job queue as completed, but no PDF is generated. The response JSON seems to confirm that nothing is being done:

{
    "meta": {
        "type": "invoice",
        "id": 1
    },
    "url": "https://localhost:3001/test",
    "id": "ae6f6151-cb6a-4d21-914b-a10a8154ff94",
    "created_at": "Wed, 27 Sep 2017 16:55:30 GMT",
    "completed_at": null,
    "generations": [],
    "pings": [],
    "storage": {}
}

My /test endpoint is never touched as well as the /hook. I have google-chrome running via pm2 and am running pdf-bot with a basic local storage config file. I can't get any errors to display anywhere.

  1. At the very least, I think that 201 Created should not be the response if nothing is actually created.
  2. Is there anything obvious I'm missing in getting pdf-bot working? Thanks.

Config if it helps:

var htmlPdf = require('html-pdf-chrome');
module.exports = {
  api: {
    port: 3000,
    token: 'api-token'
  },
  generator: {
    completionTrigger: new htmlPdf.CompletionTrigger.Timer(1000) // 1 sec timeout
  },
  storagePath: "/Users/matthewmolnar/junk/pdf-storage",
  webhook: {
    secret: '12345',
    url: 'http://localhost:3001/hook'
  }
}

Add a parameter to the request to support postback to the url

For our use case, the form is a formal document representation of other functionality, as such, there is no need for the overhead of having a static form page created for each instance. Preferable would be to have a template url that can consume a json payload via POST, render the form with the mapped in data, and then pass this data via the same request to pdf bot - basically thinking of having a 3rd optional parameter called formdata, an arbitrary object blob, and having a value in this field changes the request to a post.

This is so compelling for us vs having to instantiate every form prior to making the pdf-bot request, that I may end up forking and implementing, if you are at all interested in a PR...

Support for posting the html instead of adding a url

I think it would be reasonable to make it possible to generate the pdf's directly from html instead of from visiting a url.

Not sure how html-pdf-chrome handles this, but Puppeteer has support out of the box, so it should be possible.

Error: connect ECONNREFUSED

When i am trying to generate pdf using CLI, i am getting the following log.

$ DEBUG=pdf:* pdf-bot generate 359621c9-87cc-4070-b648-09aa51d117ba
  pdf:cli Creating CLI using config file /Users/venkadesh/Downloads/pdf-bot-master/pdf-bot.config.js +0ms
  pdf:generator Creating PDF for url https://esbenp.github.io with options {"completionTrigger":{"timeout":5000,"timeoutMessage":"CompletionTrigger timed out."}} +68ms
  pdf:db Logging try for job ID 359621c9-87cc-4070-b648-09aa51d117ba +26s
html-pdf-chrome error: Error: connect ECONNREFUSED ::1:50296 (job ID: 359621c9-87cc-4070-b648-09aa51d117ba. Generation ID: 09864256-00a8-410f-9a7a-68a8e8ba2f05)

Anyone please help me to fix this.

Not able to install pdf-bot

I installed pdf-bot using npm but after installing whenever I run command
pdf-bot install I get following error:

/usr/lib/node_modules/pdf-bot/bin/pdf-bot.js:328
function openConfig(delayQueueCreation = false) {
                                       ^

SyntaxError: Unexpected token =
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:373:25)
    at Object.Module._extensions..js (module.js:416:10)
    at Module.load (module.js:343:32)
    at Function.Module._load (module.js:300:12)
    at Function.Module.runMain (module.js:441:10)
    at startup (node.js:139:18)
    at node.js:968:3

I don't know why it is throwing this error. Is it because of the node version?

"Question"

Sorry i'm new here, can anyone tell me if this works on pressreader.com to save newspapers/magazines to pdf..thanks..

Disable crypto dependency

Installing pdf-bot via npm outputs the following warning:

npm WARN deprecated [email protected]: This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.