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:
poduck
2025-12-18 22:59:37 -05:00
parent 9848268d34
commit 3aa7199503
16292 changed files with 1284892 additions and 4708 deletions

View File

@@ -0,0 +1,49 @@
{
"Issue tracking for modern software teams": "Fehlerverfolgung für moderne Software-Teams",
"\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.": "\nUm Ihren API-Schlüssel zu erhalten, folgen Sie diesen Schritten:\n\n1. Gehen Sie zu den Einstellungen, indem Sie auf Ihr Profilbild (oben links)\n2 klicken. Gehen Sie in den API-Bereich in Mein Konto.\n3. Auf persönlichen API-Schlüsseln geben Sie Label ein und drücken Sie Erstellen-Schlüssel.",
"Create Issue": "Ticket erstellen",
"Update Issue": "Problem aktualisieren",
"Create Project": "Projekt erstellen",
"Update Project": "Projekt aktualisieren",
"Create Comment": "Kommentar erstellen",
"Raw GraphQL query": "Rohe GraphQL-Abfrage",
"Create a new issue in Linear workspace": "Ein neues Problem im Linear-Arbeitsbereich erstellen",
"Update a issue in Linear Workspace": "Ein Problem im Linear-Arbeitsbereich aktualisieren",
"Create a new project in Linear workspace": "Neues Projekt im linearen Arbeitsbereich erstellen",
"Update a existing project in Linear workspace": "Aktualisiere ein bestehendes Projekt im linearen Arbeitsbereich",
"Create a new comment on an issue in Linear workspace": "Einen neuen Kommentar zu einem Problem im linearen Arbeitsbereich erstellen",
"Perform a raw GraphQL query": "Eine rohe GraphQL-Abfrage ausführen",
"Team": "Team",
"Title": "Titel",
"Description": "Beschreibung",
"Status": "Status",
"Labels": "Etiketten",
"Assignee": "Assignee",
"Priority": "Priorität",
"Template": "Vorlage",
"Issue": "Ticket",
"Project Name": "Projekt Name",
"Icon": "Symbol",
"Color": "Farbe",
"Start Date": "Startdatum",
"Target Date": "Target Date",
"Project": "Projekt",
"Comment Body": "Kommentar-Text",
"Query": "Abfrage",
"Parameters": "Parameter",
"The team for which the issue, project or comment will be created": "Das Team, für das das Problem, Projekt oder Kommentar erstellt wird",
"Status of the Issue": "Status des Problems",
"Labels for the Issue": "Bezeichnungen für den Fall",
"Assignee of the Issue / Comment": "Beauftragter des Problems / Kommentar",
"Priority of the Issue": "Priorität des Problems",
"ID of Template": "ID der Vorlage",
"ID of Linear Issue": "ID des linearen Problems",
"ID of Linear Project": "ID des linearen Projekts",
"The content of the comment": "Der Inhalt des Kommentars",
"New Issue": "Neuer Fall",
"Updated Issue": "Aktualisierter Fall",
"Removed Issue": "Problem entfernt",
"Triggers when Linear receives a new issue": "Wird ausgelöst, wenn Linear ein neues Problem erhält",
"Triggers when an existing Linear issue is updated": "Wird ausgelöst, wenn ein bestehendes lineares Problem aktualisiert wird",
"Triggers when an existing Linear issue is removed": "Wird ausgelöst, wenn ein bestehendes lineares Problem entfernt wird"
}

View File

@@ -0,0 +1,49 @@
{
"Issue tracking for modern software teams": "Seguimiento de problemas para equipos de software modernos",
"\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.": "\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.",
"Create Issue": "Crear asunto",
"Update Issue": "Actualizar problema",
"Create Project": "Crear proyecto",
"Update Project": "Actualizar proyecto",
"Create Comment": "Crear comentario",
"Raw GraphQL query": "Consulta GraphQL Raw",
"Create a new issue in Linear workspace": "Crear un nuevo problema en el área de trabajo lineal",
"Update a issue in Linear Workspace": "Actualizar un problema en el espacio de trabajo lineal",
"Create a new project in Linear workspace": "Crear un nuevo proyecto en el área de trabajo lineal",
"Update a existing project in Linear workspace": "Actualizar un proyecto existente en el área de trabajo lineal",
"Create a new comment on an issue in Linear workspace": "Crear un nuevo comentario sobre un problema en el área de trabajo lineal",
"Perform a raw GraphQL query": "Realizar una consulta GraphQL sin procesar",
"Team": "Equipo",
"Title": "Título",
"Description": "Descripción",
"Status": "Estado",
"Labels": "Etiquetas",
"Assignee": "Assignee",
"Priority": "Prioridad",
"Template": "Plantilla",
"Issue": "Problema",
"Project Name": "Nombre del proyecto",
"Icon": "Icono",
"Color": "Color",
"Start Date": "Fecha de inicio",
"Target Date": "Target Date",
"Project": "Projekt",
"Comment Body": "Comentar cuerpo",
"Query": "Consulta",
"Parameters": "Parámetros",
"The team for which the issue, project or comment will be created": "El equipo para el cual se creará la petición, proyecto o comentario",
"Status of the Issue": "Estado del problema",
"Labels for the Issue": "Etiquetas para el problema",
"Assignee of the Issue / Comment": "Asignado al asunto / Comentario",
"Priority of the Issue": "Prioridad del problema",
"ID of Template": "ID de la plantilla",
"ID of Linear Issue": "ID del problema lineal",
"ID of Linear Project": "ID del proyecto lineal",
"The content of the comment": "El contenido del comentario",
"New Issue": "Nuevo problema",
"Updated Issue": "Problema actualizado",
"Removed Issue": "Problema eliminado",
"Triggers when Linear receives a new issue": "Disparadores cuando el lineal recibe un nuevo problema",
"Triggers when an existing Linear issue is updated": "Dispara cuando se actualiza un problema lineal existente",
"Triggers when an existing Linear issue is removed": "Dispara cuando se elimina un problema lineal existente"
}

View File

