Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"extends": [
|
||||
"../../../../.eslintrc.json"
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"!**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx",
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {},
|
||||
"extends": [
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"plugins": ["prettier"]
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# pieces-metabase
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build pieces-metabase` to build the library.
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "@activepieces/piece-metabase",
|
||||
"version": "0.1.22",
|
||||
"dependencies": {
|
||||
"playwright": "1.55.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "pieces-metabase",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/metabase/src",
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/packages/pieces/community/metabase",
|
||||
"tsConfig": "packages/pieces/community/metabase/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/metabase/package.json",
|
||||
"main": "packages/pieces/community/metabase/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/metabase/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/metabase/src/i18n",
|
||||
"output": "./src/i18n",
|
||||
"glob": "**/!(i18n.json)"
|
||||
}
|
||||
],
|
||||
"buildableProjectDepsInPackageJsonType": "dependencies",
|
||||
"updateBuildableProjectDepsInPackageJson": true
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"prebuild"
|
||||
]
|
||||
},
|
||||
"publish": {
|
||||
"command": "node tools/scripts/publish.mjs pieces-metabase {args.ver} {args.tag}",
|
||||
"dependsOn": [
|
||||
"build"
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
]
|
||||
},
|
||||
"prebuild": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"cwd": "packages/pieces/community/metabase",
|
||||
"command": "bun install --no-save --silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
]
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"The simplest way to ask questions and learn from data": "Der einfachste Weg, Fragen zu stellen und von Daten zu lernen",
|
||||
"Metabase API base URL": "Metabase API Basis-URL",
|
||||
"API key": "API-Schlüssel",
|
||||
"Embedding key": "Einbetten Schlüssel",
|
||||
"Generate one on your Metabase instance (settings -> authentication -> API keys)": "Generieren Sie eine in Ihrer Metabase-Instanz (Einstellungen -> Authentifizierung -> API-Schlüssel)",
|
||||
"Needed if you want to generate a graph of a question (settings -> embedding -> static embedding).": "Benötigt wenn Sie ein Diagramm einer Frage generieren möchten (Einstellungen -> Einbetten -> statische Einbetten).",
|
||||
"Metabase authentication requires a baseUrl and a password.": "Metabase Authentifizierung erfordert eine baseUrl und ein Passwort.",
|
||||
"Get question": "Fragen erhalten",
|
||||
"Get Question PNG Preview": "PNG-Vorschau für Fragen abrufen",
|
||||
"Get Dashboard Questions": "Dashboard-Fragen erhalten",
|
||||
"Embed question": "Frage einbetten",
|
||||
"Get the graph of the question": "Graph der Frage abrufen",
|
||||
"Fetch the results of a Metabase question": "Die Ergebnisse einer Metabase-Frage abrufen",
|
||||
"Get PNG preview rendering (low resolution) of a Metabase card/question.": "Erhalte PNG Vorschau Rendering (geringe Auflösung) einer Metabase-Karte/Frage.",
|
||||
"Execute all questions across all tabs in a Metabase dashboard and return their consolidated results in a single response": "Alle Fragen in allen Registerkarten in einem Metabase-Dashboard ausführen und ihre konsolidierten Ergebnisse in einer einzigen Antwort zurückgeben",
|
||||
"Enable embedding for a Metabase question and configure parameters": "Einbetten für eine Metabase-Frage aktivieren und Parameter konfigurieren",
|
||||
"Get the graph of a Metabase question and save it as a png": "Ruft die Grafik einer Metabase-Frage ab und speichert sie als png",
|
||||
"Metabase question ID": "Metabase Frage-ID",
|
||||
"Parameters (slug name -> value)": "Parameter (Slug Name -> Wert)",
|
||||
"Metabase Dashboard ID": "Metabase Dashboard-ID",
|
||||
"Enable embedding": "Einbetten aktivieren",
|
||||
"Parameter settings": "Parametereinstellungen",
|
||||
"The name of the graph (without the extension)": "Der Name des Graphen (ohne Erweiterung)",
|
||||
"Wait Time (seconds)": "Wartezeit (Sekunden)",
|
||||
"Dashboard parameters to apply to all questions": "Dashboard-Parameter für alle Fragen",
|
||||
"Whether to enable embedding for this question": "Gibt an, ob die Einbettung für diese Frage aktiviert wird",
|
||||
"Configure how each parameter should be handled in the embed": "Konfigurieren, wie jeder Parameter in der Einbettung behandelt werden soll",
|
||||
"How long to wait for the graph to render completely in seconds": "Wie lange warten soll, bis der Graph in Sekunden komplett rendert wird"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"The simplest way to ask questions and learn from data": "La forma más sencilla de hacer preguntas y aprender de los datos",
|
||||
"Metabase API base URL": "URL base de la API Metabase",
|
||||
"API key": "Clave API",
|
||||
"Embedding key": "Clave de inserción",
|
||||
"Generate one on your Metabase instance (settings -> authentication -> API keys)": "Generar una en su instancia de Metabase (configuración-> autenticación-> claves API)",
|
||||
"Needed if you want to generate a graph of a question (settings -> embedding -> static embedding).": "Se necesita si desea generar un gráfico de una pregunta (configuración-> incrustación-> incrustación).",
|
||||
"Metabase authentication requires a baseUrl and a password.": "La autenticación de Metabase requiere una URL base y una contraseña.",
|
||||
"Get question": "Obtener pregunta",
|
||||
"Get Question PNG Preview": "Obtener la vista previa PNG de Pregunta",
|
||||
"Get Dashboard Questions": "Obtener preguntas del panel",
|
||||
"Embed question": "Incrustar pregunta",
|
||||
"Get the graph of the question": "Obtener el gráfico de la pregunta",
|
||||
"Fetch the results of a Metabase question": "Obtener los resultados de una pregunta de Metabase",
|
||||
"Get PNG preview rendering (low resolution) of a Metabase card/question.": "Obtener la previsualización PNG (baja resolución) de una tarjeta Metabase/pregunta.",
|
||||
"Execute all questions across all tabs in a Metabase dashboard and return their consolidated results in a single response": "Ejecutar todas las preguntas en todas las pestañas en un panel de Metabase y devolver sus resultados consolidados en una sola respuesta",
|
||||
"Enable embedding for a Metabase question and configure parameters": "Habilitar la incrustación para una pregunta de Metabase y configurar parámetros",
|
||||
"Get the graph of a Metabase question and save it as a png": "Obtener el gráfico de una pregunta de Metabase y guardarla como un png",
|
||||
"Metabase question ID": "ID de pregunta de Metabase",
|
||||
"Parameters (slug name -> value)": "Parámetros (nombre del slug -> valor)",
|
||||
"Metabase Dashboard ID": "ID del tablero de metabasa",
|
||||
"Enable embedding": "Habilitar incrustación",
|
||||
"Parameter settings": "Ajustes de parámetro",
|
||||
"The name of the graph (without the extension)": "El nombre del gráfico (sin la extensión)",
|
||||
"Wait Time (seconds)": "Tiempo de espera (segundos)",
|
||||
"Dashboard parameters to apply to all questions": "Parámetros del panel a aplicar a todas las preguntas",
|
||||
"Whether to enable embedding for this question": "Activar el embebido para esta pregunta",
|
||||
"Configure how each parameter should be handled in the embed": "Configurar como cada parámetro debe ser manejado en el embebido",
|
||||
"How long to wait for the graph to render completely in seconds": "Cuánto tiempo esperar a que el gráfico se renderice completamente en segundos"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"The simplest way to ask questions and learn from data": "La façon la plus simple de poser des questions et d'apprendre des données",
|
||||
"Metabase API base URL": "URL de base de l'API Metabase",
|
||||
"API key": "Clé API",
|
||||
"Embedding key": "Clé d'intégration",
|
||||
"Generate one on your Metabase instance (settings -> authentication -> API keys)": "Générez-en une sur votre instance Metabase (paramètres -> authentification -> clés API)",
|
||||
"Needed if you want to generate a graph of a question (settings -> embedding -> static embedding).": "Nécessaire si vous voulez générer un graphe d'une question (paramètres -> intégration -> intégration statique).",
|
||||
"Metabase authentication requires a baseUrl and a password.": "L'authentification Metabase nécessite une baseUrl et un mot de passe.",
|
||||
"Get question": "Obtenir une question",
|
||||
"Get Question PNG Preview": "Obtenir l'aperçu de la question PNG",
|
||||
"Get Dashboard Questions": "Obtenir des questions sur le tableau de bord",
|
||||
"Embed question": "Intégrer la question",
|
||||
"Get the graph of the question": "Obtenir le graphe de la question",
|
||||
"Fetch the results of a Metabase question": "Récupérer les résultats d'une question de Metabase",
|
||||
"Get PNG preview rendering (low resolution) of a Metabase card/question.": "Obtenir le rendu de l'aperçu PNG (basse résolution) d'une carte/question Metabase.",
|
||||
"Execute all questions across all tabs in a Metabase dashboard and return their consolidated results in a single response": "Exécuter toutes les questions sur tous les onglets d'un tableau de bord Metabase et retourner leurs résultats consolidés en une seule réponse",
|
||||
"Enable embedding for a Metabase question and configure parameters": "Activer l'intégration pour une question Metabase et configurer les paramètres",
|
||||
"Get the graph of a Metabase question and save it as a png": "Récupère le graphique d'une question Metabase et l'enregistre en tant que png",
|
||||
"Metabase question ID": "ID de la question de la métabase",
|
||||
"Parameters (slug name -> value)": "Paramètres (slug name -> value)",
|
||||
"Metabase Dashboard ID": "ID du tableau de bord de la métabase",
|
||||
"Enable embedding": "Activer l'intégration",
|
||||
"Parameter settings": "Paramètres du paramètre",
|
||||
"The name of the graph (without the extension)": "Le nom du graphique (sans extension)",
|
||||
"Wait Time (seconds)": "Temps d'attente (secondes)",
|
||||
"Dashboard parameters to apply to all questions": "Paramètres du tableau de bord à appliquer à toutes les questions",
|
||||
"Whether to enable embedding for this question": "Activer ou non l'intégration pour cette question",
|
||||
"Configure how each parameter should be handled in the embed": "Configurer la façon dont chaque paramètre doit être traité dans l'embed",
|
||||
"How long to wait for the graph to render completely in seconds": "Combien de temps attendre que le graphique soit rendu complètement en secondes"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"The simplest way to ask questions and learn from data": "質問をしたり、データから学ぶ最も簡単な方法",
|
||||
"Metabase API base URL": "Metabase API base URL",
|
||||
"API key": "API キー",
|
||||
"Embedding key": "埋め込みキー",
|
||||
"Generate one on your Metabase instance (settings -> authentication -> API keys)": "Metabaseインスタンスで生成します (設定 → 認証 → APIキー)",
|
||||
"Needed if you want to generate a graph of a question (settings -> embedding -> static embedding).": "質問のグラフを生成する場合に必要です (設定 > 埋め込み -> 静的埋め込み)。",
|
||||
"Metabase authentication requires a baseUrl and a password.": "Metabase認証にはbaseUrlとパスワードが必要です。",
|
||||
"Get question": "質問を取得",
|
||||
"Get Question PNG Preview": "問題PNGのプレビューを取得",
|
||||
"Get Dashboard Questions": "ダッシュボードの質問を取得する",
|
||||
"Embed question": "埋め込みの質問",
|
||||
"Get the graph of the question": "質問のグラフを取得する",
|
||||
"Fetch the results of a Metabase question": "メタベースの質問の結果を取得",
|
||||
"Get PNG preview rendering (low resolution) of a Metabase card/question.": "Metabaseカード/質問のPNGプレビューレンダリング(低解像度)を取得します。",
|
||||
"Execute all questions across all tabs in a Metabase dashboard and return their consolidated results in a single response": "Metabase ダッシュボード内のすべてのタブですべての問題を実行し、統合された結果を一度に返信します",
|
||||
"Enable embedding for a Metabase question and configure parameters": "メタベースの質問への埋め込みを有効にし、パラメータを設定します",
|
||||
"Get the graph of a Metabase question and save it as a png": "Metabase質問のグラフを取得し、png として保存します。",
|
||||
"Metabase question ID": "メタベースの質問ID",
|
||||
"Parameters (slug name -> value)": "パラメータ (スラグ名 -> 値)",
|
||||
"Metabase Dashboard ID": "メタベースダッシュボードID",
|
||||
"Enable embedding": "埋め込みを有効にする",
|
||||
"Parameter settings": "パラメーターの設定",
|
||||
"The name of the graph (without the extension)": "グラフの名前 (拡張子なし)",
|
||||
"Wait Time (seconds)": "待機時間 (秒)",
|
||||
"Dashboard parameters to apply to all questions": "すべての質問に適用するダッシュボードパラメータ",
|
||||
"Whether to enable embedding for this question": "この質問に埋め込みを有効にするかどうか",
|
||||
"Configure how each parameter should be handled in the embed": "各パラメータの埋め込み処理方法を設定します",
|
||||
"How long to wait for the graph to render completely in seconds": "グラフが完全にレンダリングされるまでの時間(秒)"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"The simplest way to ask questions and learn from data": "De eenvoudigste manier om vragen te stellen en te leren van gegevens",
|
||||
"Metabase API base URL": "Metabase API basis-URL",
|
||||
"API key": "API sleutel",
|
||||
"Embedding key": "Sleutel insluiten",
|
||||
"Generate one on your Metabase instance (settings -> authentication -> API keys)": "Genereer een op uw Metabase instantie (instellingen -> authenticatie--> API sleutels)",
|
||||
"Needed if you want to generate a graph of a question (settings -> embedding -> static embedding).": "Nodig als u een grafiek van een vraag wilt genereren (instellingen -> embedding -> statische embedding).",
|
||||
"Metabase authentication requires a baseUrl and a password.": "Metabase authenticatie vereist een baseUrl en een wachtwoord.",
|
||||
"Get question": "Vraag ophalen",
|
||||
"Get Question PNG Preview": "Krijg Vraag PNG Voorbeeld",
|
||||
"Get Dashboard Questions": "Krijg Dashboard Vragen",
|
||||
"Embed question": "Vraag insluiten",
|
||||
"Get the graph of the question": "Bekijk de grafiek van de vraag",
|
||||
"Fetch the results of a Metabase question": "Haal de resultaten van een Metabase vraag op",
|
||||
"Get PNG preview rendering (low resolution) of a Metabase card/question.": "Krijg PNG weergave (lage resolutie) van een Metabase kaart/vraag.",
|
||||
"Execute all questions across all tabs in a Metabase dashboard and return their consolidated results in a single response": "Voer alle vragen uit in alle tabbladen in een Metabase dashboard en geef hun geconsolideerde resultaten in één enkele reactie",
|
||||
"Enable embedding for a Metabase question and configure parameters": "Activeer insluiten voor een Metabase vraag en configureer parameters",
|
||||
"Get the graph of a Metabase question and save it as a png": "Bekijk de grafiek van een Metabase vraag en sla deze op als een png",
|
||||
"Metabase question ID": "Metabase vraag ID",
|
||||
"Parameters (slug name -> value)": "Parameters (slug name -> waarde)",
|
||||
"Metabase Dashboard ID": "Metabase Dashboard ID",
|
||||
"Enable embedding": "Insluiten inschakelen",
|
||||
"Parameter settings": "Parameter instellingen",
|
||||
"The name of the graph (without the extension)": "De naam van de grafiek (zonder de extensie)",
|
||||
"Wait Time (seconds)": "Wachttijd (seconden)",
|
||||
"Dashboard parameters to apply to all questions": "Dashboard parameters om toe te passen op alle vragen",
|
||||
"Whether to enable embedding for this question": "Insluiten inschakelen voor deze vraag",
|
||||
"Configure how each parameter should be handled in the embed": "Stel in hoe elke parameter moet worden afgehandeld in de embed",
|
||||
"How long to wait for the graph to render completely in seconds": "Hoe lang te wachten tot de grafiek volledig in seconden wordt weergegeven"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"The simplest way to ask questions and learn from data": "A maneira mais simples de fazer perguntas e aprender com os dados",
|
||||
"Metabase API base URL": "Metabase URL base da API",
|
||||
"API key": "Chave da API",
|
||||
"Embedding key": "Incorporando a chave",
|
||||
"Generate one on your Metabase instance (settings -> authentication -> API keys)": "Gerar uma em sua instância do Metabase (configurações -> autenticação -> chaves da API)",
|
||||
"Needed if you want to generate a graph of a question (settings -> embedding -> static embedding).": "Necessário se você deseja gerar um gráfico de uma questão (configurações-> incorporação -> incorporação estática).",
|
||||
"Metabase authentication requires a baseUrl and a password.": "A autenticação do Metabase requer uma baseUrl e uma senha.",
|
||||
"Get question": "Obter pergunta",
|
||||
"Get Question PNG Preview": "Obter Pré-visualização de Questões PNG",
|
||||
"Get Dashboard Questions": "Obter perguntas do painel",
|
||||
"Embed question": "Incorporar pergunta",
|
||||
"Get the graph of the question": "Obtenha o gráfico da pergunta",
|
||||
"Fetch the results of a Metabase question": "Obter os resultados de uma pergunta Metabase",
|
||||
"Get PNG preview rendering (low resolution) of a Metabase card/question.": "Obter a pré-visualização PNG (baixa resolução) de um cartão/pergunta de Metabase .",
|
||||
"Execute all questions across all tabs in a Metabase dashboard and return their consolidated results in a single response": "Execute todas as questões em todas as abas em um painel de Metabase e retorne seus resultados consolidados em uma única resposta",
|
||||
"Enable embedding for a Metabase question and configure parameters": "Habilitar a incorporação de uma pergunta Metabase e configurar parâmetros",
|
||||
"Get the graph of a Metabase question and save it as a png": "Obter o gráfico de uma pergunta Metabase e salvá-lo como png",
|
||||
"Metabase question ID": "ID da pergunta Metabase",
|
||||
"Parameters (slug name -> value)": "Parâmetros (nome -> nome do valor)",
|
||||
"Metabase Dashboard ID": "Metabase Dashboard ID",
|
||||
"Enable embedding": "Habilitar incorporação",
|
||||
"Parameter settings": "Definições de parâmetros",
|
||||
"The name of the graph (without the extension)": "O nome do gráfico (sem a extensão)",
|
||||
"Wait Time (seconds)": "Tempo de espera (segundos)",
|
||||
"Dashboard parameters to apply to all questions": "Parâmetros do painel para aplicar a todas as questões",
|
||||
"Whether to enable embedding for this question": "Se deseja habilitar a incorporação desta questão",
|
||||
"Configure how each parameter should be handled in the embed": "Configure como cada parâmetro deve ser tratado na incorporação",
|
||||
"How long to wait for the graph to render completely in seconds": "Quanto tempo espera o gráfico ser completamente renderizado em segundos"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Metabase": "Метабаза",
|
||||
"The simplest way to ask questions and learn from data": "Самый простой способ задавать вопросы и учиться на данных",
|
||||
"Metabase API base URL": "Базовый URL-адрес Metabase API",
|
||||
"API key": "API ключ",
|
||||
"Embedding key": "Встраиваемый ключ",
|
||||
"Generate one on your Metabase instance (settings -> authentication -> API keys)": "Сгенерировать один из экземпляров Metabase (настройки -> аутентификация -> API ключей)",
|
||||
"Needed if you want to generate a graph of a question (settings -> embedding -> static embedding).": "Необходимо, если вы хотите сгенерировать график вопроса (настройки -> встраивание -> статическое встраивание).",
|
||||
"Metabase authentication requires a baseUrl and a password.": "Для аутентификации базы данных требуется baseUrl и пароль.",
|
||||
"Get question": "Получить вопрос",
|
||||
"Get Question PNG Preview": "Получить предварительный просмотр вопроса PNG",
|
||||
"Get Dashboard Questions": "Получить вопросы в меню настроек",
|
||||
"Embed question": "Вставить вопрос",
|
||||
"Get the graph of the question": "Получить график вопроса",
|
||||
"Fetch the results of a Metabase question": "Получить результаты вопроса метабазы",
|
||||
"Get PNG preview rendering (low resolution) of a Metabase card/question.": "Получить PNG предварительный рендеринг (низкое разрешение) Metabase карты/вопроса.",
|
||||
"Execute all questions across all tabs in a Metabase dashboard and return their consolidated results in a single response": "Выполнить все вопросы во всех вкладках панели Metabase и вернуть сводные результаты в один ответ",
|
||||
"Enable embedding for a Metabase question and configure parameters": "Включить встраивание вопроса Metabase и настроить параметры",
|
||||
"Get the graph of a Metabase question and save it as a png": "Получить график метабазисного вопроса и сохранить его как png",
|
||||
"Metabase question ID": "ID метабазового вопроса",
|
||||
"Parameters (slug name -> value)": "Параметры (slug name -> значение)",
|
||||
"Metabase Dashboard ID": "ID панели Metabase",
|
||||
"Enable embedding": "Включить вставку",
|
||||
"Parameter settings": "Настройки параметров",
|
||||
"The name of the graph (without the extension)": "Название графика (без расширения)",
|
||||
"Wait Time (seconds)": "Время ожидания (секунд)",
|
||||
"Dashboard parameters to apply to all questions": "Параметры приборной панели для всех вопросов",
|
||||
"Whether to enable embedding for this question": "Включить ли встраивание этого вопроса",
|
||||
"Configure how each parameter should be handled in the embed": "Настройте как каждый параметр должен быть обработан в виде вставки",
|
||||
"How long to wait for the graph to render completely in seconds": "Как долго ждать полной отрисовки графика в секундах"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"The simplest way to ask questions and learn from data": "The simplest way to ask questions and learn from data",
|
||||
"Metabase API base URL": "Metabase API base URL",
|
||||
"API key": "API key",
|
||||
"Embedding key": "Embedding key",
|
||||
"Generate one on your Metabase instance (settings -> authentication -> API keys)": "Generate one on your Metabase instance (settings -> authentication -> API keys)",
|
||||
"Needed if you want to generate a graph of a question (settings -> embedding -> static embedding).": "Needed if you want to generate a graph of a question (settings -> embedding -> static embedding).",
|
||||
"Metabase authentication requires a baseUrl and a password.": "Metabase authentication requires a baseUrl and a password.",
|
||||
"Get question": "Get question",
|
||||
"Get Question PNG Preview": "Get Question PNG Preview",
|
||||
"Get Dashboard Questions": "Get Dashboard Questions",
|
||||
"Embed question": "Embed question",
|
||||
"Get the graph of the question": "Get the graph of the question",
|
||||
"Fetch the results of a Metabase question": "Fetch the results of a Metabase question",
|
||||
"Get PNG preview rendering (low resolution) of a Metabase card/question.": "Get PNG preview rendering (low resolution) of a Metabase card/question.",
|
||||
"Execute all questions across all tabs in a Metabase dashboard and return their consolidated results in a single response": "Execute all questions across all tabs in a Metabase dashboard and return their consolidated results in a single response",
|
||||
"Enable embedding for a Metabase question and configure parameters": "Enable embedding for a Metabase question and configure parameters",
|
||||
"Get the graph of a Metabase question and save it as a png": "Get the graph of a Metabase question and save it as a png",
|
||||
"Metabase question ID": "Metabase question ID",
|
||||
"Parameters (slug name -> value)": "Parameters (slug name -> value)",
|
||||
"Metabase Dashboard ID": "Metabase Dashboard ID",
|
||||
"Enable embedding": "Enable embedding",
|
||||
"Parameter settings": "Parameter settings",
|
||||
"The name of the graph (without the extension)": "The name of the graph (without the extension)",
|
||||
"Wait Time (seconds)": "Wait Time (seconds)",
|
||||
"Dashboard parameters to apply to all questions": "Dashboard parameters to apply to all questions",
|
||||
"Whether to enable embedding for this question": "Whether to enable embedding for this question",
|
||||
"Configure how each parameter should be handled in the embed": "Configure how each parameter should be handled in the embed",
|
||||
"How long to wait for the graph to render completely in seconds": "How long to wait for the graph to render completely in seconds"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Metabase": "Metabase",
|
||||
"The simplest way to ask questions and learn from data": "The simplest way to ask questions and learn from data",
|
||||
"Metabase API base URL": "Metabase API base URL",
|
||||
"API key": "API key",
|
||||
"Embedding key": "Embedding key",
|
||||
"Generate one on your Metabase instance (settings -> authentication -> API keys)": "Generate one on your Metabase instance (settings -> authentication -> API keys)",
|
||||
"Needed if you want to generate a graph of a question (settings -> embedding -> static embedding).": "Needed if you want to generate a graph of a question (settings -> embedding -> static embedding).",
|
||||
"Metabase authentication requires a baseUrl and a password.": "Metabase authentication requires a baseUrl and a password.",
|
||||
"Get question": "Get question",
|
||||
"Get Question PNG Preview": "Get Question PNG Preview",
|
||||
"Get Dashboard Questions": "Get Dashboard Questions",
|
||||
"Embed question": "Embed question",
|
||||
"Get the graph of the question": "Get the graph of the question",
|
||||
"Fetch the results of a Metabase question": "Fetch the results of a Metabase question",
|
||||
"Get PNG preview rendering (low resolution) of a Metabase card/question.": "Get PNG preview rendering (low resolution) of a Metabase card/question.",
|
||||
"Execute all questions across all tabs in a Metabase dashboard and return their consolidated results in a single response": "Execute all questions across all tabs in a Metabase dashboard and return their consolidated results in a single response",
|
||||
"Enable embedding for a Metabase question and configure parameters": "Enable embedding for a Metabase question and configure parameters",
|
||||
"Get the graph of a Metabase question and save it as a png": "Get the graph of a Metabase question and save it as a png",
|
||||
"Metabase question ID": "Metabase question ID",
|
||||
"Parameters (slug name -> value)": "Parameters (slug name -> value)",
|
||||
"Metabase Dashboard ID": "Metabase Dashboard ID",
|
||||
"Enable embedding": "Enable embedding",
|
||||
"Parameter settings": "Parameter settings",
|
||||
"The name of the graph (without the extension)": "The name of the graph (without the extension)",
|
||||
"Wait Time (seconds)": "Wait Time (seconds)",
|
||||
"Dashboard parameters to apply to all questions": "Dashboard parameters to apply to all questions",
|
||||
"Whether to enable embedding for this question": "Whether to enable embedding for this question",
|
||||
"Configure how each parameter should be handled in the embed": "Configure how each parameter should be handled in the embed",
|
||||
"How long to wait for the graph to render completely in seconds": "How long to wait for the graph to render completely in seconds"
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"The simplest way to ask questions and learn from data": "The simplest way to ask questions and learn from data",
|
||||
"Metabase API base URL": "Metabase API base URL",
|
||||
"API key": "API key",
|
||||
"Embedding key": "Embedding key",
|
||||
"Generate one on your Metabase instance (settings -> authentication -> API keys)": "Generate one on your Metabase instance (settings -> authentication -> API keys)",
|
||||
"Needed if you want to generate a graph of a question (settings -> embedding -> static embedding).": "Needed if you want to generate a graph of a question (settings -> embedding -> static embedding).",
|
||||
"Metabase authentication requires a baseUrl and a password.": "Metabase authentication requires a baseUrl and a password.",
|
||||
"Get question": "Get question",
|
||||
"Get Question PNG Preview": "Get Question PNG Preview",
|
||||
"Get Dashboard Questions": "Get Dashboard Questions",
|
||||
"Embed question": "Embed question",
|
||||
"Get the graph of the question": "Get the graph of the question",
|
||||
"Fetch the results of a Metabase question": "Fetch the results of a Metabase question",
|
||||
"Get PNG preview rendering (low resolution) of a Metabase card/question.": "Get PNG preview rendering (low resolution) of a Metabase card/question.",
|
||||
"Execute all questions across all tabs in a Metabase dashboard and return their consolidated results in a single response": "Execute all questions across all tabs in a Metabase dashboard and return their consolidated results in a single response",
|
||||
"Enable embedding for a Metabase question and configure parameters": "Enable embedding for a Metabase question and configure parameters",
|
||||
"Get the graph of a Metabase question and save it as a png": "Get the graph of a Metabase question and save it as a png",
|
||||
"Metabase question ID": "Metabase question ID",
|
||||
"Parameters (slug name -> value)": "Parameters (slug name -> value)",
|
||||
"Metabase Dashboard ID": "Metabase Dashboard ID",
|
||||
"Enable embedding": "Enable embedding",
|
||||
"Parameter settings": "Parameter settings",
|
||||
"The name of the graph (without the extension)": "The name of the graph (without the extension)",
|
||||
"Wait Time (seconds)": "Wait Time (seconds)",
|
||||
"Dashboard parameters to apply to all questions": "Dashboard parameters to apply to all questions",
|
||||
"Whether to enable embedding for this question": "Whether to enable embedding for this question",
|
||||
"Configure how each parameter should be handled in the embed": "Configure how each parameter should be handled in the embed",
|
||||
"How long to wait for the graph to render completely in seconds": "How long to wait for the graph to render completely in seconds"
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import {
|
||||
createPiece,
|
||||
PieceAuth,
|
||||
Property,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { getQuestion } from './lib/actions/get-question';
|
||||
import { getQuestionPngPreview } from './lib/actions/get-png-rendering';
|
||||
import { getDashboardQuestions } from './lib/actions/get-dashboard';
|
||||
import { queryMetabaseApi } from './lib/common';
|
||||
import { HttpMethod, is_chromium_installed } from '@activepieces/pieces-common';
|
||||
import { getGraphQuestion } from './lib/actions/get-graph-question';
|
||||
import { embedQuestion } from './lib/actions/embed-question';
|
||||
import { AppConnectionType } from '@activepieces/shared';
|
||||
|
||||
const baseProps = {
|
||||
baseUrl: Property.ShortText({
|
||||
displayName: 'Metabase API base URL',
|
||||
required: true,
|
||||
}),
|
||||
apiKey: PieceAuth.SecretText({
|
||||
displayName: 'API key',
|
||||
description:
|
||||
'Generate one on your Metabase instance (settings -> authentication -> API keys)',
|
||||
required: true,
|
||||
}),
|
||||
};
|
||||
|
||||
const authProps = is_chromium_installed()
|
||||
? {
|
||||
...baseProps,
|
||||
embeddingKey: Property.ShortText({
|
||||
displayName: 'Embedding key',
|
||||
description:
|
||||
'Needed if you want to generate a graph of a question (settings -> embedding -> static embedding).',
|
||||
required: false,
|
||||
}),
|
||||
}
|
||||
: baseProps;
|
||||
|
||||
export const metabaseAuth = PieceAuth.CustomAuth({
|
||||
description: 'Metabase authentication requires a baseUrl and a password.',
|
||||
required: true,
|
||||
props: authProps,
|
||||
|
||||
validate: async ({ auth }) => {
|
||||
try {
|
||||
await queryMetabaseApi(
|
||||
{
|
||||
endpoint: 'login-history/current',
|
||||
method: HttpMethod.GET,
|
||||
},
|
||||
{
|
||||
type: AppConnectionType.CUSTOM_AUTH,
|
||||
props: auth,
|
||||
}
|
||||
);
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Invalid API Key or base URL',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const metabase = createPiece({
|
||||
displayName: 'Metabase',
|
||||
description: 'The simplest way to ask questions and learn from data',
|
||||
|
||||
auth: metabaseAuth,
|
||||
minimumSupportedRelease: '0.30.0',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/metabase.png',
|
||||
authors: ['AdamSelene', 'abuaboud', 'valentin-mourtialon', 'Kevinyu-alan'],
|
||||
actions: [
|
||||
getQuestion,
|
||||
getQuestionPngPreview,
|
||||
getDashboardQuestions,
|
||||
embedQuestion,
|
||||
...(is_chromium_installed() ? [getGraphQuestion] : []),
|
||||
],
|
||||
triggers: [],
|
||||
});
|
||||
@@ -0,0 +1,143 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { queryMetabaseApi } from '../common';
|
||||
import { metabaseAuth } from '../..';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
interface MetabaseParam {
|
||||
id: string;
|
||||
slug: string;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export const embedQuestion = createAction({
|
||||
name: 'embedQuestion',
|
||||
auth: metabaseAuth,
|
||||
requireAuth: true,
|
||||
displayName: 'Embed question',
|
||||
description:
|
||||
'Enable embedding for a Metabase question and configure parameters',
|
||||
props: {
|
||||
questionId: Property.ShortText({
|
||||
displayName: 'Metabase question ID',
|
||||
required: true,
|
||||
}),
|
||||
enableEmbedding: Property.Checkbox({
|
||||
displayName: 'Enable embedding',
|
||||
description: 'Whether to enable embedding for this question',
|
||||
required: true,
|
||||
defaultValue: true,
|
||||
}),
|
||||
parameterSettings: Property.DynamicProperties<false, typeof metabaseAuth>({
|
||||
displayName: 'Parameter settings',
|
||||
auth: metabaseAuth,
|
||||
description:
|
||||
'Configure how each parameter should be handled in the embed',
|
||||
required: false,
|
||||
refreshers: ['questionId', 'enableEmbedding'],
|
||||
props: async ({ auth, questionId, enableEmbedding }) => {
|
||||
if (!questionId || !enableEmbedding || !auth) {
|
||||
return {};
|
||||
}
|
||||
|
||||
try {
|
||||
const card = await queryMetabaseApi(
|
||||
{
|
||||
endpoint: `card/${(questionId as string).split('-')[0]}`,
|
||||
method: HttpMethod.GET,
|
||||
},
|
||||
auth
|
||||
);
|
||||
|
||||
const parameters = (card['parameters'] as MetabaseParam[]) || [];
|
||||
const props: Record<string, any> = {};
|
||||
|
||||
// Get current embedding settings if they exist
|
||||
const currentEmbeddingParams = card.embedding_params || {};
|
||||
|
||||
parameters.forEach((param) => {
|
||||
const paramName = param.name || param.slug;
|
||||
const currentSetting =
|
||||
currentEmbeddingParams[param.slug] || 'disabled';
|
||||
|
||||
props[param.slug] = Property.StaticDropdown({
|
||||
displayName: paramName,
|
||||
description: `How to handle parameter: ${paramName}`,
|
||||
required: false,
|
||||
defaultValue: currentSetting,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Disabled', value: 'disabled' },
|
||||
{ label: 'Editable', value: 'enabled' },
|
||||
{ label: 'Locked', value: 'locked' },
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
return props;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const questionId = propsValue.questionId.split('-')[0];
|
||||
|
||||
// First, get the current question details
|
||||
const card = await queryMetabaseApi(
|
||||
{ endpoint: `card/${questionId}`, method: HttpMethod.GET },
|
||||
auth
|
||||
);
|
||||
|
||||
const parameters = (card['parameters'] as MetabaseParam[]) || [];
|
||||
|
||||
const updatePayload = {
|
||||
...card,
|
||||
enable_embedding: propsValue.enableEmbedding,
|
||||
};
|
||||
|
||||
// If parameter settings are provided, update the parameters
|
||||
// Create embedding_params object if parameter settings are provided
|
||||
if (propsValue.parameterSettings && parameters.length > 0) {
|
||||
const embeddingParams: Record<string, string> = {};
|
||||
|
||||
parameters.forEach((param) => {
|
||||
const paramSetting = propsValue.parameterSettings?.[
|
||||
param.slug
|
||||
] as string;
|
||||
if (paramSetting) {
|
||||
embeddingParams[param.slug] = paramSetting;
|
||||
} else {
|
||||
embeddingParams[param.slug] = 'disabled';
|
||||
}
|
||||
});
|
||||
|
||||
updatePayload.embedding_params = embeddingParams;
|
||||
}
|
||||
|
||||
// Update the card with embedding settings
|
||||
const response = await queryMetabaseApi(
|
||||
{
|
||||
endpoint: `card/${questionId}`,
|
||||
method: HttpMethod.PUT,
|
||||
body: updatePayload,
|
||||
},
|
||||
auth
|
||||
);
|
||||
|
||||
if (response.error) {
|
||||
throw new Error(response.error);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: propsValue.enableEmbedding
|
||||
? 'Question embedding has been enabled successfully'
|
||||
: 'Question embedding has been disabled successfully',
|
||||
embeddingParams: propsValue.enableEmbedding
|
||||
? updatePayload.embedding_params
|
||||
: {},
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,156 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { queryMetabaseApi } from '../common';
|
||||
import { metabaseAuth } from '../..';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
interface MetabaseParam {
|
||||
id: string;
|
||||
name?: string;
|
||||
slug?: string;
|
||||
type?: string;
|
||||
values_source_config?: {
|
||||
values?: unknown[];
|
||||
};
|
||||
}
|
||||
interface CardResult {
|
||||
name: string;
|
||||
data?: unknown;
|
||||
error?: string;
|
||||
}
|
||||
interface DashboardParameter {
|
||||
id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
type: string;
|
||||
possible_values?: unknown[];
|
||||
}
|
||||
|
||||
interface DashboardResult {
|
||||
dashboard_name: string;
|
||||
available_parameters: DashboardParameter[];
|
||||
cards_results: Record<string, CardResult>;
|
||||
}
|
||||
|
||||
export const getDashboardQuestions = createAction({
|
||||
name: 'getDashboardQuestions',
|
||||
auth: metabaseAuth,
|
||||
requireAuth: true,
|
||||
displayName: 'Get Dashboard Questions',
|
||||
description:
|
||||
'Execute all questions across all tabs in a Metabase dashboard and return their consolidated results in a single response',
|
||||
props: {
|
||||
dashboardId: Property.ShortText({
|
||||
displayName: 'Metabase Dashboard ID',
|
||||
required: true,
|
||||
}),
|
||||
parameters: Property.Object({
|
||||
displayName: 'Parameters (slug name -> value)',
|
||||
description: 'Dashboard parameters to apply to all questions',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const dashboardId = propsValue.dashboardId.split('-')[0];
|
||||
|
||||
const dashboardData = await queryMetabaseApi(
|
||||
{ endpoint: `dashboard/${dashboardId}`, method: HttpMethod.GET },
|
||||
auth
|
||||
);
|
||||
|
||||
if (dashboardData.error) {
|
||||
throw new Error(`Error fetching dashboard: ${dashboardData.error}`);
|
||||
}
|
||||
|
||||
const dashboardParameters = dashboardData.parameters || [];
|
||||
|
||||
const result: DashboardResult = {
|
||||
dashboard_name: dashboardData.name || 'Unknown Dashboard',
|
||||
available_parameters: dashboardParameters.map((param: MetabaseParam) => ({
|
||||
id: param.id,
|
||||
name: param.name || 'Unknown',
|
||||
slug: param.slug || '',
|
||||
type: param.type || '',
|
||||
possible_values: param.values_source_config?.values || [],
|
||||
})),
|
||||
cards_results: {},
|
||||
};
|
||||
|
||||
// Execute each card and collect results
|
||||
for (const dashcard of dashboardData.dashcards || []) {
|
||||
const cardId = dashcard.card_id;
|
||||
const dashcardId = dashcard.id;
|
||||
|
||||
if (!cardId) continue;
|
||||
|
||||
let cardName = 'Unknown';
|
||||
if (dashcard.card && typeof dashcard.card === 'object') {
|
||||
cardName = dashcard.card.name || `Card ${cardId}`;
|
||||
}
|
||||
|
||||
const cardParameters = [];
|
||||
|
||||
// Map dashboard parameters to card parameters using parameter_mappings
|
||||
if (propsValue.parameters && dashcard.parameter_mappings) {
|
||||
for (const mapping of dashcard.parameter_mappings) {
|
||||
const paramId = mapping.parameter_id;
|
||||
|
||||
// Find corresponding dashboard parameter
|
||||
const dashParam = dashboardParameters.find(
|
||||
(p: { id: string }) => p.id === paramId
|
||||
);
|
||||
|
||||
if (
|
||||
dashParam &&
|
||||
dashParam.slug &&
|
||||
propsValue.parameters[dashParam.slug] !== undefined
|
||||
) {
|
||||
cardParameters.push({
|
||||
id: paramId,
|
||||
target: mapping.target,
|
||||
type: dashParam.type,
|
||||
value: propsValue.parameters[dashParam.slug],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const cardResult = await queryMetabaseApi(
|
||||
{
|
||||
endpoint: `dashboard/${dashboardId}/dashcard/${dashcardId}/card/${cardId}/query/json`,
|
||||
method: HttpMethod.POST,
|
||||
body: {
|
||||
parameters: cardParameters,
|
||||
},
|
||||
},
|
||||
auth
|
||||
);
|
||||
|
||||
const cardIdStr = String(cardId);
|
||||
result.cards_results[cardIdStr] = {
|
||||
name: cardName,
|
||||
data: cardResult,
|
||||
};
|
||||
} catch (error: unknown) {
|
||||
let errorMessage = 'Unknown error';
|
||||
|
||||
if (
|
||||
error &&
|
||||
typeof error === 'object' &&
|
||||
'message' in error &&
|
||||
typeof error.message === 'string'
|
||||
) {
|
||||
errorMessage = error.message;
|
||||
}
|
||||
|
||||
const cardIdStr = String(cardId);
|
||||
result.cards_results[cardIdStr] = {
|
||||
name: cardName,
|
||||
error: `Failed to execute: ${errorMessage}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,135 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { metabaseAuth } from '../..';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
export const getGraphQuestion = createAction({
|
||||
name: 'getGraphQuestion',
|
||||
auth: metabaseAuth,
|
||||
requireAuth: true,
|
||||
displayName: 'Get the graph of the question',
|
||||
description: 'Get the graph of a Metabase question and save it as a png',
|
||||
props: {
|
||||
questionId: Property.ShortText({
|
||||
displayName: 'Metabase question ID',
|
||||
required: true,
|
||||
}),
|
||||
parameters: Property.Object({
|
||||
displayName: 'Parameters (slug name -> value)',
|
||||
required: false,
|
||||
}),
|
||||
graphName: Property.ShortText({
|
||||
displayName: 'The name of the graph (without the extension)',
|
||||
required: false,
|
||||
}),
|
||||
waitTime: Property.Number({
|
||||
displayName: 'Wait Time (seconds)',
|
||||
description:
|
||||
'How long to wait for the graph to render completely in seconds',
|
||||
required: true,
|
||||
defaultValue: 5,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue, files }) {
|
||||
if ('embeddingKey' in auth && !auth.embeddingKey)
|
||||
return 'An embedding key is needed.';
|
||||
|
||||
if (propsValue.waitTime <= 0)
|
||||
return 'The wait time needs to be superior to 0';
|
||||
|
||||
const questionId = propsValue.questionId.split('-')[0];
|
||||
const numericQuestionId = parseInt(questionId);
|
||||
|
||||
const payload = {
|
||||
resource: { question: numericQuestionId },
|
||||
params: propsValue.parameters,
|
||||
exp: Math.round(Date.now() / 1000) + 10 * 60,
|
||||
};
|
||||
|
||||
// @ts-expect-error we expect an embedding key if the user can use this action.
|
||||
const token = jwt.sign(payload, auth.embeddingKey);
|
||||
const graphName = propsValue.graphName
|
||||
? propsValue.graphName + '.png'
|
||||
: `metabase_question_${questionId}.png`;
|
||||
|
||||
const iframeUrl =
|
||||
auth.props.baseUrl +
|
||||
'/embed/question/' +
|
||||
token +
|
||||
'#bordered=true&titled=true';
|
||||
|
||||
const browser = await chromium.launch({
|
||||
headless: true,
|
||||
chromiumSandbox: false,
|
||||
executablePath: '/usr/bin/chromium',
|
||||
});
|
||||
|
||||
try {
|
||||
const context = await browser.newContext({
|
||||
viewport: {
|
||||
width: 1600,
|
||||
height: 1200,
|
||||
},
|
||||
deviceScaleFactor: 2,
|
||||
});
|
||||
|
||||
const page = await context.newPage();
|
||||
|
||||
const response = await page.goto(iframeUrl, {
|
||||
waitUntil: 'networkidle',
|
||||
timeout: 30000,
|
||||
});
|
||||
|
||||
if (!response || !response.ok()) {
|
||||
throw new Error(
|
||||
`Page load failed with status: ${response ? response.status() : 400}`
|
||||
);
|
||||
}
|
||||
|
||||
// we wait so the graph can load
|
||||
await page.waitForTimeout(propsValue.waitTime * 1000);
|
||||
|
||||
const mainElement = await page.$('main');
|
||||
let screenshotBuffer;
|
||||
if (mainElement) {
|
||||
screenshotBuffer = await mainElement.screenshot({
|
||||
path: graphName,
|
||||
type: 'png',
|
||||
});
|
||||
} else {
|
||||
screenshotBuffer = await page.screenshot({
|
||||
path: graphName,
|
||||
type: 'png',
|
||||
clip: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 1600,
|
||||
height: 1120, // so it doesn't screenshot the metabase banner
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const fileUrl = await files.write({
|
||||
fileName: graphName,
|
||||
data: screenshotBuffer,
|
||||
});
|
||||
|
||||
return {
|
||||
file: {
|
||||
filename: graphName,
|
||||
base64Content: screenshotBuffer.toString('base64'),
|
||||
download: fileUrl,
|
||||
},
|
||||
iframeUrl,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(
|
||||
'Please verify that either your embedding key and question id are valid or that the question is embedded and published.'
|
||||
);
|
||||
console.error('Error capturing Metabase chart:', error);
|
||||
throw error;
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,48 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { metabaseAuth } from '../..';
|
||||
import { queryMetabaseApi } from '../common';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const getQuestionPngPreview = createAction({
|
||||
name: 'getQuestionPngPreview',
|
||||
auth: metabaseAuth,
|
||||
requireAuth: true,
|
||||
displayName: 'Get Question PNG Preview',
|
||||
description:
|
||||
'Get PNG preview rendering (low resolution) of a Metabase card/question.',
|
||||
props: {
|
||||
questionId: Property.ShortText({
|
||||
displayName: 'Metabase question ID',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue, files }) {
|
||||
const questionId = propsValue.questionId.split('-')[0];
|
||||
|
||||
const response = await queryMetabaseApi(
|
||||
{
|
||||
endpoint: `pulse/preview_card_png/${questionId}`,
|
||||
method: HttpMethod.GET,
|
||||
headers: {
|
||||
Accept: 'image/png',
|
||||
},
|
||||
responseType: 'arraybuffer',
|
||||
},
|
||||
auth
|
||||
);
|
||||
|
||||
if (response.error) {
|
||||
throw new Error(response.error);
|
||||
}
|
||||
|
||||
const fileUrl = await files.write({
|
||||
fileName: `metabase_question_${questionId}.png`,
|
||||
data: Buffer.from(response, 'base64'),
|
||||
});
|
||||
|
||||
return {
|
||||
fileName: `metabase_question_${questionId}.png`,
|
||||
file: fileUrl,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,69 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { queryMetabaseApi } from '../common';
|
||||
import { metabaseAuth } from '../..';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
interface MetabaseParam {
|
||||
id: string;
|
||||
target: unknown[];
|
||||
type: string[];
|
||||
slug: string;
|
||||
}
|
||||
|
||||
export const getQuestion = createAction({
|
||||
name: 'getQuestion',
|
||||
auth: metabaseAuth,
|
||||
requireAuth: true,
|
||||
displayName: 'Get question',
|
||||
description: 'Fetch the results of a Metabase question',
|
||||
props: {
|
||||
questionId: Property.ShortText({
|
||||
displayName: 'Metabase question ID',
|
||||
required: true,
|
||||
}),
|
||||
parameters: Property.Object({
|
||||
displayName: 'Parameters (slug name -> value)',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const questionId = propsValue.questionId.split('-')[0];
|
||||
const card = await queryMetabaseApi(
|
||||
{ endpoint: `card/${questionId}`, method: HttpMethod.GET },
|
||||
auth
|
||||
);
|
||||
const parameters = card['parameters'] as MetabaseParam[];
|
||||
|
||||
const response = await queryMetabaseApi(
|
||||
{
|
||||
endpoint: `card/${questionId}/query`,
|
||||
method: HttpMethod.POST,
|
||||
body: {
|
||||
collection_preview: false,
|
||||
ignore_cache: false,
|
||||
parameters: parameters
|
||||
.filter(
|
||||
(param) =>
|
||||
propsValue.parameters &&
|
||||
propsValue.parameters[param.slug] !== undefined
|
||||
)
|
||||
.map((param) => {
|
||||
return {
|
||||
id: param.id,
|
||||
target: param.target,
|
||||
type: param.type,
|
||||
value:
|
||||
propsValue.parameters && propsValue.parameters[param.slug],
|
||||
};
|
||||
}),
|
||||
},
|
||||
},
|
||||
auth
|
||||
);
|
||||
if (response.error) {
|
||||
throw new Error(response.error);
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,40 @@
|
||||
import {
|
||||
httpClient,
|
||||
HttpHeaders,
|
||||
HttpMethod,
|
||||
HttpRequest,
|
||||
QueryParams,
|
||||
} from '@activepieces/pieces-common';
|
||||
import {
|
||||
AppConnectionValueForAuthProperty,
|
||||
CustomAuthProps,
|
||||
StaticPropsValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { metabaseAuth } from '..';
|
||||
|
||||
export async function queryMetabaseApi(
|
||||
params: {
|
||||
endpoint: string;
|
||||
method: HttpMethod;
|
||||
queryParams?: QueryParams;
|
||||
headers?: HttpHeaders;
|
||||
body?: object;
|
||||
responseType?: 'arraybuffer' | 'json' | 'blob' | 'text';
|
||||
},
|
||||
auth: AppConnectionValueForAuthProperty<typeof metabaseAuth>
|
||||
) {
|
||||
const request: HttpRequest = {
|
||||
method: params.method,
|
||||
url: `${auth.props.baseUrl}/api/${params.endpoint}`,
|
||||
queryParams: params.queryParams,
|
||||
headers: {
|
||||
...params.headers,
|
||||
'Content-Type': 'application/json',
|
||||
'X-API-KEY': auth.props.apiKey,
|
||||
},
|
||||
body: JSON.stringify(params.body),
|
||||
responseType: params.responseType,
|
||||
};
|
||||
const response = await httpClient.sendRequest(request);
|
||||
return response.body;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": false,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"exclude": ["node_modules"],
|
||||
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "node_modules"],
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user