Automatically obtain PDF Generation URL for use in Watcher (7.7)

Given a working Dashboard in Kibana 7.7 where we're able to Share > PDF Reports > Generate PDF, we'd like to automate the regular generation of these reports.

We've manually created a Watcher job following the Kibana docs, with a webhook action to call the POST URL in Kibana from Elasticsearch (where Watcher runs). The generated reports can later be downloaded from Elasticsearch, which is great.

What we'd like to do is automate the creation of this Watcher job, e.g. when (re)deploying our setup into an environment. The Elasticsearch Watcher APIs will allow us to do this, but we need to somehow get the POST URL from Kibana, but there doesn't appear to be a Kibana API to easily achieve this.

I've taken a look at using a "template" URL and trying to GET saved_object (dashboard), but don't see an easy way of reliably building the required URL.

Does such a(n undocumented) way of getting the POST URL exist? If not, is there a feature request for this in the pipeline (or should one be created)?

Hi Chris,

I agree we need a way to do this automatically :slight_smile:

You can hack it a bit though. If you take a look at the jobParams= query parameter, you'll notice that it is URI encoded. You can use the decodeURIComponent function available in JavaScript to "decipher" this a bit.

For instance, given this POST URL:

https://mykibana.com/api/reporting/generate/printablePdf?jobParams=%28browserTimezone%3AAmerica%2FChicago%2Clayout%3A%28dimensions%3A%28height%3A1884%2Cwidth%3A1733%29%2Cid%3Apreserve_layout%29%2CobjectType%3Adashboard%2CrelativeUrls%3A%21%28%27%2Fapp%2Fkibana%23%2Fdashboard%2Fedf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b%3F_a%3D%28description%3A%21%27Analyze%2520mock%2520web%2520traffic%2520log%2520data%2520for%2520Elastic%21%21%21%27s%2520website%21%27%2Cfilters%3A%21%21%28%29%2CfullScreenMode%3A%21%21f%2Coptions%3A%28hidePanelTitles%3A%21%21f%2CuseMargins%3A%21%21t%29%2Cpanels%3A%21%21%28%28embeddableConfig%3A%28vis%3A%28colors%3A%28%21%27Avg.%2520Bytes%21%27%3A%25236ED0E0%2C%21%27Unique%2520Visitors%21%27%3A%25230A437C%29%2ClegendOpen%3A%21%21f%29%29%2CgridData%3A%28h%3A13%2Ci%3A%21%272%21%27%2Cw%3A21%2Cx%3A27%2Cy%3A11%29%2Cid%3Ae1d0f010-9ee7-11e7-8711-e7a007dcef99%2CpanelIndex%3A%21%272%21%27%2Ctype%3Avisualization%2Cversion%3A%21%277.7.0%21%27%29%2C%28embeddableConfig%3A%28%29%2CgridData%3A%28h%3A18%2Ci%3A%21%274%21%27%2Cw%3A24%2Cx%3A0%2Cy%3A49%29%2Cid%3A%21%2706cf9c40-9ee8-11e7-8711-e7a007dcef99%21%27%2CpanelIndex%3A%21%274%21%27%2Ctype%3Avisualization%2Cversion%3A%21%277.7.0%21%27%29%2C%28embeddableConfig%3A%28vis%3A%28defaultColors%3A%28%21%270%2520-%252022%21%27%3A%21%27rgb%28247%2C251%2C255%29%21%27%2C%21%2722%2520-%252044%21%27%3A%21%27rgb%28208%2C225%2C242%29%21%27%2C%21%2744%2520-%252066%21%27%3A%21%27rgb%28148%2C196%2C223%29%21%27%2C%21%2766%2520-%252088%21%27%3A%21%27rgb%2874%2C152%2C201%29%21%27%2C%21%2788%2520-%2520110%21%27%3A%21%27rgb%2823%2C100%2C171%29%21%27%29%2ClegendOpen%3A%21%21f%29%29%2CgridData%3A%28h%3A13%2Ci%3A%21%277%21%27%2Cw%3A24%2Cx%3A0%2Cy%3A36%29%2Cid%3A%21%27935afa20-e0cd-11e7-9d07-1398ccfcefa3%21%27%2CpanelIndex%3A%21%277%21%27%2Ctype%3Avisualization%2Cversion%3A%21%277.7.0%21%27%29%2C%28embeddableConfig%3A%28mapCenter%3A%21%21%2836.8092847020594%2C-96.94335937500001%29%2Cvis%3A%28params%3A%28sort%3A%28columnIndex%3A%21%21n%2Cdirection%3A%21%21n%29%29%29%29%2CgridData%3A%28h%3A12%2Ci%3A%21%279%21%27%2Cw%3A21%2Cx%3A27%2Cy%3A24%29%2Cid%3A%21%274eb6e500-e1c7-11e7-b6d5-4dc382ef7f5b%21%27%2CpanelIndex%3A%21%279%21%27%2Ctype%3Avisualization%2Cversion%3A%21%277.7.0%21%27%29%2C%28embeddableConfig%3A%28title%3A%21%27%21%27%2Cvis%3A%28colors%3A%28%21%270%2520-%2520500%21%27%3A%2523BF1B00%2C%21%271000%2520-%25201500%21%27%3A%25237EB26D%2C%21%27500%2520-%25201000%21%27%3A%2523F2C96D%29%2CdefaultColors%3A%28%21%270%2520-%2520500%21%27%3A%21%27rgb%28165%2C0%2C38%29%21%27%2C%21%271000%2520-%25201500%21%27%3A%21%27rgb%280%2C104%2C55%29%21%27%2C%21%27500%2520-%25201000%21%27%3A%21%27rgb%28255%2C255%2C190%29%21%27%29%2ClegendOpen%3A%21%21f%29%29%2CgridData%3A%28h%3A11%2Ci%3A%21%2711%21%27%2Cw%3A9%2Cx%3A10%2Cy%3A0%29%2Cid%3A%21%2769a34b00-9ee8-11e7-8711-e7a007dcef99%21%27%2CpanelIndex%3A%21%2711%21%27%2Ctype%3Avisualization%2Cversion%3A%21%277.7.0%21%27%29%2C%28embeddableConfig%3A%28%29%2CgridData%3A%28h%3A12%2Ci%3A%21%2713%21%27%2Cw%3A27%2Cx%3A0%2Cy%3A24%29%2Cid%3A%21%2742b997f0-0c26-11e8-b0ec-3bb475f6b6ff%21%27%2CpanelIndex%3A%21%2713%21%27%2Ctype%3Avisualization%2Cversion%3A%21%277.7.0%21%27%29%2C%28embeddableConfig%3A%28%29%2CgridData%3A%28h%3A31%2Ci%3A%21%2714%21%27%2Cw%3A24%2Cx%3A24%2Cy%3A36%29%2Cid%3A%21%277cbd2350-2223-11e8-b802-5bcf64c2cfb4%21%27%2CpanelIndex%3A%21%2714%21%27%2Ctype%3Avisualization%2Cversion%3A%21%277.7.0%21%27%29%2C%28embeddableConfig%3A%28%29%2CgridData%3A%28h%3A13%2Ci%3A%21%2715%21%27%2Cw%3A27%2Cx%3A0%2Cy%3A11%29%2Cid%3A%21%27314c6f60-2224-11e8-b802-5bcf64c2cfb4%21%27%2CpanelIndex%3A%21%2715%21%27%2Ctype%3Avisualization%2Cversion%3A%21%277.7.0%21%27%29%2C%28embeddableConfig%3A%28title%3A%21%27%21%27%29%2CgridData%3A%28h%3A11%2Ci%3A%21%2716%21%27%2Cw%3A15%2Cx%3A19%2Cy%3A0%29%2Cid%3A%21%2724a3e970-4257-11e8-b3aa-73fdaf54bfc9%21%27%2CpanelIndex%3A%21%2716%21%27%2Ctype%3Avisualization%2Cversion%3A%21%277.7.0%21%27%29%2C%28embeddableConfig%3A%28vis%3A%28legendOpen%3A%21%21f%29%29%2CgridData%3A%28h%3A11%2Ci%3A%21%2717%21%27%2Cw%3A14%2Cx%3A34%2Cy%3A0%29%2Cid%3A%21%2714e2e710-4258-11e8-b3aa-73fdaf54bfc9%21%27%2CpanelIndex%3A%21%2717%21%27%2Ctype%3Avisualization%2Cversion%3A%21%277.7.0%21%27%29%2C%28embeddableConfig%3A%28title%3A%21%27%21%27%29%2CgridData%3A%28h%3A11%2Ci%3A%21%2718%21%27%2Cw%3A10%2Cx%3A0%2Cy%3A0%29%2Cid%3A%21%2747f2c680-a6e3-11e8-94b4-c30c0228351b%21%27%2CpanelIndex%3A%21%2718%21%27%2Ctype%3Avisualization%2Cversion%3A%21%277.7.0%21%27%29%29%2Cquery%3A%28language%3Akuery%2Cquery%3A%21%27%21%27%29%2CtimeRestore%3A%21%21t%2Ctitle%3A%21%27%255BLogs%255D%2520Web%2520Traffic%21%27%2CviewMode%3Aview%29%26_g%3D%28filters%3A%21%21%28%29%2CrefreshInterval%3A%28pause%3A%21%21f%2Cvalue%3A900000%29%2Ctime%3A%28from%3Anow-7d%2Cto%3Anow%29%29%27%29%2Ctitle%3A%27%5BLogs%5D%20Web%20Traffic%27%29

I can decode the jobParams string and find that it reads as:

(browserTimezone:America/Chicago,layout:(dimensions:(height:1884,width:1733),id:preserve_layout),objectType:dashboard,relativeUrls:!('/app/kibana#/dashboard/edf84fe0-e1a0-11e7-b6d5-4dc382ef7f5b_g=(filters:!!(),refreshInterval:(pause:!!f,value:900000),time:(from:now-7d,to:now))'),title:'[Logs] Web Traffic')

Using this you may be able to modify the bits you need to point to the correct dashboard. The majority of this data comes straight from the Dashboard's URL. I don't have any more detailed guidance than that, but you maybe able to modify the necessary bits and run it again through encodeURIComponent to get the desired result.

Yeah, thanks.

I'd been looking at that as a possible way forward although it seemed like there were subtle differences between the two URLs that I'd need to try and cater for in creating the generation url. I'll take a closer look and see whether I can get something working without too much faff.

Worth a ticket being raised to request this as a feature in an upcoming release?

Certainly. We are actively improving our reporting capabilities and hearing about different use cases is helpful. You can use this link to create a feature request in Github.

https://github.com/elastic/kibana/issues/67420 created, thanks.