@@ -0,0 +1,49 @@
{
"Issue tracking for modern software teams": "Suivi des problèmes pour les équipes logicielles modernes",
"\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.": "\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.",
"Create Issue": "Créer un problème",
"Update Issue": "Mettre à jour le problème",
"Create Project": "Créer un projet",
"Update Project": "Mettre à jour le projet",
"Create Comment": "Créer un commentaire",
"Raw GraphQL query": "Requête GraphQL brute",
"Create a new issue in Linear workspace": "Créer un nouveau ticket dans l'espace de travail linéaire",
"Update a issue in Linear Workspace": "Mettre à jour un problème dans l'espace de travail linéaire",
"Create a new project in Linear workspace": "Créer un nouveau projet dans l'espace de travail linéaire",
"Update a existing project in Linear workspace": "Mettre à jour un projet existant dans l'espace de travail linéaire",
"Create a new comment on an issue in Linear workspace": "Créer un nouveau commentaire sur une anomalie dans l'espace de travail linéaire",
"Perform a raw GraphQL query": "Effectuer une requête GraphQL brute",
"Team": "Équipe",
"Title": "Titre de la page",
"Description": "Libellé",
"Status": "Statut",
"Labels": "Étiquettes",
"Assignee": "Assignee",
"Priority": "Priorité",
"Template": "Gabarit",
"Issue": "Problème",
"Project Name": "Project Name",
"Icon": "Icône",
"Color": "Couleur",
"Start Date": "Date de début",
"Target Date": "Target Date",
"Project": "Projet",
"Comment Body": "Corps du commentaire",
"Query": "Requête",
"Parameters": "Paramètres",
"The team for which the issue, project or comment will be created": "L'équipe pour laquelle le ticket, le projet ou le commentaire seront créés",
"Status of the Issue": "Statut du problème",
"Labels for the Issue": "Étiquettes pour le problème",
"Assignee of the Issue / Comment": "Responsable du ticket / commentaire",
"Priority of the Issue": "Priorité du problème",
"ID of Template": "ID du modèle",
"ID of Linear Issue": "ID du ticket linéaire",
"ID of Linear Project": "ID du projet linéaire",
"The content of the comment": "Le contenu du commentaire",
"New Issue": "Nouveau problème",
"Updated Issue": "Problème mis à jour",
"Removed Issue": "Problème supprimé",
"Triggers when Linear receives a new issue": "Déclenche quand Linear reçoit un nouveau ticket",
"Triggers when an existing Linear issue is updated": "Déclenche quand une anomalie linéaire existante est mise à jour",
"Triggers when an existing Linear issue is removed": "Déclenche quand une anomalie linéaire existante est supprimée"
}

View File

@@ -0,0 +1,49 @@
{
"Issue tracking for modern software teams": "最新のソフトウェアチームの問題追跡中",
"\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.": "\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.",
"Create Issue": "課題を作成",
"Update Issue": "問題を更新",
"Create Project": "プロジェクトを作成",
"Update Project": "プロジェクトを更新",
"Create Comment": "コメントを作成",
"Raw GraphQL query": "生のGraphQLクエリ",
"Create a new issue in Linear workspace": "Linear ワークスペースで新しい課題を作成",
"Update a issue in Linear Workspace": "リニアワークスペースで課題を更新する",
"Create a new project in Linear workspace": "Linear ワークスペースで新しいプロジェクトを作成",
"Update a existing project in Linear workspace": "Linear ワークスペースの既存のプロジェクトを更新する",
"Create a new comment on an issue in Linear workspace": "Linear ワークスペースの課題に新しいコメントを作成する",
"Perform a raw GraphQL query": "生のGraphQLクエリを実行します",
"Team": "Team",
"Title": "タイトル",
"Description": "説明",
"Status": "ステータス",
"Labels": "ラベル",
"Assignee": "Assignee",
"Priority": "優先度",
"Template": "テンプレート",
"Issue": "課題",
"Project Name": "プロジェクト名",
"Icon": "アイコン",
"Color": "色",
"Start Date": "開始日",
"Target Date": "Target Date",
"Project": "プロジェクト",
"Comment Body": "コメント本文",
"Query": "クエリ",
"Parameters": "パラメータ",
"The team for which the issue, project or comment will be created": "課題、プロジェクト、またはコメントが作成されるチーム",
"Status of the Issue": "案件の状況",
"Labels for the Issue": "課題のラベル",
"Assignee of the Issue / Comment": "課題/コメントの担当者",
"Priority of the Issue": "問題の優先度",
"ID of Template": "テンプレートの ID",
"ID of Linear Issue": "Linear IssueのID",
"ID of Linear Project": "線形プロジェクトのID",
"The content of the comment": "コメントの内容",
"New Issue": "新しい課題",
"Updated Issue": "更新された課題",
"Removed Issue": "削除された問題",
"Triggers when Linear receives a new issue": "Linear が新しい課題を受け取ったときに発行する",
"Triggers when an existing Linear issue is updated": "既存のリニアの問題が更新されたときにトリガーします",
"Triggers when an existing Linear issue is removed": "既存の線形問題が削除されたときにトリガーします"
}

View File

@@ -0,0 +1,49 @@
{
"Issue tracking for modern software teams": "Probleem bijhouden voor moderne softwareteams",
"\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.": "\nOm uw API-sleutel te verkrijgen, volg deze stappen:\n\n1. Ga naar instellingen door op uw profiel-pic (linksboven)\n2 te klikken. Ga naar API-sectie in Mijn Account.\n3. Op Persoonlijke API-sleutels geef je het label en druk je op het maken van de sleutel.",
"Create Issue": "Probleem aanmaken",
"Update Issue": "Probleem bijwerken",
"Create Project": "Project aanmaken",
"Update Project": "Project bijwerken",
"Create Comment": "Commentaar maken",
"Raw GraphQL query": "Onbewerkte GraphQL query",
"Create a new issue in Linear workspace": "Maak een nieuw issue in de Lineaire workspace",
"Update a issue in Linear Workspace": "Update een probleem in Linear werkruimte",
"Create a new project in Linear workspace": "Maak een nieuw project in de Lineaire workspace",
"Update a existing project in Linear workspace": "Een bestaand project in Lineaire workspace bijwerken",
"Create a new comment on an issue in Linear workspace": "Maak een nieuwe reactie op een issue in de Lineaire werkruimte",
"Perform a raw GraphQL query": "Een rauwe GraphQL query uitvoeren",
"Team": "Team",
"Title": "Aanspreektitel",
"Description": "Beschrijving",
"Status": "status",
"Labels": "Labels",
"Assignee": "Assignee",
"Priority": "Prioriteit",
"Template": "Sjabloon",
"Issue": "Probleem",
"Project Name": "Projectnaam",
"Icon": "Pictogram",
"Color": "Kleur",
"Start Date": "Start datum",
"Target Date": "Target Date",
"Project": "Project",
"Comment Body": "Commentaar inhoud",
"Query": "Zoekopdracht",
"Parameters": "Parameters",
"The team for which the issue, project or comment will be created": "Het team waarvoor het probleem, project of commentaar zal worden aangemaakt",
"Status of the Issue": "Status van het probleem",
"Labels for the Issue": "Etiketten voor het probleem",
"Assignee of the Issue / Comment": "Toegewezene van de Issue / Opmerking",
"Priority of the Issue": "Prioriteit van het probleem",
"ID of Template": "ID van de sjabloon",
"ID of Linear Issue": "ID van Lineaire Probleem",
"ID of Linear Project": "ID van het Lineair Project",
"The content of the comment": "De inhoud van de opmerking",
"New Issue": "Nieuw probleem",
"Updated Issue": "Probleem bijgewerkt",
"Removed Issue": "Probleem verwijderd",
"Triggers when Linear receives a new issue": "Triggert wanneer Linear een nieuw probleem ontvangt",
"Triggers when an existing Linear issue is updated": "Triggert wanneer een bestaand Lineair probleem wordt bijgewerkt",
"Triggers when an existing Linear issue is removed": "Triggers wanneer een bestaand Lineair probleem wordt verwijderd"
}

