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,18 @@
{
"extends": ["../../../../.eslintrc.json"],
"ignorePatterns": ["!**/*", "package.json"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}

View File

@@ -0,0 +1,7 @@
# pieces-bettermode
This library was generated with [Nx](https://nx.dev).
## Building
Run `nx build pieces-bettermode` to build the library.

View File

@@ -0,0 +1,4 @@
{
"name": "@activepieces/piece-bettermode",
"version": "0.0.10"
}

View File

@@ -0,0 +1,57 @@
{
"name": "pieces-bettermode",
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/pieces/community/bettermode/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nx/js:tsc",
"outputs": [
"{options.outputPath}"
],
"options": {
"outputPath": "dist/packages/pieces/community/bettermode",
"tsConfig": "packages/pieces/community/bettermode/tsconfig.lib.json",
"packageJson": "packages/pieces/community/bettermode/package.json",
"main": "packages/pieces/community/bettermode/src/index.ts",
"assets": [
"packages/pieces/community/bettermode/*.md",
{
"input": "packages/pieces/community/bettermode/src/i18n",
"output": "./src/i18n",
"glob": "**/!(i18n.json)"
}
],
"buildableProjectDepsInPackageJsonType": "dependencies",
"updateBuildableProjectDepsInPackageJson": true
},
"dependsOn": [
"^build",
"prebuild"
]
},
"publish": {
"command": "node tools/scripts/publish.mjs pieces-bettermode {args.ver} {args.tag}",
"dependsOn": [
"build"
]
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": [
"{options.outputFile}"
]
},
"prebuild": {
"executor": "nx:run-commands",
"options": {
"cwd": "packages/pieces/community/bettermode",
"command": "bun install --no-save --silent"
},
"dependsOn": [
"^build"
]
}
},
"tags": []
}

View File

