Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accept viewport size as an argument for a proper screenshot of the large pivot table #15

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,16 @@ Redashbot V2 is a open-source slack bot for [Redash](https://redash.io).
- Table
- `@botname <Query URL>#table`
- e.g. `@redash https://your-redash-server.example.com/queries/1#table`


You can add the following additional arguments to the command.

- e.g. `@botname https://your-redash-server.example.com/queries/1#2 rb_width=1280`

| key | description | default |
| --- | --- | --- |
| rb_width | Specify viewport width | 1024 |
| rb_hight | Specify viewport height | 360 |

## Setup

[Create a Slack app](https://api.slack.com/apps/) and set environment variables `SLACK_BOT_TOKEN` and `SLACK_SIGNING_SECRET`.
Expand Down
4 changes: 2 additions & 2 deletions src/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ export class Browser {
}
}

async capture(url: string): Promise<Buffer> {
async capture(url: string, width: number, height: number): Promise<Buffer> {
if (!this.browser) {
this.browser = await launch(config.browser, this.options)
}

const page = await this.browser.newPage()
page.setViewportSize({ width: 1024, height: 360 })
page.setViewportSize({ width: width, height: height })
await page.goto(url, { timeout: config.browserTimeout })
try {
const waitFor = url.includes('/query/') ? /results/ : /events/
Expand Down
28 changes: 25 additions & 3 deletions src/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,25 @@ type Middleware = (args: {
}) => Promise<void>

export type Handler = (ctx: { redash: Redash; browser: Browser }) => Middleware
export type CommandOptions = { width: number, height: number}

function prepareOptions(input: string): CommandOptions {
const regex = /rb_(\w+)=([\w\d]+)/g;

const args = {};
let match;
while ((match = regex.exec(input)) !== null) {
const [_, key, value] = match;
args[key] = value;
}

const options: CommandOptions = {
width: parseInt(args["width"]) || 1024,
height: parseInt(args["height"]) || 360,
};

return options;
}

export const handleRecordChart: Handler = ({ redash, browser }) => {
return async ({ context, client, message }) => {
Expand All @@ -28,7 +47,8 @@ export const handleRecordChart: Handler = ({ redash, browser }) => {
const embedUrl = `${redash.alias}/embed/query/${queryId}/visualization/${visualizationId}?api_key=${redash.apiKey}`
const filename = `${query.name}-${visualization?.name}-query-${queryId}-visualization-${visualizationId}.png`

const file = await browser.capture(embedUrl)
const options = prepareOptions(context.matches.input)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several candidate methods for obtaining input values.
The motivation for retrieving from matches.input is to also cover workflow steps, slash command

const file = await browser.capture(embedUrl, options.width, options.height)
client.files.uploadV2({
channels: message.channel,
filename,
Expand All @@ -47,7 +67,8 @@ export const handleRecordDashboardLegacy: Handler = ({ redash, browser }) => {

const dashboard = await redash.getDashboardLegacy(dashboardSlug)
const filename = `${dashboard.name}-dashboard-${dashboardSlug}.png`
const file = await browser.capture(dashboard.public_url)
const options = prepareOptions(context.matches.input)
const file = await browser.capture(dashboard.public_url, options.width, options.height)
client.files.uploadV2({
channels: message.channel,
filename,
Expand All @@ -67,7 +88,8 @@ export const handleRecordDashboard: Handler = ({ redash, browser }) => {
const dashboard = await redash.getDashboard(dashboardId)
const filename = `${dashboard.name}-dashboard-${dashboardId}-${dashboardSlug}.png`
if (dashboard.public_url) {
const file = await browser.capture(dashboard.public_url)
const options = prepareOptions(context.matches.input)
const file = await browser.capture(dashboard.public_url, options.width, options.height)
client.files.uploadV2({
channels: message.channel,
filename,
Expand Down