View File

@@ -0,0 +1,49 @@
{
"Issue tracking for modern software teams": "Rastreamento de problemas para equipes de software modernas",
"\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.": "\nPara obter a sua chave de API, siga estas etapas:\n\n1. Vá para configurações clicando no seu perfil-pic (top-left)\n2. Vá para a seção API dentro de Minha Conta.\n3. Em chaves de API pessoal, dê rótulo e pressione criar chave.",
"Create Issue": "Criar issue",
"Update Issue": "Atualizar issue",
"Create Project": "Criar Projeto",
"Update Project": "Atualizar Projeto",
"Create Comment": "Criar Comentário",
"Raw GraphQL query": "Consulta de Raw GraphQL",
"Create a new issue in Linear workspace": "Criar um novo problema no espaço de trabalho linear",
"Update a issue in Linear Workspace": "Atualizar um problema no workspace linear",
"Create a new project in Linear workspace": "Criar um novo projeto no espaço de trabalho Linear",
"Update a existing project in Linear workspace": "Atualizar um projeto existente no espaço de trabalho Linear",
"Create a new comment on an issue in Linear workspace": "Criar um novo comentário em uma issue no espaço de trabalho linear",
"Perform a raw GraphQL query": "Execute uma consulta raw do GraphQL",
"Team": "Equipe",
"Title": "Título",
"Description": "Descrição",
"Status": "Estado",
"Labels": "Marcadores",
"Assignee": "Assignee",
"Priority": "Prioridade",
"Template": "Modelo",
"Issue": "Problema",
"Project Name": "Nome do Projeto",
"Icon": "Ícone",
"Color": "Cor",
"Start Date": "Data Inicial",
"Target Date": "Target Date",
"Project": "Projecto",
"Comment Body": "Corpo do Comentário",
"Query": "Requisição",
"Parameters": "Parâmetros",
"The team for which the issue, project or comment will be created": "A equipe para a qual a issue, projeto ou comentário será criada",
"Status of the Issue": "Estado do problema",
"Labels for the Issue": "Etiquetas para a Solicitação",
"Assignee of the Issue / Comment": "Responsável pela Solicitação / Comentário",
"Priority of the Issue": "Prioridade da Solicitação",
"ID of Template": "ID do modelo",
"ID of Linear Issue": "ID do Problema Linear",
"ID of Linear Project": "ID do projeto Linear",
"The content of the comment": "O conteúdo do comentário",
"New Issue": "Nova issue",
"Updated Issue": "Issue atualizada",
"Removed Issue": "Issue removida",
"Triggers when Linear receives a new issue": "Aciona quando Linear recebe uma nova issue",
"Triggers when an existing Linear issue is updated": "Dispara quando uma issue linear existente é atualizada",
"Triggers when an existing Linear issue is removed": "Aciona quando uma issue linear é removida"
}

View File

@@ -0,0 +1,50 @@
{
"Linear": "Линейный",
"Issue tracking for modern software teams": "Отслеживание проблем для современных команд программного обеспечения",
"\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.": "\nДля получения API ключа выполните следующие действия:\n\n1. Перейдите в настройки, нажав на свой профиль-пик (слева сверху)\n2. Перейдите в раздел API внутри My Account.\n3. На персональных API ключах, дайте метку и нажмите клавишу создания.",
"Create Issue": "Создать запрос",
"Update Issue": "Проблема с обновлением",
"Create Project": "Создать проект",
"Update Project": "Обновить проект",
"Create Comment": "Создать комментарий",
"Raw GraphQL query": "Запрос сырых GraphQL",
"Create a new issue in Linear workspace": "Создать новый запрос в линейном проекте",
"Update a issue in Linear Workspace": "Изменить проблему в линейном проекте",
"Create a new project in Linear workspace": "Создать новый проект в линейном проекте",
"Update a existing project in Linear workspace": "Обновить существующий проект в линейном проекте",
"Create a new comment on an issue in Linear workspace": "Создать новый комментарий к задаче в линейном проекте",
"Perform a raw GraphQL query": "Выполнить необработанный запрос GraphQL",
"Team": "Команда",
"Title": "Заголовок",
"Description": "Описание",
"Status": "Статус",
"Labels": "Метки",
"Assignee": "Assignee",
"Priority": "Приоритет",
"Template": "Шаблон",
"Issue": "Выпуск",
"Project Name": "Название проекта",
"Icon": "Иконка",
"Color": "Цвет",
"Start Date": "Дата начала",
"Target Date": "Target Date",
"Project": "Проект",
"Comment Body": "Тело комментария",
"Query": "Запрос",
"Parameters": "Параметры",
"The team for which the issue, project or comment will be created": "Команда, для которой будет создан выпуск, проект или комментарий",
"Status of the Issue": "Статус проблемы",
"Labels for the Issue": "Ярлыки для проблемы",
"Assignee of the Issue / Comment": "Назначенный вопрос / комментарий",
"Priority of the Issue": "Приоритет задачи",
"ID of Template": "ID шаблона",
"ID of Linear Issue": "ID линейной задачи",
"ID of Linear Project": "ID проекта Linear",
"The content of the comment": "Содержание комментария",
"New Issue": "Новая задача",
"Updated Issue": "Задача обновлена",
"Removed Issue": "Удалённая задача",
"Triggers when Linear receives a new issue": "Триггеры при получении новой задачи",
"Triggers when an existing Linear issue is updated": "Триггеры при обновлении существующей линейной проблемы",
"Triggers when an existing Linear issue is removed": "Триггеры при удалении существующей линейной задачи"
}

View File