@@ -0,0 +1,59 @@
{
"Feature-rich engagement platform. Browse beautifully designed templates, each flexible for precise customization to your needs.": "Feature-reiche Verlobungs-Plattform. Durchsuchen Sie wunderschön gestaltete Vorlagen, jede flexibel für präzise Anpassung an Ihre Bedürfnisse.",
"Region": "Region",
"BetterMode Domain": "Bettermode-Domain",
"Email": "E-Mail",
"Password": "Kennwort",
"The region of your Bettermode account": "Die Region Ihres Bettermode-Kontos",
"The domain of your Bettermode account": "Die Domäne Ihres Bettermode-Kontos",
"Email address for your Bettermode account": "E-Mail-Adresse für Ihr Bettermode-Konto",
"Password for your Bettermode account": "Passwort für Ihr Bettermode-Konto",
"US Region": "US-Region",
"EU Region": "EU Region",
"Your domain should be the base URL of your Bettermode community. Example: community.example.com": "Deine Domain sollte die Basis-URL deiner Bettermode-Community sein. Beispiel: community.example.com",
"Create Discussion Post": "Diskussionsbeitrag erstellen",
"Create Question Post": "Fragenbeitrag erstellen",
"Assign Badge to Member": "Abzeichen dem Mitglied zuweisen",
"Revoke Badge from Member": "Abzeichen vom Mitglied widerrufen",
"Custom API Call": "Eigener API-Aufruf",
"Create a new discussion post in a space": "Neuen Diskussionsbeitrag in einem Raum erstellen",
"Create a new question post in a space": "Neuen Fragenbeitrag in einer Gruppe erstellen",
"Assign an existing badge to a member by email": "Ein bestehendes Abzeichen einem Mitglied per E-Mail zuweisen",
"Revoke a badge from a member by email": "Ein Abzeichen von einem Mitglied per E-Mail widerrufen",
"Make a custom API call to a specific endpoint": "Einen benutzerdefinierten API-Aufruf an einen bestimmten Endpunkt machen",
"Space": "Raum",
"Title": "Titel",
"Content": "Inhalt",
"Tags": "Tags",
"Locked": "Gesperrt",
"Badge": "Abzeichen",
"Method": "Methode",
"Headers": "Kopfzeilen",
"Query Parameters": "Abfrageparameter",
"Body": "Körper",
"Response is Binary ?": "Antwort ist binär?",
"No Error on Failure": "Kein Fehler bei Fehler",
"Timeout (in seconds)": "Timeout (in Sekunden)",
"The space to create the discussion in": "Der Raum um die Diskussion zu erstellen in",
"The title of the discussion": "Der Titel der Diskussion",
"The content of the discussion": "Der Inhalt der Diskussion",
"The tags to add to the discussion": "Die Tags die zur Diskussion hinzugefügt werden sollen",
"If the discussion should be locked": "Wenn die Diskussion gesperrt werden soll",
"The space to create the question in": "Der Raum um die Frage zu erstellen in",
"The title of the question": "Der Titel der Frage",
"The content of the question": "Der Inhalt der Frage",
"The tags to add to the question": "Die Tags zur Frage hinzufügen",
"If the question should be locked": "Wenn die Frage gesperrt werden soll",
"The badge to assign": "Das Abzeichen zum Zuweisen",
"The email of the member to assign the badge to": "Die E-Mail des Mitglieds, dem das Abzeichen zugewiesen wird",
"The badge to revoke": "Das Abzeichen zum Widerrufen",
"The email of the member to revoke the badge from": "Die E-Mail des Mitglieds, das das Abzeichen widerrufen soll von",
"Authorization headers are injected automatically from your connection.": "Autorisierungs-Header werden automatisch von Ihrer Verbindung injiziert.",
"Enable for files like PDFs, images, etc..": "Aktivieren für Dateien wie PDFs, Bilder, etc..",
"GET": "ERHALTEN",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "LÖSCHEN",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,59 @@
{
"Feature-rich engagement platform. Browse beautifully designed templates, each flexible for precise customization to your needs.": "Plataforma de compromiso enriquecida con Feature. Navegue por plantillas de diseño hermoso, cada una flexible para una personalización precisa a sus necesidades.",
"Region": "Región",
"BetterMode Domain": "Dominio de Mejor Modo",
"Email": "E-mail",
"Password": "Contraseña",
"The region of your Bettermode account": "La región de tu cuenta de Bettermode",
"The domain of your Bettermode account": "El dominio de su cuenta Bettermode",
"Email address for your Bettermode account": "Dirección de correo electrónico para su cuenta de Bettermode",
"Password for your Bettermode account": "Contraseña para su cuenta de Bettermode",
"US Region": "Región de EEUU",
"EU Region": "EU Region",
"Your domain should be the base URL of your Bettermode community. Example: community.example.com": "Su dominio debe ser la URL base de su comunidad Bettermood. Ejemplo: community.example.com",
"Create Discussion Post": "Crear mensaje de discusión",
"Create Question Post": "Crear mensaje de pregunta",
"Assign Badge to Member": "Asignar Insignia a Miembro",
"Revoke Badge from Member": "Revocar Insignia de Miembro",
"Custom API Call": "Llamada API personalizada",
"Create a new discussion post in a space": "Crear una nueva discusión en un espacio",
"Create a new question post in a space": "Crear un nuevo post de pregunta en un espacio",
"Assign an existing badge to a member by email": "Asignar una insignia existente a un miembro por correo electrónico",
"Revoke a badge from a member by email": "Revocar una insignia de un miembro por correo electrónico",
"Make a custom API call to a specific endpoint": "Hacer una llamada API personalizada a un extremo específico",
"Space": "Espacio",
"Title": "Título",
"Content": "Contenido",
"Tags": "Etiquetas",
"Locked": "Bloqueado",
"Badge": "Insignia",
"Method": "Método",
"Headers": "Encabezados",
"Query Parameters": "Parámetros de consulta",
"Body": "Cuerpo",
"Response is Binary ?": "¿Respuesta es binaria?",
"No Error on Failure": "No hay ningún error en fallo",
"Timeout (in seconds)": "Tiempo de espera (en segundos)",
"The space to create the discussion in": "El espacio en el que crear la discusión",
"The title of the discussion": "El título de la discusión",
"The content of the discussion": "El contenido de la discusión",
"The tags to add to the discussion": "Las etiquetas a añadir a la discusión",
"If the discussion should be locked": "Si la discusión debe estar bloqueada",
"The space to create the question in": "El espacio en el que crear la pregunta",
"The title of the question": "El título de la pregunta",
"The content of the question": "El contenido de la pregunta",
"The tags to add to the question": "Las etiquetas a añadir a la pregunta",
"If the question should be locked": "Si la pregunta debe estar bloqueada",
"The badge to assign": "La insignia a asignar",
"The email of the member to assign the badge to": "El correo electrónico del miembro al que asignar la insignia",
"The badge to revoke": "La insignia a revocar",
"The email of the member to revoke the badge from": "El correo electrónico del miembro para revocar la insignia de",
"Authorization headers are injected automatically from your connection.": "Las cabeceras de autorización se inyectan automáticamente desde tu conexión.",
"Enable for files like PDFs, images, etc..": "Activar para archivos como PDFs, imágenes, etc.",
"GET": "RECOGER",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "BORRAR",
"HEAD": "LIMPIO"
}

View File

@@ -0,0 +1,59 @@
{
"Feature-rich engagement platform. Browse beautifully designed templates, each flexible for precise customization to your needs.": "Plateforme d'engagement riche en fonctionnalités. Parcourez les modèles superbement conçus, chacun flexible pour une personnalisation précise de vos besoins.",
"Region": "Région",
"BetterMode Domain": "Domaine du meilleur Mode",
"Email": "Courriel",
"Password": "Password",
"The region of your Bettermode account": "La région de votre compte Bettermode",
"The domain of your Bettermode account": "Le domaine de votre compte Bettermode",
"Email address for your Bettermode account": "Adresse e-mail de votre compte Bettermode",
"Password for your Bettermode account": "Mot de passe pour votre compte Bettermode",
"US Region": "Région des États-Unis",
"EU Region": "EU Region",
"Your domain should be the base URL of your Bettermode community. Example: community.example.com": "Votre domaine devrait être l'URL de base de votre communauté Bettermode. Exemple: community.example.com",
"Create Discussion Post": "Créer un message de discussion",
"Create Question Post": "Créer un message de question",
"Assign Badge to Member": "Assigner un badge à un membre",
"Revoke Badge from Member": "Révoquer le badge du membre",
"Custom API Call": "Appel API personnalisé",
"Create a new discussion post in a space": "Créer une nouvelle discussion dans un espace",
"Create a new question post in a space": "Créer une nouvelle question dans un espace",
"Assign an existing badge to a member by email": "Assigner un badge existant à un membre par e-mail",
"Revoke a badge from a member by email": "Révoquer un badge d'un membre par e-mail",
"Make a custom API call to a specific endpoint": "Passez un appel API personnalisé à un point de terminaison spécifique",
"Space": "Espace libre",
"Title": "Titre de la page",
"Content": "Contenus",
"Tags": "Tags",
"Locked": "Verrouillé",
"Badge": "Insigne",
"Method": "Méthode",
"Headers": "En-têtes",
"Query Parameters": "Paramètres de requête",
"Body": "Corps",
"Response is Binary ?": "La réponse est Binaire ?",
"No Error on Failure": "Aucune erreur en cas d'échec",
"Timeout (in seconds)": "Délai d'attente (en secondes)",
"The space to create the discussion in": "L'espace dans lequel créer la discussion",
"The title of the discussion": "Le titre de la discussion",
"The content of the discussion": "Le contenu de la discussion",
"The tags to add to the discussion": "Les tags à ajouter à la discussion",
"If the discussion should be locked": "Si la discussion doit être verrouillée",
"The space to create the question in": "L'espace dans lequel créer la question",
"The title of the question": "Le titre de la question",
"The content of the question": "Le contenu de la question",
"The tags to add to the question": "Les tags à ajouter à la question",
"If the question should be locked": "Si la question doit être verrouillée",
"The badge to assign": "Le badge à assigner",
"The email of the member to assign the badge to": "L'e-mail du membre à assigner au badge",
"The badge to revoke": "Le badge à révoquer",
"The email of the member to revoke the badge from": "L'e-mail du membre pour révoquer le badge de",
"Authorization headers are injected automatically from your connection.": "Les en-têtes d'autorisation sont injectés automatiquement à partir de votre connexion.",
"Enable for files like PDFs, images, etc..": "Activer pour les fichiers comme les PDFs, les images, etc.",
"GET": "OBTENIR",
"POST": "POSTER",
"PATCH": "PATCH",
"PUT": "EFFACER",
"DELETE": "SUPPRIMER",
"HEAD": "TÊTE"
}

View File

@@ -0,0 +1,59 @@
{
"Feature-rich engagement platform. Browse beautifully designed templates, each flexible for precise customization to your needs.": "機能豊富なエンゲージメントプラットフォーム。美しくデザインされたテンプレートを閲覧し、それぞれの柔軟性でニーズに合わせて正確にカスタマイズできます。",
"Region": "地域",
"BetterMode Domain": "BetterModeドメイン",
"Email": "Eメールアドレス",
"Password": "パスワード",
"The region of your Bettermode account": "Bettermodeアカウントの地域",
"The domain of your Bettermode account": "Bettermodeアカウントのドメイン",
"Email address for your Bettermode account": "Bettermodeアカウントのメールアドレス",
"Password for your Bettermode account": "Bettermodeアカウントのパスワード",
"US Region": "米国地域",
"EU Region": "EU Region",
"Your domain should be the base URL of your Bettermode community. Example: community.example.com": "ドメインは、Bettermode コミュニティのベース URL である必要があります。例: community.example.com",
"Create Discussion Post": "ディスカッション投稿を作成",
"Create Question Post": "問題の投稿を作成",
"Assign Badge to Member": "バッジをメンバーに割り当てる",
"Revoke Badge from Member": "メンバーからバッジを取り消す",
"Custom API Call": "カスタムAPI通話",
"Create a new discussion post in a space": "スペースに新しいディスカッション投稿を作成する",
"Create a new question post in a space": "スペースに新しい質問投稿を作成",
"Assign an existing badge to a member by email": "メールでメンバーに既存のバッジを割り当てる",
"Revoke a badge from a member by email": "メンバーからメールでバッジを取り消します",
"Make a custom API call to a specific endpoint": "特定のエンドポイントへのカスタム API コールを実行します。",
"Space": "スペース",
"Title": "タイトル",
"Content": "コンテンツ",
"Tags": "タグ",
"Locked": "ロック中",
"Badge": "バッジ",
"Method": "方法",
"Headers": "ヘッダー",
"Query Parameters": "クエリパラメータ",
"Body": "本文",
"Response is Binary ?": "応答はバイナリですか?",
"No Error on Failure": "失敗時にエラーはありません",
"Timeout (in seconds)": "タイムアウト(秒)",
"The space to create the discussion in": "ディスカッションを作成するスペース",
"The title of the discussion": "ディスカッションのタイトル",
"The content of the discussion": "ディスカッションの内容",
"The tags to add to the discussion": "ディスカッションに追加するタグ",
"If the discussion should be locked": "ディスカッションをロックする必要がある場合",
"The space to create the question in": "質問を作成するスペース",
"The title of the question": "質問のタイトル",
"The content of the question": "質問の内容",
"The tags to add to the question": "質問に追加するタグ",
"If the question should be locked": "質問をロックする必要がある場合",
"The badge to assign": "アサインするバッジ",
"The email of the member to assign the badge to": "バッジを割り当てるメンバーのメールアドレス",
"The badge to revoke": "取り消すバッジ",
"The email of the member to revoke the badge from": "バッジを取り消すメンバーのメールアドレス",
"Authorization headers are injected automatically from your connection.": "認証ヘッダは接続から自動的に注入されます。",
"Enable for files like PDFs, images, etc..": "PDF、画像などのファイルを有効にします。",
"GET": "取得",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "削除",
"HEAD": "頭"
}

View File

@@ -0,0 +1,59 @@
{
"Feature-rich engagement platform. Browse beautifully designed templates, each flexible for precise customization to your needs.": "Met een veelzijdig engagement-platform. Blader door prachtig ontworpen sjablonen, elk flexibel voor nauwkeurige aanpassingen aan uw behoeften.",
"Region": "Regio",
"BetterMode Domain": "BetterMode Domein",
"Email": "E-mail",
"Password": "Wachtwoord",
"The region of your Bettermode account": "De regio van je Bettermode account",
"The domain of your Bettermode account": "Het domein van uw Bettermode account",
"Email address for your Bettermode account": "E-mailadres voor uw Bettermode account",
"Password for your Bettermode account": "Wachtwoord voor je Bettermode account",
"US Region": "US Regio",
"EU Region": "EU Region",
"Your domain should be the base URL of your Bettermode community. Example: community.example.com": "Uw domein moet de basis-URL van uw Bettermode community zijn. Voorbeeld: community.example.com",
"Create Discussion Post": "Discussiebericht maken",
"Create Question Post": "Maak een vraagbericht",
"Assign Badge to Member": "Badge toewijzen aan Lid",
"Revoke Badge from Member": "Intrekken Badge van Lid",
"Custom API Call": "Custom API Call",
"Create a new discussion post in a space": "Maak een nieuwe discussie post in een ruimte",
"Create a new question post in a space": "Maak een nieuw vraagbericht in een ruimte",
"Assign an existing badge to a member by email": "Wijs een bestaande badge toe aan een lid via e-mail",
"Revoke a badge from a member by email": "Een badge van een lid intrekken via e-mail",
"Make a custom API call to a specific endpoint": "Maak een aangepaste API call naar een specifiek eindpunt",
"Space": "Spatiebalk",
"Title": "Aanspreektitel",
"Content": "Inhoud",
"Tags": "Labels",
"Locked": "Vergrendeld",
"Badge": "Badge",
"Method": "Methode",
"Headers": "Kopteksten",
"Query Parameters": "Query parameters",
"Body": "Lichaam",
"Response is Binary ?": "Antwoord is binair?",
"No Error on Failure": "Geen fout bij fout",
"Timeout (in seconds)": "Time-out (in seconden)",
"The space to create the discussion in": "De ruimte om de discussie te maken in",
"The title of the discussion": "De titel van de discussie",
"The content of the discussion": "De inhoud van de discussie",
"The tags to add to the discussion": "De tags om toe te voegen aan de discussie",
"If the discussion should be locked": "Als de discussie moet worden afgesloten",
"The space to create the question in": "De ruimte om de vraag te maken in",
"The title of the question": "De titel van de vraag",
"The content of the question": "De inhoud van de vraag",
"The tags to add to the question": "De tags om toe te voegen aan de vraag",
"If the question should be locked": "Als de vraag moet worden gesloten",
"The badge to assign": "De badge om toe te wijzen",
"The email of the member to assign the badge to": "De e-mail van het lid aan wie de badge toe te wijzen",
"The badge to revoke": "De badge om in te trekken",
"The email of the member to revoke the badge from": "De e-mail van het lid om de badge van te trekken",
"Authorization headers are injected automatically from your connection.": "Autorisatie headers worden automatisch geïnjecteerd vanuit uw verbinding.",
"Enable for files like PDFs, images, etc..": "Inschakelen voor bestanden zoals PDF's, afbeeldingen etc..",
"GET": "KRIJG",
"POST": "POSTE",
"PATCH": "BEKIJK",
"PUT": "PUT",
"DELETE": "VERWIJDEREN",
"HEAD": "HOOFD"
}

View File

@@ -0,0 +1,59 @@
{
"Feature-rich engagement platform. Browse beautifully designed templates, each flexible for precise customization to your needs.": "Plataforma de engajamento rica em recursos. Procure modelos maravilhosamente projetados, cada um flexível para personalização precisa às suas necessidades.",
"Region": "Região",
"BetterMode Domain": "Domínio Melhorado",
"Email": "e-mail",
"Password": "Senha",
"The region of your Bettermode account": "Região da sua conta Bettermode",
"The domain of your Bettermode account": "O domínio da sua conta Bettermode",
"Email address for your Bettermode account": "Endereço de e-mail para sua conta de modo melhor",
"Password for your Bettermode account": "Senha para sua conta do Bettermode",
"US Region": "Região dos EUA",
"EU Region": "EU Region",
"Your domain should be the base URL of your Bettermode community. Example: community.example.com": "Seu domínio deve ser a URL base da sua comunidade Bettermod. Exemplo: community.example.com",
"Create Discussion Post": "Criar Post de Discussão",
"Create Question Post": "Criar mensagem de perguntas",
"Assign Badge to Member": "Atribuir Emblema para Membro",
"Revoke Badge from Member": "Revogar emblema do membro",
"Custom API Call": "Chamada de API personalizada",
"Create a new discussion post in a space": "Criar uma nova publicação de discussão em um espaço",
"Create a new question post in a space": "Criar uma nova mensagem de pergunta em um espaço",
"Assign an existing badge to a member by email": "Atribuir uma medalha existente para um membro por e-mail",
"Revoke a badge from a member by email": "Revogar uma medalha de um membro por e-mail",
"Make a custom API call to a specific endpoint": "Faça uma chamada de API personalizada para um ponto de extremidade específico",
"Space": "Sala",
"Title": "Título",
"Content": "Conteúdo",
"Tags": "Etiquetas",
"Locked": "Trancado",
"Badge": "Distintivo",
"Method": "Método",
"Headers": "Cabeçalhos",
"Query Parameters": "Parâmetros da consulta",
"Body": "Conteúdo",
"Response is Binary ?": "A resposta é binária ?",
"No Error on Failure": "Nenhum erro no Failure",
"Timeout (in seconds)": "Tempo limite (em segundos)",
"The space to create the discussion in": "O espaço para criar a discussão em",
"The title of the discussion": "O título da discussão",
"The content of the discussion": "O conteúdo da discussão",
"The tags to add to the discussion": "As tags a serem adicionadas à discussão",
"If the discussion should be locked": "Se a discussão deve ser travada",
"The space to create the question in": "O espaço para criar a pergunta em",
"The title of the question": "O título da pergunta",
"The content of the question": "O conteúdo da pergunta",
"The tags to add to the question": "As etiquetas a serem adicionadas à pergunta",
"If the question should be locked": "Se a pergunta deve ser bloqueada",
"The badge to assign": "O distintivo para atribuir",
"The email of the member to assign the badge to": "O email do membro para atribuir o selo a",
"The badge to revoke": "O distintivo para revogar",
"The email of the member to revoke the badge from": "O e-mail do membro para revogar o emblema de",
"Authorization headers are injected automatically from your connection.": "Os cabeçalhos de autorização são inseridos automaticamente a partir da sua conexão.",
"Enable for files like PDFs, images, etc..": "Habilitar para arquivos como PDFs, imagens, etc..",
"GET": "OBTER",
"POST": "POSTAR",
"PATCH": "COMPRAR",
"PUT": "COLOCAR",
"DELETE": "EXCLUIR",
"HEAD": "CABEÇA"
}

View File

@@ -0,0 +1,58 @@
{
"Bettermode": "Лучший режим",
"Feature-rich engagement platform. Browse beautifully designed templates, each flexible for precise customization to your needs.": "Просматривайте красивые шаблоны, гибкие и точные шаблоны для ваших нужд.",
"Region": "Регион",
"BetterMode Domain": "Домен BetterMode",
"Email": "Почта",
"Password": "Пароль",
"The region of your Bettermode account": "Регион вашего аккаунта Bettermode",
"The domain of your Bettermode account": "Область вашего аккаунта Bettermode",
"Email address for your Bettermode account": "Адрес электронной почты для вашей учетной записи Bettermode",
"Password for your Bettermode account": "Пароль для вашей учетной записи Bettermode",
"US Region": "Регион США",
"EU Region": "EU Region",
"Your domain should be the base URL of your Bettermode community. Example: community.example.com": "Ваш домен должен быть базовым URL вашего сообщества Bettermode. Пример: community.example.com",
"Create Discussion Post": "Создать сообщение для обсуждения",
"Create Question Post": "Создать сообщение вопроса",
"Assign Badge to Member": "Назначить Знак Участнику",
"Revoke Badge from Member": "Отозвать Значок от Пользователя",
"Custom API Call": "Пользовательский вызов API",
"Create a new discussion post in a space": "Создать новое сообщение в сообществе",
"Create a new question post in a space": "Создать новую запись вопроса в сообществе",
"Assign an existing badge to a member by email": "Назначить существующий значок члену по электронной почте",
"Revoke a badge from a member by email": "Отозвать значок участника по электронной почте",
"Make a custom API call to a specific endpoint": "Сделать пользовательский API вызов к определенной конечной точке",
"Space": "Пространство",
"Title": "Заголовок",
"Content": "Содержание",
"Tags": "Теги",
"Locked": "Заблокировано",
"Badge": "Значок",
"Method": "Метод",
"Headers": "Заголовки",
"Query Parameters": "Параметры запроса",
"Body": "Тело",
"No Error on Failure": "Нет ошибок при ошибке",
"Timeout (in seconds)": "Таймаут (в секундах)",
"The space to create the discussion in": "Пространство для создания обсуждения",
"The title of the discussion": "Название обсуждения",
"The content of the discussion": "Содержание обсуждения",
"The tags to add to the discussion": "Теги для добавления в обсуждение",
"If the discussion should be locked": "Если обсуждение должно быть заблокировано",
"The space to create the question in": "Пространство для создания вопроса",
"The title of the question": "Название вопроса",
"The content of the question": "Содержание вопроса",
"The tags to add to the question": "Теги для добавления к вопросу",
"If the question should be locked": "Если вопрос должен быть заблокирован",
"The badge to assign": "Знак для назначения",
"The email of the member to assign the badge to": "Письмо члена для назначения значка",
"The badge to revoke": "Знак для отзыва",
"The email of the member to revoke the badge from": "Письмо члена клуба, чтобы отозвать значок от",
"Authorization headers are injected automatically from your connection.": "Заголовки авторизации включаются автоматически из вашего соединения.",
"GET": "ПОЛУЧИТЬ",
"POST": "ПОСТ",
"PATCH": "ПАТЧ",
"PUT": "ПОКУПИТЬ",
"DELETE": "УДАЛИТЬ",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,59 @@
{
"Feature-rich engagement platform. Browse beautifully designed templates, each flexible for precise customization to your needs.": "Feature-rich engagement platform. Browse beautifully designed templates, each flexible for precise customization to your needs.",
"Region": "Region",
"BetterMode Domain": "BetterMode Domain",
"Email": "Email",
"Password": "Password",
"The region of your Bettermode account": "The region of your Bettermode account",
"The domain of your Bettermode account": "The domain of your Bettermode account",
"Email address for your Bettermode account": "Email address for your Bettermode account",
"Password for your Bettermode account": "Password for your Bettermode account",
"US Region": "US Region",
"EU Region": "EU Region",
"Your domain should be the base URL of your Bettermode community. Example: community.example.com": "Your domain should be the base URL of your Bettermode community. Example: community.example.com",
"Create Discussion Post": "Create Discussion Post",
"Create Question Post": "Create Question Post",
"Assign Badge to Member": "Assign Badge to Member",
"Revoke Badge from Member": "Revoke Badge from Member",
"Custom API Call": "Custom API Call",
"Create a new discussion post in a space": "Create a new discussion post in a space",
"Create a new question post in a space": "Create a new question post in a space",
"Assign an existing badge to a member by email": "Assign an existing badge to a member by email",
"Revoke a badge from a member by email": "Revoke a badge from a member by email",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Space": "Space",
"Title": "Title",
"Content": "Content",
"Tags": "Tags",
"Locked": "Locked",
"Badge": "Badge",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"Response is Binary ?": "Response is Binary ?",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"The space to create the discussion in": "The space to create the discussion in",
"The title of the discussion": "The title of the discussion",
"The content of the discussion": "The content of the discussion",
"The tags to add to the discussion": "The tags to add to the discussion",
"If the discussion should be locked": "If the discussion should be locked",
"The space to create the question in": "The space to create the question in",
"The title of the question": "The title of the question",
"The content of the question": "The content of the question",
"The tags to add to the question": "The tags to add to the question",
"If the question should be locked": "If the question should be locked",
"The badge to assign": "The badge to assign",
"The email of the member to assign the badge to": "The email of the member to assign the badge to",
"The badge to revoke": "The badge to revoke",
"The email of the member to revoke the badge from": "The email of the member to revoke the badge from",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,58 @@
{
"Bettermode": "Bettermode",
"Feature-rich engagement platform. Browse beautifully designed templates, each flexible for precise customization to your needs.": "Feature-rich engagement platform. Browse beautifully designed templates, each flexible for precise customization to your needs.",
"Region": "Region",
"BetterMode Domain": "BetterMode Domain",
"Email": "Email",
"Password": "Password",
"The region of your Bettermode account": "The region of your Bettermode account",
"The domain of your Bettermode account": "The domain of your Bettermode account",
"Email address for your Bettermode account": "Email address for your Bettermode account",
"Password for your Bettermode account": "Password for your Bettermode account",
"US Region": "US Region",
"EU Region": "EU Region",
"Your domain should be the base URL of your Bettermode community. Example: community.example.com": "Your domain should be the base URL of your Bettermode community. Example: community.example.com",
"Create Discussion Post": "Create Discussion Post",
"Create Question Post": "Create Question Post",
"Assign Badge to Member": "Assign Badge to Member",
"Revoke Badge from Member": "Revoke Badge from Member",
"Custom API Call": "Custom API Call",
"Create a new discussion post in a space": "Create a new discussion post in a space",
"Create a new question post in a space": "Create a new question post in a space",
"Assign an existing badge to a member by email": "Assign an existing badge to a member by email",
"Revoke a badge from a member by email": "Revoke a badge from a member by email",
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
"Space": "Space",
"Title": "Title",
"Content": "Content",
"Tags": "Tags",
"Locked": "Locked",
"Badge": "Badge",
"Method": "Method",
"Headers": "Headers",
"Query Parameters": "Query Parameters",
"Body": "Body",
"No Error on Failure": "No Error on Failure",
"Timeout (in seconds)": "Timeout (in seconds)",
"The space to create the discussion in": "The space to create the discussion in",
"The title of the discussion": "The title of the discussion",
"The content of the discussion": "The content of the discussion",
"The tags to add to the discussion": "The tags to add to the discussion",
"If the discussion should be locked": "If the discussion should be locked",
"The space to create the question in": "The space to create the question in",
"The title of the question": "The title of the question",
"The content of the question": "The content of the question",
"The tags to add to the question": "The tags to add to the question",
"If the question should be locked": "If the question should be locked",
"The badge to assign": "The badge to assign",
"The email of the member to assign the badge to": "The email of the member to assign the badge to",
"The badge to revoke": "The badge to revoke",
"The email of the member to revoke the badge from": "The email of the member to revoke the badge from",
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
"GET": "GET",
"POST": "POST",
"PATCH": "PATCH",
"PUT": "PUT",
"DELETE": "DELETE",
"HEAD": "HEAD"
}

View File

@@ -0,0 +1,59 @@
{
"Feature-rich engagement platform. Browse beautifully designed templates, each flexible for precise customization to your needs.": "Feature-rich engagement platform. Browse beautifully designed templates, each flexible for precise customization to your needs.",
"Region": "Region",
"BetterMode Domain": "BetterMode Domain",
"Email": "电子邮件地址",
"Password": "密码",
"The region of your Bettermode account": "The region of your Bettermode account",
"The domain of your Bettermode account": "The domain of your Bettermode account",
"Email address for your Bettermode account": "Email address for your Bettermode account",
"Password for your Bettermode account": "Password for your Bettermode account",
"US Region": "US Region",
"EU Region": "EU Region",
"Your domain should be the base URL of your Bettermode community. Example: community.example.com": "Your domain should be the base URL of your Bettermode community. Example: community.example.com",
"Create Discussion Post": "Create Discussion Post",
"Create Question Post": "Create Question Post",
"Assign Badge to Member": "Assign Badge to Member",
"Revoke Badge from Member": "Revoke Badge from Member",
"Custom API Call": "自定义 API 呼叫",
"Create a new discussion post in a space": "Create a new discussion post in a space",
"Create a new question post in a space": "Create a new question post in a space",
"Assign an existing badge to a member by email": "Assign an existing badge to a member by email",
"Revoke a badge from a member by email": "Revoke a badge from a member by email",
"Make a custom API call to a specific endpoint": "将一个自定义 API 调用到一个特定的终点",
"Space": "Space",
"Title": "标题",
"Content": "Content",
"Tags": "标签",
"Locked": "Locked",
"Badge": "Badge",
"Method": "方法",
"Headers": "信头",
"Query Parameters": "查询参数",
"Body": "正文内容",
"Response is Binary ?": "Response is Binary ?",
"No Error on Failure": "失败时没有错误",
"Timeout (in seconds)": "超时(秒)",
"The space to create the discussion in": "The space to create the discussion in",
"The title of the discussion": "The title of the discussion",
"The content of the discussion": "The content of the discussion",
"The tags to add to the discussion": "The tags to add to the discussion",
"If the discussion should be locked": "If the discussion should be locked",
"The space to create the question in": "The space to create the question in",
"The title of the question": "The title of the question",
"The content of the question": "The content of the question",
"The tags to add to the question": "The tags to add to the question",
"If the question should be locked": "If the question should be locked",
"The badge to assign": "The badge to assign",
"The email of the member to assign the badge to": "The email of the member to assign the badge to",
"The badge to revoke": "The badge to revoke",
"The email of the member to revoke the badge from": "The email of the member to revoke the badge from",
"Authorization headers are injected automatically from your connection.": "授权头自动从您的连接中注入。",
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
"GET": "获取",
"POST": "帖子",
"PATCH": "PATCH",
"PUT": "弹出",
"DELETE": "删除",
"HEAD": "黑色"
}

View File

@@ -0,0 +1,35 @@
import { createCustomApiCallAction } from '@activepieces/pieces-common';
import { createPiece } from '@activepieces/pieces-framework';
import { PieceCategory } from '@activepieces/shared';
import { assignBadgeAction } from './lib/actions/assign-badge';
import { createDiscussionAction } from './lib/actions/create-discussion';
import { createQuestionAction } from './lib/actions/create-question';
import { revokeBadgeAction } from './lib/actions/revoke-badge';
import { bettermodeAuth } from './lib/auth';
import { getAuthToken } from './lib/api';
export const bettermode = createPiece({
displayName: 'Bettermode',
description: 'Feature-rich engagement platform. Browse beautifully designed templates, each flexible for precise customization to your needs.',
auth: bettermodeAuth,
minimumSupportedRelease: '0.30.0',
logoUrl: 'https://cdn.activepieces.com/pieces/bettermode.png',
categories: [PieceCategory.MARKETING],
authors: ["joeworkman","kishanprmr","MoShizzle","abuaboud"],
actions: [
createDiscussionAction,
createQuestionAction,
assignBadgeAction,
revokeBadgeAction,
createCustomApiCallAction({
baseUrl: (auth) => auth ? auth.props.region : '', // replace with the actual base URL
auth: bettermodeAuth,
authMapping: async (auth) => ({
Authorization: `Bearer ${(await getAuthToken(auth.props)).token}`,
}),
}),
],
triggers: [],
});
// Bettermode API docs: https://developers.bettermode.com/

View File

@@ -0,0 +1,34 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { assignBadgeToMember } from '../api';
import { buildBadgesDropdown } from '../props';
import { bettermodeAuth } from '../auth';
export const assignBadgeAction = createAction({
name: 'assign_badge',
auth: bettermodeAuth,
displayName: 'Assign Badge to Member',
description: 'Assign an existing badge to a member by email',
props: {
badgeId: Property.Dropdown({
auth: bettermodeAuth,
displayName: 'Badge',
description: 'The badge to assign',
required: true,
refreshers: [],
options: async ({ auth }) =>
await buildBadgesDropdown(auth?.props),
}),
email: Property.ShortText({
displayName: 'Email',
description: 'The email of the member to assign the badge to',
required: true,
}),
},
async run(context) {
return await assignBadgeToMember(
context.auth.props,
context.propsValue.badgeId,
context.propsValue.email
);
},
});

View File

@@ -0,0 +1,53 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { createDiscussion } from '../api';
import { buildMemberSpacesDropdown } from '../props';
import { bettermodeAuth } from '../auth';
export const createDiscussionAction = createAction({
name: 'create_discussion',
auth: bettermodeAuth,
displayName: 'Create Discussion Post',
description: 'Create a new discussion post in a space',
props: {
spaceId: Property.Dropdown({
auth: bettermodeAuth,
displayName: 'Space',
description: 'The space to create the discussion in',
required: true,
refreshers: [],
options: async ({ auth }) =>
await buildMemberSpacesDropdown(auth?.props),
}),
title: Property.ShortText({
displayName: 'Title',
description: 'The title of the discussion',
required: true,
}),
content: Property.LongText({
displayName: 'Content',
description: 'The content of the discussion',
required: true,
}),
tagNames: Property.ShortText({
displayName: 'Tags',
description: 'The tags to add to the discussion',
required: false,
}),
locked: Property.Checkbox({
displayName: 'Locked',
description: 'If the discussion should be locked',
required: false,
defaultValue: false,
}),
},
async run(context) {
return await createDiscussion(
context.auth.props,
context.propsValue.spaceId,
context.propsValue.tagNames ?? '',
context.propsValue.title,
context.propsValue.content,
context.propsValue.locked
);
},
});

View File

@@ -0,0 +1,53 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { createQuestion } from '../api';
import { buildMemberSpacesDropdown } from '../props';
import { bettermodeAuth } from '../auth';
export const createQuestionAction = createAction({
name: 'create_question',
auth: bettermodeAuth,
displayName: 'Create Question Post',
description: 'Create a new question post in a space',
props: {
spaceId: Property.Dropdown({
auth: bettermodeAuth,
displayName: 'Space',
description: 'The space to create the question in',
required: true,
refreshers: [],
options: async ({ auth }) =>
await buildMemberSpacesDropdown(auth?.props),
}),
title: Property.ShortText({
displayName: 'Title',
description: 'The title of the question',
required: true,
}),
content: Property.LongText({
displayName: 'Content',
description: 'The content of the question',
required: true,
}),
tagNames: Property.ShortText({
displayName: 'Tags',
description: 'The tags to add to the question',
required: false,
}),
locked: Property.Checkbox({
displayName: 'Locked',
description: 'If the question should be locked',
required: false,
defaultValue: false,
}),
},
async run(context) {
return await createQuestion(
context.auth.props,
context.propsValue.spaceId,
context.propsValue.tagNames ?? '',
context.propsValue.title,
context.propsValue.content,
context.propsValue.locked
);
},
});

View File

@@ -0,0 +1,34 @@
import { createAction, Property } from '@activepieces/pieces-framework';
import { revokeBadgeFromMember } from '../api';
import { buildBadgesDropdown } from '../props';
import { bettermodeAuth } from '../auth';
export const revokeBadgeAction = createAction({
name: 'revoke_badge',
auth: bettermodeAuth,
displayName: 'Revoke Badge from Member',
description: 'Revoke a badge from a member by email',
props: {
badgeId: Property.Dropdown({
auth: bettermodeAuth,
displayName: 'Badge',
description: 'The badge to revoke',
required: true,
refreshers: [],
options: async ({ auth }) =>
await buildBadgesDropdown(auth?.props),
}),
email: Property.ShortText({
displayName: 'Email',
description: 'The email of the member to revoke the badge from',
required: true,
}),
},
async run(context) {
return await revokeBadgeFromMember(
context.auth.props,
context.propsValue.badgeId,
context.propsValue.email
);
},
});

View File

@@ -0,0 +1,292 @@
import {
httpClient,
HttpMethod,
HttpRequest,
} from '@activepieces/pieces-common';
import { BettermodeAuthType } from './auth';
type KeyValuePair = { [key: string]: string | boolean | object | undefined };
const bettermodeAPI = async (
auth: BettermodeAuthType,
query: string,
variables: KeyValuePair = {}
) => {
const request: HttpRequest = {
method: HttpMethod.POST,
url: auth.region,
headers: {
'Content-Type': 'application/json',
Authorization: auth.token ? `Bearer ${auth.token}` : undefined,
},
body: JSON.stringify({
query: query,
variables: variables,
}),
};
const response = await httpClient.sendRequest(request);
if (response.body['errors']) {
throw new Error(response.body['errors'][0]['message']);
}
return response.body['data'];
};
const getGuestToken = async (auth: BettermodeAuthType) => {
const query = `query GetGuestToken($domain: String!) {
tokens(networkDomain: $domain) {
accessToken
}
}`;
const variables = { domain: auth.domain };
const response = await bettermodeAPI(auth, query, variables);
auth.token = response.tokens.accessToken;
return auth;
};
export const getAuthToken = async (auth: BettermodeAuthType) => {
const query = `mutation getAuthToken($email: String!, $password: String!) {
loginNetwork(input:{usernameOrEmail: $email, password: $password}) {
accessToken
member {
id
name
}
}
}`;
const variables = {
email: auth.email,
password: auth.password,
};
auth = await getGuestToken(auth);
const response = await bettermodeAPI(auth, query, variables);
auth.token = response.loginNetwork.accessToken;
auth.memberId = response.loginNetwork.member.id;
return auth;
};
const getPostType = async (auth: BettermodeAuthType, postTypeName: string) => {
const query = `query getPostType($postTypeName: String!) {
postTypes(limit: 1, query: $postTypeName) {
nodes {
id
name
}
}
}`;
if (!auth.memberId) auth = await getAuthToken(auth);
const variables = { postTypeName: postTypeName };
const response = await bettermodeAPI(auth, query, variables);
return response.postTypes.nodes[0];
};
export const listBadges = async (auth: BettermodeAuthType) => {
const query = `query {
network {
badges {
id
name
}
}
}`;
if (!auth.memberId) auth = await getAuthToken(auth);
const response = await bettermodeAPI(auth, query);
return response.network.badges;
};
export const listMemberSpaces = async (auth: BettermodeAuthType) => {
const query = `query listMemberSpaces($memberId: ID!) {
spaces(memberId: $memberId, limit: 100) {
nodes {
id
name
}
}
}`;
if (!auth.memberId) auth = await getAuthToken(auth);
const variables = { memberId: auth.memberId };
const response = await bettermodeAPI(auth, query, variables);
return response.spaces.nodes;
};
const getMemberByEmail = async (auth: BettermodeAuthType, email: string) => {
const query = `query getMemberId($email: String!) {
members(limit: 1, query: $email) {
nodes {
id
name
}
}
}`;
if (!auth.memberId) auth = await getAuthToken(auth);
const variables = { email: email };
const response = await bettermodeAPI(auth, query, variables);
if (response.members.nodes.length == 0) {
throw new Error(`Member with email ${email} not found`);
}
return response.members.nodes[0];
};
export const assignBadgeToMember = async (
auth: BettermodeAuthType,
badgeId: string,
email: string
) => {
const query = `mutation assignBadgeToMember($badgeId: String!, $memberId: String!) {
assignBadge(
id: $badgeId,
input: {
memberId: $memberId,
}
) {
status
}
}`;
if (!auth.memberId) auth = await getAuthToken(auth);
const member = await getMemberByEmail(auth, email);
const variables = { badgeId: badgeId, memberId: member.id };
const response = await bettermodeAPI(auth, query, variables);
return response.assignBadge;
};
export const revokeBadgeFromMember = async (
auth: BettermodeAuthType,
badgeId: string,
email: string
) => {
const query = `mutation revokeBadgeFromMember($badgeId: String!, $memberId: String!) {
revokeBadge(
id: $badgeId,
input: {
memberId: $memberId,
}
) {
status
}
}`;
if (!auth.memberId) auth = await getAuthToken(auth);
const member = await getMemberByEmail(auth, email);
const variables = { badgeId: badgeId, memberId: member.id };
const response = await bettermodeAPI(auth, query, variables);
return response.revokeBadge;
};
export const createPostOfType = async (
auth: BettermodeAuthType,
postTypeName: string,
spaceId: string,
tagNames: string,
title: string,
content: string,
locked = false
) => {
const query = `mutation createPostOfType($spaceId: ID!, $postTypeId: String!, $locked: Boolean!, $tagNames: [String!], $title: String!, $content: String!) {
createPost(
spaceId : $spaceId,
input : {
postTypeId : $postTypeId,
locked : $locked,
publish : true,
tagNames : $tagNames,
mappingFields : [
{
key : "title",
type : text,
value : $title
},
{
key : "content",
type : html,
value : $content
}
]
}
) {
url
createdAt
}
}`;
auth = await getAuthToken(auth);
const postType = await getPostType(auth, postTypeName);
const variables = {
spaceId: spaceId,
postTypeId: postType.id,
locked: locked,
tagNames: tagNames.split(',').map((tag: string) => tag.trim()),
title: JSON.stringify(title),
content: JSON.stringify(content),
};
const response = await bettermodeAPI(auth, query, variables);
return response.createPost;
};
export const createDiscussion = async (
auth: BettermodeAuthType,
spaceId: string,
tagNames: string,
title: string,
content: string,
locked = false
) => {
return await createPostOfType(
auth,
'Discussion',
spaceId,
tagNames,
title,
content,
locked
);
};
export const createQuestion = async (
auth: BettermodeAuthType,
spaceId: string,
tagNames: string,
title: string,
content: string,
locked = false
) => {
return await createPostOfType(
auth,
'Question',
spaceId,
tagNames,
title,
content,
locked
);
};
// TODO: assignBadge to member

View File

@@ -0,0 +1,77 @@
import {
PieceAuth,
Property,
} from '@activepieces/pieces-framework';
import { z } from 'zod';
import { propsValidation } from '@activepieces/pieces-common';
import { getAuthToken } from './api';
export type BettermodeAuthType = {
region: string;
domain: string;
email: string;
password: string;
token?: string;
memberId?: string;
};
export const bettermodeAuth = PieceAuth.CustomAuth({
description:
'Your domain should be the base URL of your Bettermode community. Example: community.example.com',
props: {
region: Property.StaticDropdown({
displayName: 'Region',
description: 'The region of your Bettermode account',
required: true,
options: {
options: [
{ label: 'US Region', value: 'https://api.bettermode.com' },
{ label: 'EU Region', value: 'https://api.bettermode.de' },
],
},
}),
domain: Property.ShortText({
displayName: 'BetterMode Domain',
description: 'The domain of your Bettermode account',
required: true,
}),
email: Property.ShortText({
displayName: 'Email',
description: 'Email address for your Bettermode account',
required: true,
}),
password: PieceAuth.SecretText({
displayName: 'Password',
description: 'Password for your Bettermode account',
required: true,
}),
},
validate: async ({ auth }) => {
try {
await validateAuth(auth);
return {
valid: true,
};
} catch (e) {
return {
valid: false,
error: (e as Error)?.message,
};
}
},
required: true,
});
const validateAuth = async (auth: BettermodeAuthType) => {
await propsValidation.validateZod(auth, {
domain: z.string().url(),
email: z.string().email(),
});
const response = await getAuthToken(auth);
if (!response.memberId) {
throw new Error(
'Authentication failed. Please check your credentials and try again.'
);
}
};

View File

@@ -0,0 +1,36 @@
import { BettermodeAuthType } from './auth';
import { listMemberSpaces, listBadges } from './api';
export async function buildMemberSpacesDropdown(auth?: BettermodeAuthType) {
if (!auth) {
return {
options: [],
disabled: true,
placeholder: 'Please authenticate first',
};
}
const spaces = await listMemberSpaces(auth as BettermodeAuthType);
const options = spaces.map((space: { name: string; id: string }) => {
return { label: space.name, value: space.id };
});
return {
options: options,
};
}
export async function buildBadgesDropdown(auth?: BettermodeAuthType) {
if (!auth) {
return {
options: [],
disabled: true,
placeholder: 'Please authenticate first',
};
}
const badges = await listBadges(auth as BettermodeAuthType);
const options = badges.map((badge: { name: string; id: string }) => {
return { label: badge.name, value: badge.id };
});
return {
options: options,
};
}

View File

@@ -0,0 +1,19 @@
{
"extends": "../../../../tsconfig.base.json",
"compilerOptions": {
"module": "commonjs",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
}
]
}

View File

@@ -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"],
"include": ["src/**/*.ts"]
}