@@ -0,0 +1,49 @@
{
"Issue tracking for modern software teams": "Issue tracking for modern software teams",
"\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.": "\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.",
"Create Issue": "Create Issue",
"Update Issue": "Update Issue",
"Create Project": "Create Project",
"Update Project": "Update Project",
"Create Comment": "Create Comment",
"Raw GraphQL query": "Raw GraphQL query",
"Create a new issue in Linear workspace": "Create a new issue in Linear workspace",
"Update a issue in Linear Workspace": "Update a issue in Linear Workspace",
"Create a new project in Linear workspace": "Create a new project in Linear workspace",
"Update a existing project in Linear workspace": "Update a existing project in Linear workspace",
"Create a new comment on an issue in Linear workspace": "Create a new comment on an issue in Linear workspace",
"Perform a raw GraphQL query": "Perform a raw GraphQL query",
"Team": "Team",
"Title": "Title",
"Description": "Description",
"Status": "Status",
"Labels": "Labels",
"Assignee": "Assignee",
"Priority": "Priority",
"Template": "Template",
"Issue": "Issue",
"Project Name": "Project Name",
"Icon": "Icon",
"Color": "Color",
"Start Date": "Start Date",
"Target Date": "Target Date",
"Project": "Project",
"Comment Body": "Comment Body",
"Query": "Query",
"Parameters": "Parameters",
"The team for which the issue, project or comment will be created": "The team for which the issue, project or comment will be created",
"Status of the Issue": "Status of the Issue",
"Labels for the Issue": "Labels for the Issue",
"Assignee of the Issue / Comment": "Assignee of the Issue / Comment",
"Priority of the Issue": "Priority of the Issue",
"ID of Template": "ID of Template",
"ID of Linear Issue": "ID of Linear Issue",
"ID of Linear Project": "ID of Linear Project",
"The content of the comment": "The content of the comment",
"New Issue": "New Issue",
"Updated Issue": "Updated Issue",
"Removed Issue": "Removed Issue",
"Triggers when Linear receives a new issue": "Triggers when Linear receives a new issue",
"Triggers when an existing Linear issue is updated": "Triggers when an existing Linear issue is updated",
"Triggers when an existing Linear issue is removed": "Triggers when an existing Linear issue is removed"
}

View File

@@ -0,0 +1,50 @@
{
"Linear": "Linear",
"Issue tracking for modern software teams": "Issue tracking for modern software teams",
"\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.": "\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.",
"Create Issue": "Create Issue",
"Update Issue": "Update Issue",
"Create Project": "Create Project",
"Update Project": "Update Project",
"Create Comment": "Create Comment",
"Raw GraphQL query": "Raw GraphQL query",
"Create a new issue in Linear workspace": "Create a new issue in Linear workspace",
"Update a issue in Linear Workspace": "Update a issue in Linear Workspace",
"Create a new project in Linear workspace": "Create a new project in Linear workspace",
"Update a existing project in Linear workspace": "Update a existing project in Linear workspace",
"Create a new comment on an issue in Linear workspace": "Create a new comment on an issue in Linear workspace",
"Perform a raw GraphQL query": "Perform a raw GraphQL query",
"Team": "Team",
"Title": "Title",
"Description": "Description",
"Status": "Status",
"Labels": "Labels",
"Assignee": "Assignee",
"Priority": "Priority",
"Template": "Template",
"Issue": "Issue",
"Project Name": "Project Name",
"Icon": "Icon",
"Color": "Color",
"Start Date": "Start Date",
"Target Date": "Target Date",
"Project": "Project",
"Comment Body": "Comment Body",
"Query": "Query",
"Parameters": "Parameters",
"The team for which the issue, project or comment will be created": "The team for which the issue, project or comment will be created",
"Status of the Issue": "Status of the Issue",
"Labels for the Issue": "Labels for the Issue",
"Assignee of the Issue / Comment": "Assignee of the Issue / Comment",
"Priority of the Issue": "Priority of the Issue",
"ID of Template": "ID of Template",
"ID of Linear Issue": "ID of Linear Issue",
"ID of Linear Project": "ID of Linear Project",
"The content of the comment": "The content of the comment",
"New Issue": "New Issue",
"Updated Issue": "Updated Issue",
"Removed Issue": "Removed Issue",
"Triggers when Linear receives a new issue": "Triggers when Linear receives a new issue",
"Triggers when an existing Linear issue is updated": "Triggers when an existing Linear issue is updated",
"Triggers when an existing Linear issue is removed": "Triggers when an existing Linear issue is removed"
}

View File

@@ -0,0 +1,49 @@
{
"Issue tracking for modern software teams": "Issue tracking for modern software teams",
"\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.": "\nTo obtain your API key, follow these steps:\n\n1. Go to settings by clicking your profile-pic (top-left)\n2. Go to API section inside My Account.\n3. On Personal API keys, give label and press create key.",
"Create Issue": "Create Issue",
"Update Issue": "Update Issue",
"Create Project": "Create Project",
"Update Project": "Update Project",
"Create Comment": "Create Comment",
"Raw GraphQL query": "Raw GraphQL query",
"Create a new issue in Linear workspace": "Create a new issue in Linear workspace",
"Update a issue in Linear Workspace": "Update a issue in Linear Workspace",
"Create a new project in Linear workspace": "Create a new project in Linear workspace",
"Update a existing project in Linear workspace": "Update a existing project in Linear workspace",
"Create a new comment on an issue in Linear workspace": "Create a new comment on an issue in Linear workspace",
"Perform a raw GraphQL query": "Perform a raw GraphQL query",
"Team": "团队",
"Title": "标题",
"Description": "描述",
"Status": "状态",
"Labels": "Labels",
"Assignee": "Assignee",
"Priority": "Priority",
"Template": "模板",
"Issue": "Issue",
"Project Name": "项目名称",
"Icon": "Icon",
"Color": "Color",
"Start Date": "Start Date",
"Target Date": "Target Date",
"Project": "项目",
"Comment Body": "Comment Body",
"Query": "Query",
"Parameters": "Parameters",
"The team for which the issue, project or comment will be created": "The team for which the issue, project or comment will be created",
"Status of the Issue": "Status of the Issue",
"Labels for the Issue": "Labels for the Issue",
"Assignee of the Issue / Comment": "Assignee of the Issue / Comment",
"Priority of the Issue": "Priority of the Issue",
"ID of Template": "ID of Template",
"ID of Linear Issue": "ID of Linear Issue",
"ID of Linear Project": "ID of Linear Project",
"The content of the comment": "The content of the comment",
"New Issue": "New Issue",
"Updated Issue": "Updated Issue",
"Removed Issue": "Removed Issue",
"Triggers when Linear receives a new issue": "Triggers when Linear receives a new issue",
"Triggers when an existing Linear issue is updated": "Triggers when an existing Linear issue is updated",
"Triggers when an existing Linear issue is removed": "Triggers when an existing Linear issue is removed"
}

View File

@@ -0,0 +1,54 @@
import { createPiece, PieceAuth } from '@activepieces/pieces-framework';
import { PieceCategory } from '@activepieces/shared';
import { linearCreateComment } from './lib/actions/comments/create-comment';
import { linearCreateIssue } from './lib/actions/issues/create-issue';
import { linearUpdateIssue } from './lib/actions/issues/update-issue';
import { linearCreateProject } from './lib/actions/projects/create-project';
import { linearUpdateProject } from './lib/actions/projects/update-project';
import { linearRawGraphqlQuery } from './lib/actions/raw-graphql-query';
import { linearNewIssue } from './lib/triggers/new-issue';
import { linearUpdatedIssue } from './lib/triggers/updated-issue';
import { linearRemovedIssue } from './lib/triggers/removed-issue';
const markdown = `
To obtain your API key, follow these steps:
1. Go to settings by clicking your profile-pic (top-left)
2. Go to API section inside My Account.
3. On Personal API keys, give label and press create key.`;
export const linearAuth = PieceAuth.SecretText({
displayName: 'API Key',
required: true,
description: markdown,
validate: async ({ auth }) => {
if (auth.startsWith('lin_api_')) {
return {
valid: true,
};
}
return {
valid: false,
error: 'Invalid API Key',
};
},
});
export const linear = createPiece({
displayName: 'Linear',
description: 'Issue tracking for modern software teams',
auth: linearAuth,
minimumSupportedRelease: '0.30.0',
logoUrl: 'https://cdn.activepieces.com/pieces/linear.png',
authors: ['lldiegon', 'kishanprmr', 'abuaboud'],
categories: [PieceCategory.PRODUCTIVITY],
actions: [
linearCreateIssue,
linearUpdateIssue,
linearCreateProject,
linearUpdateProject,
linearCreateComment,
linearRawGraphqlQuery,
],
triggers: [linearNewIssue, linearUpdatedIssue, linearRemovedIssue],
});

View File

@@ -0,0 +1,41 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { linearAuth } from '../../..';
import { props } from '../../common/props';
import { makeClient } from '../../common/client';
import { LinearDocument } from '@linear/sdk';
export const linearCreateComment = createAction({
auth: linearAuth,
name: 'linear_create_comment',
displayName: 'Create Comment',
description: 'Create a new comment on an issue in Linear workspace',
props: {
team_id: props.team_id(),
user_id: props.assignee_id(),
issue_id: props.issue_id(),
body: Property.LongText({
displayName: 'Comment Body',
description: 'The content of the comment',
required: true,
}),
},
async run({ auth, propsValue }) {
const comment: LinearDocument.CommentCreateInput = {
issueId: propsValue.issue_id!,
body: propsValue.body,
};
const client = makeClient(auth);
const result = await client.createComment(comment);
if (result.success) {
const createdComment = await result.comment;
return {
success: result.success,
lastSyncId: result.lastSyncId,
comment: createdComment,
};
} else {
throw new Error(`Unexpected error: ${result}`)
}
},
});

View File

@@ -0,0 +1,52 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { linearAuth } from '../../..';
import { props } from '../../common/props';
import { makeClient } from '../../common/client';
import { LinearDocument } from '@linear/sdk';
export const linearCreateIssue = createAction({
auth: linearAuth,
name: 'linear_create_issue',
displayName: 'Create Issue',
description: 'Create a new issue in Linear workspace',
props: {
team_id: props.team_id(),
title: Property.ShortText({
displayName: 'Title',
required: true,
}),
description: Property.LongText({
displayName: 'Description',
required: false,
}),
state_id: props.status_id(),
labels: props.labels(),
assignee_id: props.assignee_id(),
priority_id: props.priority_id(),
template_id: props.template_id()
},
async run({ auth, propsValue }) {
const issue: LinearDocument.IssueCreateInput = {
teamId: propsValue.team_id!,
title: propsValue.title,
description: propsValue.description,
assigneeId: propsValue.assignee_id,
stateId: propsValue.state_id,
priority: propsValue.priority_id,
labelIds: propsValue.labels,
templateId: propsValue.template_id
};
const client = makeClient(auth);
const result = await client.createIssue(issue);
if (result.success) {
const createdIssue = await result.issue;
return {
success: result.success,
lastSyncId: result.lastSyncId,
issue: createdIssue,
};
} else {
throw new Error(`Unexpected error: ${result}`)
}
},
});

View File

@@ -0,0 +1,51 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { linearAuth } from '../../..';
import { props } from '../../common/props';
import { makeClient } from '../../common/client';
import { LinearDocument } from '@linear/sdk';
export const linearUpdateIssue = createAction({
auth: linearAuth,
name: 'linear_update_issue',
displayName: 'Update Issue',
description: 'Update a issue in Linear Workspace',
props: {
team_id: props.team_id(),
issue_id: props.issue_id(),
title: Property.ShortText({
displayName: 'Title',
required: false,
}),
description: Property.LongText({
displayName: 'Description',
required: false,
}),
state_id: props.status_id(),
labels: props.labels(),
assignee_id: props.assignee_id(),
priority_id: props.priority_id(),
},
async run({ auth, propsValue }) {
const issueId = propsValue.issue_id!;
const issue: LinearDocument.IssueUpdateInput = {
title: propsValue.title,
description: propsValue.description,
assigneeId: propsValue.assignee_id,
stateId: propsValue.state_id,
priority: propsValue.priority_id,
labelIds: propsValue.labels,
};
const client = makeClient(auth);
const result = await client.updateIssue(issueId, issue);
if (result.success) {
const updatedIssue = await result.issue;
return {
success: result.success,
lastSyncId: result.lastSyncId,
issue: updatedIssue,
};
} else {
throw new Error(`Unexpected error: ${result}`)
}
},
});

View File

@@ -0,0 +1,63 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { linearAuth } from '../../..';
import { props } from '../../common/props';
import { makeClient } from '../../common/client';
import { LinearDocument } from '@linear/sdk';
export const linearCreateProject = createAction({
auth: linearAuth,
name: 'linear_create_project',
displayName: 'Create Project',
description: 'Create a new project in Linear workspace',
props: {
team_id: props.team_id(),
name: Property.ShortText({
displayName: 'Project Name',
required: true,
}),
description: Property.LongText({
displayName: 'Description',
required: false,
}),
icon: Property.ShortText({
displayName: 'Icon',
required: false,
}),
color: Property.ShortText({
displayName: 'Color',
required: false,
}),
startDate: Property.DateTime({
displayName: 'Start Date',
required: false,
}),
targetDate: Property.DateTime({
displayName: 'Target Date',
required: false,
}),
},
async run({ auth, propsValue }) {
const project: LinearDocument.ProjectCreateInput = {
teamIds: [propsValue.team_id!],
name: propsValue.name,
description: propsValue.description,
icon: propsValue.icon,
color: propsValue.color,
startDate: propsValue.startDate,
targetDate: propsValue.targetDate,
};
const client = makeClient(auth);
const result = await client.createProject(project);
if (result.success) {
const createdProject = await result.project;
return {
success: result.success,
lastSyncId: result.lastSyncId,
project: createdProject,
};
} else {
throw new Error(`Unexpected error: ${result}`)
}
},
});

View File

@@ -0,0 +1,64 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { linearAuth } from '../../..';
import { props } from '../../common/props';
import { makeClient } from '../../common/client';
import { LinearDocument } from '@linear/sdk';
export const linearUpdateProject = createAction({
auth: linearAuth,
name: 'linear_update_project',
displayName: 'Update Project',
description: 'Update a existing project in Linear workspace',
props: {
team_id: props.team_id(),
project_id: props.project_id(),
name: Property.ShortText({
displayName: 'Project Name',
required: true,
}),
description: Property.LongText({
displayName: 'Description',
required: false,
}),
icon: Property.ShortText({
displayName: 'Icon',
required: false,
}),
color: Property.ShortText({
displayName: 'Color',
required: false,
}),
startDate: Property.DateTime({
displayName: 'Start Date',
required: false,
}),
targetDate: Property.DateTime({
displayName: 'Target Date',
required: false,
}),
},
async run({ auth, propsValue }) {
const project: LinearDocument.ProjectUpdateInput = {
teamIds: [propsValue.team_id!],
name: propsValue.name,
description: propsValue.description,
icon: propsValue.icon,
color: propsValue.color,
startDate: propsValue.startDate,
targetDate: propsValue.targetDate,
};
const client = makeClient(auth);
const result = await client.updateProject(propsValue.project_id!, project);
if (result.success) {
const updatedProject = await result.project;
return {
success: result.success,
lastSyncId: result.lastSyncId,
project: updatedProject,
};
} else {
throw new Error(`Unexpected error: ${result}`)
}
},
});

View File

@@ -0,0 +1,22 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { linearAuth } from '../..';
import { makeClient } from '../common/client';
export const linearRawGraphqlQuery = createAction({
name: 'rawGraphqlQuery',
displayName: 'Raw GraphQL query',
description: 'Perform a raw GraphQL query',
auth: linearAuth,
props: {
query: Property.LongText({ displayName: 'Query', required: true }),
variables: Property.Object({ displayName: 'Parameters', required: false }),
},
async run({ auth, propsValue }) {
const client = makeClient(auth);
const result = await client.rawRequest(
propsValue.query,
propsValue.variables
);
return result;
},
});

View File

@@ -0,0 +1,74 @@
import { AppConnectionValueForAuthProperty } from '@activepieces/pieces-framework';
import { LinearClient, LinearDocument } from '@linear/sdk';
import { linearAuth } from '../..';
export class LinearClientWrapper {
private client: LinearClient;
constructor(apiKey: string) {
this.client = new LinearClient({ apiKey: apiKey });
}
async createIssue(input: LinearDocument.IssueCreateInput) {
return this.client.createIssue(input);
}
async listIssueStates(
variables: LinearDocument.WorkflowStatesQueryVariables
) {
return this.client.workflowStates(variables);
}
async listIssuePriorities() {
return this.client.issuePriorityValues;
}
async listUsers(variables: LinearDocument.UsersQueryVariables) {
return this.client.users(variables);
}
async listIssueLabels(variables: LinearDocument.IssueLabelsQueryVariables) {
return this.client.issueLabels(variables);
}
async listTeams(variables: LinearDocument.TeamsQueryVariables = {}) {
return this.client.teams(variables);
}
async listIssues(variables: LinearDocument.IssuesQueryVariables = {}) {
return this.client.issues(variables);
}
async updateIssue(issueId: string, input: LinearDocument.IssueUpdateInput) {
return this.client.updateIssue(issueId, input);
}
async createProject(input: LinearDocument.ProjectCreateInput) {
return this.client.createProject(input);
}
async listProjects(variables: LinearDocument.ProjectsQueryVariables = {}) {
return this.client.projects(variables);
}
async updateProject(
projectId: string,
input: LinearDocument.ProjectUpdateInput
) {
return this.client.updateProject(projectId, input);
}
async createComment(input: LinearDocument.CommentCreateInput) {
return this.client.createComment(input);
}
async createWebhook(input: LinearDocument.WebhookCreateInput) {
return this.client.createWebhook(input);
}
async listWebhooks(variables: LinearDocument.WebhooksQueryVariables = {}) {
return this.client.webhooks(variables);
}
async deleteWebhook(webhookId: string) {
return this.client.deleteWebhook(webhookId);
}
async listTeamsTemplates(
teamId: string,
variables: Omit<LinearDocument.Team_TemplatesQueryVariables, 'id'>
) {
const team = await this.client.team(teamId);
return team.templates(variables);
}
async rawRequest(query: string, variables?: Record<string, unknown>) {
return this.client.client.rawRequest(query, variables);
}
}
export function makeClient(auth: AppConnectionValueForAuthProperty<typeof linearAuth>): LinearClientWrapper {
return new LinearClientWrapper(auth.secret_text);
}

View File

@@ -0,0 +1,394 @@
import { DropdownOption, Property } from '@activepieces/pieces-framework';
import { makeClient } from './client';
import { LinearDocument } from '@linear/sdk';
import { linearAuth } from '../..';
export const props = {
team_id: (required = true) =>
Property.Dropdown({
auth: linearAuth,
description:
'The team for which the issue, project or comment will be created',
displayName: 'Team',
required,
refreshers: ['auth'],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
placeholder: 'connect your account first',
options: [],
};
}
const client = makeClient(auth);
const options: DropdownOption<string>[] = [];
let hasNextPage = false;
let cursor;
do {
const teams = await client.listTeams({
orderBy: LinearDocument.PaginationOrderBy.UpdatedAt,
first: 100,
after: cursor,
});
for (const team of teams.nodes) {
options.push({ label: team.name, value: team.id });
}
hasNextPage = teams.pageInfo.hasNextPage;
cursor = teams.pageInfo.endCursor;
} while (hasNextPage);
return {
disabled: false,
options,
};
},
}),
status_id: (required = false) =>
Property.Dropdown({
auth: linearAuth,
description: 'Status of the Issue',
displayName: 'Status',
required,
refreshers: ['auth', 'team_id'],
options: async ({ auth, team_id }) => {
if (!auth || !team_id) {
return {
disabled: true,
placeholder: 'connect your account first and select team',
options: [],
};
}
const client = makeClient(auth);
const options: DropdownOption<string>[] = [];
let hasNextPage = false;
let cursor;
do {
const filter: LinearDocument.WorkflowStatesQueryVariables = {
filter: {
team: {
id: {
eq: team_id as string,
},
},
},
first: 100,
after: cursor,
};
const statusList = await client.listIssueStates(filter);
for (const status of statusList.nodes) {
options.push({ label: status.name, value: status.id });
}
hasNextPage = statusList.pageInfo.hasNextPage;
cursor = statusList.pageInfo.endCursor;
} while (hasNextPage);
return {
disabled: false,
options,
};
},
}),
labels: (required = false) =>
Property.MultiSelectDropdown({
auth: linearAuth,
description: 'Labels for the Issue',
displayName: 'Labels',
required,
refreshers: ['auth', 'team_id'],
options: async ({ auth, team_id }) => {
if (!auth) {
return {
disabled: true,
placeholder: 'connect your account first',
options: [],
};
}
if (!team_id) {
return {
disabled: true,
placeholder: 'select a team to load labels',
options: [],
};
}
const client = makeClient(auth);
const teamLabels: DropdownOption<string>[] = [];
const workspaceLabels: DropdownOption<string>[] = [];
// Fetch team specific labels
let hasNextPage = false;
let cursor;
do {
const labels = await client.listIssueLabels({
filter: {
team: {
id: {
eq: team_id as string,
},
},
},
orderBy: LinearDocument.PaginationOrderBy.UpdatedAt,
first: 100,
after: cursor,
});
for (const label of labels.nodes) {
teamLabels.push({ label: label.name, value: label.id });
}
hasNextPage = labels.pageInfo.hasNextPage;
cursor = labels.pageInfo.endCursor;
} while (hasNextPage);
// Fetch all workspace labels that are common to all teams
hasNextPage = false;
cursor = undefined;
do {
const labels = await client.listIssueLabels({
filter: {
team: {
null: true,
},
},
orderBy: LinearDocument.PaginationOrderBy.UpdatedAt,
first: 100,
after: cursor,
});
for (const label of labels.nodes) {
// Prefix workspace labels with [Workspace]
workspaceLabels.push({ label: `[Workspace] ${label.name}`, value: label.id });
}
hasNextPage = labels.pageInfo.hasNextPage;
cursor = labels.pageInfo.endCursor;
} while (hasNextPage);
// team labels are displayed first in alphabetical order
teamLabels.sort((a, b) => a.label.localeCompare(b.label));
// followed by workspace labels in alphabetical order
workspaceLabels.sort((a, b) => a.label.localeCompare(b.label));
const options = [...teamLabels, ...workspaceLabels];
return {
disabled: false,
options,
};
},
}),
assignee_id: (required = false) =>
Property.Dropdown({
auth: linearAuth,
description: 'Assignee of the Issue / Comment',
displayName: 'Assignee',
required,
refreshers: ['auth'],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
placeholder: 'connect your account first',
options: [],
};
}
const client = makeClient(auth);
const options: DropdownOption<string>[] = [];
let hasNextPage = false;
let cursor;
do {
const users = await client.listUsers({
orderBy: LinearDocument.PaginationOrderBy.UpdatedAt,
first: 100,
after: cursor,
});
for (const user of users.nodes) {
options.push({ label: user.name, value: user.id });
}
hasNextPage = users.pageInfo.hasNextPage;
cursor = users.pageInfo.endCursor;
} while (hasNextPage);
return {
disabled: false,
options,
};
},
}),
priority_id: (required = false) =>
Property.Dropdown({
auth: linearAuth,
description: 'Priority of the Issue',
displayName: 'Priority',
required,
refreshers: ['auth'],
options: async ({ auth }) => {
if (!auth) {
return {
disabled: true,
placeholder: 'connect your account first',
options: [],
};
}
const client = makeClient(auth);
const priorities = await client.listIssuePriorities();
return {
disabled: false,
options: priorities.map((priority: { label: any; priority: any }) => {
return {
label: priority.label,
value: priority.priority,
};
}),
};
},
}),
issue_id: (required = true) =>
Property.Dropdown({
auth: linearAuth,
displayName: 'Issue',
required,
description: 'ID of Linear Issue',
refreshers: ['team_id'],
options: async ({ auth, team_id }) => {
if (!auth || !team_id) {
return {
disabled: true,
placeholder: 'connect your account first and select team',
options: [],
};
}
const client = makeClient(auth);
const filter: LinearDocument.IssuesQueryVariables = {
first: 50,
filter: {
team: {
id: {
eq: team_id as string,
},
},
},
orderBy: LinearDocument.PaginationOrderBy.UpdatedAt,
};
const issues = await client.listIssues(filter);
return {
disabled: false,
options: issues.nodes.map((issue: { title: any; id: any }) => {
return {
label: issue.title,
value: issue.id,
};
}),
};
},
}),
project_id: (required = true) =>
Property.Dropdown({
auth: linearAuth,
displayName: 'Project',
required,
description: 'ID of Linear Project',
refreshers: ['team_id'],
options: async ({ auth, team_id }) => {
if (!auth || !team_id) {
return {
disabled: true,
placeholder: 'connect your account first and select team',
options: [],
};
}
const client = makeClient(auth);
const options: DropdownOption<string>[] = [];
let hasNextPage = false;
let cursor;
do {
const projects = await client.listProjects({
orderBy: LinearDocument.PaginationOrderBy.UpdatedAt,
first: 100,
after: cursor,
});
for (const project of projects.nodes) {
options.push({ label: project.name, value: project.id });
}
hasNextPage = projects.pageInfo.hasNextPage;
cursor = projects.pageInfo.endCursor;
} while (hasNextPage);
return {
disabled: false,
options,
};
},
}),
template_id: (required = false) =>
Property.Dropdown({
auth: linearAuth,
displayName: 'Template',
required,
description: 'ID of Template',
refreshers: ['auth', 'team_id'],
options: async ({ auth, team_id }) => {
if (!auth || !team_id) {
return {
disabled: true,
placeholder: 'connect your account first and select team',
options: [],
};
}
const client = makeClient(auth);
const options: DropdownOption<string>[] = [];
let hasNextPage = false;
let cursor;
do {
const filter: Omit<
LinearDocument.Team_TemplatesQueryVariables,
'id'
> = {
first: 100,
after: cursor,
orderBy: LinearDocument.PaginationOrderBy.UpdatedAt,
};
const templatesConnection = await client.listTeamsTemplates(
team_id as string,
filter
);
const templates = await templatesConnection.nodes;
for (const template of templates) {
options.push({ label: template.name, value: template.id });
}
hasNextPage = templatesConnection.pageInfo.hasNextPage;
cursor = templatesConnection.pageInfo.endCursor;
} while (hasNextPage);
return {
disabled: false,
options,
};
},
}),
};

View File

@@ -0,0 +1,101 @@
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
import { linearAuth } from '../..';
import { makeClient } from '../common/client';
import { props } from '../common/props';
export const linearNewIssue = createTrigger({
auth: linearAuth,
name: 'new_issue',
displayName: 'New Issue',
description: 'Triggers when Linear receives a new issue',
props: {
team_id: props.team_id(),
},
sampleData: {
// Sample data structure based on Linear's webhook payload for issues
action: 'create',
data: {
id: 'issue_1',
identifier: '1',
title: 'Test issue',
description: 'This is a test issue',
priority: 'priority_1',
priorityLabel: 'High',
state: 'state_1',
stateLabel: 'In Progress',
team: {
id: 'team_1',
name: 'Test team',
key: 'test-team',
description: 'This is a test team',
archived: false,
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-05T12:00:00.000Z',
},
creator: {
id: 'user_1',
name: 'Test user',
email: 'test@gmail.com',
avatarUrl: 'https://avatars.githubusercontent.com/u/1?v=4',
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-05T12:00:00.000Z',
},
assignee: {
id: 'user_1',
name: 'Test user',
email: 'test@gmail.com',
avatarUrl: 'https://avatars.githubusercontent.com/u/1?v=4',
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-05T12:00:00.000Z',
},
labels: [
{
id: 'label_1',
name: 'Test label',
color: '#000000',
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-05T12:00:00.000Z',
},
],
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-05T12:00:00.000Z',
},
},
type: TriggerStrategy.WEBHOOK,
async onEnable(context) {
const client = makeClient(context.auth);
const webhook = await client.createWebhook({
label: 'ActivePieces New Issue',
url: context.webhookUrl,
teamId: context.propsValue['team_id'],
resourceTypes: ['Issue'],
});
if (webhook.success && webhook.webhook) {
await context.store?.put<WebhookInformation>('_new_issue_trigger', {
webhookId: (await webhook.webhook).id,
});
} else {
console.error('Failed to create the webhook');
}
},
async onDisable(context) {
const client = makeClient(context.auth);
const response = await context.store?.get<WebhookInformation>(
'_new_issue_trigger'
);
if (response && response.webhookId) {
await client.deleteWebhook(response.webhookId);
}
},
async run(context) {
const body = context.payload.body as { action: string; data: unknown };
if (body.action === 'create') {
return [body.data];
}
return [];
},
});
interface WebhookInformation {
webhookId: string;
}

View File

@@ -0,0 +1,101 @@
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
import { linearAuth } from '../..';
import { makeClient } from '../common/client';
import { props } from '../common/props';
export const linearRemovedIssue = createTrigger({
auth: linearAuth,
name: 'removed_issue',
displayName: 'Removed Issue',
description: 'Triggers when an existing Linear issue is removed',
props: {
team_id: props.team_id()
},
sampleData: {
// Sample data structure based on Linear's webhook payload for issues
action: 'remove',
data: {
id: 'issue_1',
identifier: '1',
title: 'Test issue',
description: 'This is a test issue',
priority: 'priority_1',
priorityLabel: 'High',
state: 'state_1',
stateLabel: 'In Progress',
team: {
id: 'team_1',
name: 'Test team',
key: 'test-team',
description: 'This is a test team',
archived: false,
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-05T12:00:00.000Z',
},
creator: {
id: 'user_1',
name: 'Test user',
email: 'test@gmail.com',
avatarUrl: 'https://avatars.githubusercontent.com/u/1?v=4',
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-05T12:00:00.000Z',
},
assignee: {
id: 'user_1',
name: 'Test user',
email: 'test@gmail.com',
avatarUrl: 'https://avatars.githubusercontent.com/u/1?v=4',
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-05T12:00:00.000Z',
},
labels: [
{
id: 'label_1',
name: 'Test label',
color: '#000000',
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-05T12:00:00.000Z',
},
],
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-05T12:00:00.000Z',
},
},
type: TriggerStrategy.WEBHOOK,
async onEnable(context) {
const client = makeClient(context.auth);
const webhook = await client.createWebhook({
label: 'ActivePieces Updated Issue',
url: context.webhookUrl,
teamId: context.propsValue['team_id'],
resourceTypes: ['Issue']
});
if (webhook.success && webhook.webhook) {
await context.store?.put<WebhookInformation>('_removed_issue_trigger', {
webhookId: (await webhook.webhook).id
});
} else {
console.error('Failed to create the webhook');
}
},
async onDisable(context) {
const client = makeClient(context.auth);
const response = await context.store?.get<WebhookInformation>(
'_removed_issue_trigger'
);
if (response && response.webhookId) {
await client.deleteWebhook(response.webhookId);
}
},
async run(context) {
const body = context.payload.body as { action: string; data: unknown};
if (body.action === 'remove') {
return [body.data];
}
return [];
}
});
interface WebhookInformation {
webhookId: string;
}

View File

@@ -0,0 +1,124 @@
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
import { linearAuth } from '../..';
import { makeClient } from '../common/client';
import { props } from '../common/props';
export const linearUpdatedIssue = createTrigger({
auth: linearAuth,
name: 'updated_issue',
displayName: 'Updated Issue',
description: 'Triggers when an existing Linear issue is updated',
props: {
team_id: props.team_id(false)
},
sampleData: {
// Sample data structure based on Linear's webhook payload for issues
action: 'update',
data: {
id: 'issue_1',
identifier: '1',
title: 'Test issue updated',
description: 'This is a test issue (updated)',
priority: 'priority_1',
priorityLabel: 'High',
state: 'state_2',
stateLabel: 'In Review',
team: {
id: 'team_2',
name: 'Test team',
key: 'test-team',
description: 'This is another test team',
archived: false,
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-06T12:00:00.000Z'
},
creator: {
id: 'user_1',
name: 'Test user',
email: 'test@gmail.com',
avatarUrl: 'https://avatars.githubusercontent.com/u/1?v=4',
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-06T12:00:00.000Z'
},
assignee: {
id: 'user_1',
name: 'Test user',
email: 'test@gmail.com',
avatarUrl: 'https://avatars.githubusercontent.com/u/1?v=4',
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-05T12:00:00.000Z'
},
labels: [
{
id: 'label_1',
name: 'Test label',
color: '#000000',
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-05T12:00:00.000Z'
},
{
id: 'label_1',
name: 'Test label 2',
color: '#000000',
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-06T12:00:00.000Z'
}
],
createdAt: '2023-09-05T12:00:00.000Z',
updatedAt: '2023-09-06T12:00:00.000Z'
},
updatedFrom: {
'updatedAt': '2023-09-06T12:00:00.000Z',
'sortOrder': -14.61,
'startedAt': null,
'stateId': 'state_1'
}
},
type: TriggerStrategy.WEBHOOK,
async onEnable(context) {
const client = makeClient(context.auth);
// Create webhook configuration
const webhookConfig: any = {
label: 'ActivePieces Updated Issue',
url: context.webhookUrl,
allPublicTeams: true,
resourceTypes: ['Issue']
};
// Only add teamId if it's provided
if (context.propsValue['team_id']) {
webhookConfig.teamId = context.propsValue['team_id'];
}
const webhook = await client.createWebhook(webhookConfig);
if (webhook.success && webhook.webhook) {
await context.store?.put<WebhookInformation>('_updated_issue_trigger', {
webhookId: (await webhook.webhook).id
});
} else {
console.error('Failed to create the webhook');
}
},
async onDisable(context) {
const client = makeClient(context.auth);
const response = await context.store?.get<WebhookInformation>(
'_updated_issue_trigger'
);
if (response && response.webhookId) {
await client.deleteWebhook(response.webhookId);
}
},
async run(context) {
const body = context.payload.body as { action: string; data: unknown};
if (body.action === 'update') {
return [body.data];
}
return [];
}
});
interface WebhookInformation {
webhookId: string;
}