Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"extends": [
|
||||
"../../../../.eslintrc.base.json"
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"!**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx",
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# pieces-googlechat
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build pieces-googlechat` to build the library.
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "@activepieces/piece-googlechat",
|
||||
"version": "0.0.2",
|
||||
"type": "commonjs",
|
||||
"main": "./src/index.js",
|
||||
"types": "./src/index.d.ts",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "pieces-googlechat",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/googlechat/src",
|
||||
"projectType": "library",
|
||||
"release": {
|
||||
"version": {
|
||||
"manifestRootsToUpdate": [
|
||||
"dist/{projectRoot}"
|
||||
],
|
||||
"currentVersionResolver": "git-tag",
|
||||
"fallbackCurrentVersionResolver": "disk"
|
||||
}
|
||||
},
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/packages/pieces/community/googlechat",
|
||||
"tsConfig": "packages/pieces/community/googlechat/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/googlechat/package.json",
|
||||
"main": "packages/pieces/community/googlechat/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/googlechat/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/googlechat/src/i18n",
|
||||
"output": "./src/i18n",
|
||||
"glob": "**/!(i18n.json)"
|
||||
}
|
||||
],
|
||||
"buildableProjectDepsInPackageJsonType": "dependencies",
|
||||
"updateBuildableProjectDepsInPackageJson": true
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"prebuild"
|
||||
]
|
||||
},
|
||||
"nx-release-publish": {
|
||||
"options": {
|
||||
"packageRoot": "dist/{projectRoot}"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
]
|
||||
},
|
||||
"prebuild": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"cwd": "packages/pieces/community/googlechat",
|
||||
"command": "bun install --no-save --silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"Google Chat is a messaging app that allows you to send and receive messages, create spaces, and more.": "Google Chat ist eine Messaging-App, mit der Sie Nachrichten senden und empfangen können, Leerzeichen erstellen und vieles mehr.",
|
||||
"Send a Message": "Nachricht senden",
|
||||
"Get Direct Message Details": "Details der Direktnachricht erhalten",
|
||||
"Add a Space Member": "Ein Raummitglied hinzufügen",
|
||||
"Get Message Details": "Nachrichtendetails abrufen",
|
||||
"Search Messages": "Nachrichten suchen",
|
||||
"Find Member": "Mitglied finden",
|
||||
"Send a message to a space or direct conversation.": "Senden Sie eine Nachricht an einen Raum oder eine direkte Konversation.",
|
||||
"Retrieve details of a specific direct message by ID.": "Abrufen von Details einer bestimmten Direktnachricht per ID.",
|
||||
"Add a user to a Google Chat space.": "Fügen Sie einen Benutzer zu einem Google-Chat-Raum hinzu.",
|
||||
"Retrieve details of a specific message by ID. Supports both system-generated and custom message IDs.": "Abrufen von Details einer bestimmten Nachricht durch ID. Unterstützt sowohl systemgenerierte als auch benutzerdefinierte Nachrichten-IDs.",
|
||||
"Search within Chat for messages matching keywords or filters.": "Suche im Chat nach Nachrichten, die Keywords oder Filter entsprechen.",
|
||||
"Search space member by email": "Weltraummitglied per E-Mail suchen",
|
||||
"Space": "Raum",
|
||||
"Message": "Nachricht",
|
||||
"Thread": "Thread",
|
||||
"Reply Behavior": "Antwortverhalten",
|
||||
"Custom Message ID": "Eigene Nachrichten ID",
|
||||
"Send as Private Message": "Als private Nachricht senden",
|
||||
"Private Message Recipient": "Empfänger privater Nachrichten",
|
||||
"Direct Message": "Direkte Nachricht",
|
||||
"Select A Person": "Person auswählen",
|
||||
"Message Resource Name": "Nachrichtenressourcenname",
|
||||
"Keyword": "Keyword",
|
||||
"Max Results": "Maximale Ergebnisse",
|
||||
"Member Email": "Mitgliedsmail",
|
||||
"Select a Space": "Wählen Sie einen Raum",
|
||||
"The message content to send. Supports basic formatting like *bold*, _italic_, and @mentions.": "Der zu sendende Nachrichteninhalt. Unterstützt grundlegende Formatierungen wie *bold*, _italic_, und @Erwähnungen.",
|
||||
"Select a thread to reply to, leave empty for new thread": "Einen Thread auswählen, auf den geantwortet werden soll, leer lassen für neuen Thread",
|
||||
"How to handle replies when thread ID is provided.": "Wie mit Antworten umgegangen wird, wenn Thread-ID angegeben wird.",
|
||||
"Optional unique ID for this message (auto-generated if empty). Useful for deduplication.": "Optionale eindeutige ID für diese Nachricht (automatisch generiert wenn leer). Nützlich für Deduplication.",
|
||||
"Send this message privately to a specific user. Requires app authentication.": "Senden Sie diese Nachricht privat an einen bestimmten Benutzer. Benötigt App-Authentifizierung.",
|
||||
"Select the user who can view this private message.": "Wählen Sie den Benutzer, der diese private Nachricht sehen kann.",
|
||||
"Select a Direct Message": "Direkte Nachricht auswählen",
|
||||
"Select a person": "Person auswählen",
|
||||
"The full resource name of the message. Format: spaces/{space}/messages/{message}": "Der vollständige Ressourcenname der Nachricht. Format: Leerzeichen/{space}/messages/{message}",
|
||||
"Search for messages containing this text": "Nach Nachrichten mit diesem Text suchen",
|
||||
"Maximum number of messages to return": "Maximale Anzahl der Nachrichten die zurückgeschickt werden sollen",
|
||||
"The email address of the member to find": "Die E-Mail-Adresse des zu findenden Mitglieds",
|
||||
"Reply or start new thread": "Antworten oder neues Thema starten",
|
||||
"Reply only (fail if thread not found)": "Nur antworten (scheitern, wenn der Thread nicht gefunden wird)",
|
||||
"New Message": "Neue Nachricht",
|
||||
"New Mention": "Neue Erwähnung",
|
||||
"Triggers when a new message is received in Google Chat.": "Wird ausgelöst, wenn eine neue Nachricht im Google Chat empfangen wird.",
|
||||
"Triggers when a new mention is received in Google Chat.": "Wird ausgelöst, wenn eine neue Erwähnung im Google Chat empfangen wird.",
|
||||
"Project": "Projekt",
|
||||
"Space Member": "Raum-Mitglied",
|
||||
"Select a Google Cloud Project": "Wählen Sie ein Google Cloud Projekt",
|
||||
"Select a Space, leave empty for all spaces": "Wählen Sie einen Raum, lassen Sie leer für alle Leerzeichen",
|
||||
"Select a space member, leave empty for all members": "Wählen Sie ein Gruppenmitglied, lassen Sie leer für alle Mitglieder"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"Google Chat is a messaging app that allows you to send and receive messages, create spaces, and more.": "Google Chat es una aplicación de mensajería que te permite enviar y recibir mensajes, crear espacios, y más.",
|
||||
"Send a Message": "Enviar un mensaje",
|
||||
"Get Direct Message Details": "Obtener detalles del mensaje directo",
|
||||
"Add a Space Member": "Añadir un miembro espacial",
|
||||
"Get Message Details": "Detalles del mensaje",
|
||||
"Search Messages": "Buscar mensajes",
|
||||
"Find Member": "Buscar miembro",
|
||||
"Send a message to a space or direct conversation.": "Enviar un mensaje a un espacio o conversación directa.",
|
||||
"Retrieve details of a specific direct message by ID.": "Recuperar detalles de un mensaje directo específico por ID.",
|
||||
"Add a user to a Google Chat space.": "Añadir un usuario a un espacio de Google Chat.",
|
||||
"Retrieve details of a specific message by ID. Supports both system-generated and custom message IDs.": "Recuperar detalles de un mensaje específico por ID. Soporta tanto IDs de mensajes generados por el sistema como personalizados.",
|
||||
"Search within Chat for messages matching keywords or filters.": "Buscar en el chat mensajes que coincidan con palabras clave o filtros.",
|
||||
"Search space member by email": "Buscar miembro del espacio por email",
|
||||
"Space": "Espacio",
|
||||
"Message": "Mensaje",
|
||||
"Thread": "Hilo",
|
||||
"Reply Behavior": "Responder comportamiento",
|
||||
"Custom Message ID": "ID de mensaje personalizado",
|
||||
"Send as Private Message": "Enviar como mensaje privado",
|
||||
"Private Message Recipient": "Destinatario de mensajes privados",
|
||||
"Direct Message": "Mensaje directo",
|
||||
"Select A Person": "Seleccione una persona",
|
||||
"Message Resource Name": "Nombre del recurso del mensaje",
|
||||
"Keyword": "Keyword",
|
||||
"Max Results": "Resultados máximos",
|
||||
"Member Email": "Email de miembro",
|
||||
"Select a Space": "Seleccione un espacio",
|
||||
"The message content to send. Supports basic formatting like *bold*, _italic_, and @mentions.": "El contenido del mensaje a enviar. Soporta formato básico como *negrita*, _italic_, y @mentions.",
|
||||
"Select a thread to reply to, leave empty for new thread": "Selecciona un hilo para responder, déjalo vacío para un nuevo hilo",
|
||||
"How to handle replies when thread ID is provided.": "Cómo manejar las respuestas cuando el ID del hilo es proporcionado.",
|
||||
"Optional unique ID for this message (auto-generated if empty). Useful for deduplication.": "ID único opcional para este mensaje (auto-generado si está vacío). Útil para deduplicación.",
|
||||
"Send this message privately to a specific user. Requires app authentication.": "Enviar este mensaje de forma privada a un usuario específico. Requiere autenticación de la aplicación.",
|
||||
"Select the user who can view this private message.": "Seleccione el usuario que puede ver este mensaje privado.",
|
||||
"Select a Direct Message": "Seleccione un mensaje directo",
|
||||
"Select a person": "Seleccione una persona",
|
||||
"The full resource name of the message. Format: spaces/{space}/messages/{message}": "El nombre completo del recurso del mensaje. Formato: espacios/{space}/messages/{message}",
|
||||
"Search for messages containing this text": "Buscar mensajes que contengan este texto",
|
||||
"Maximum number of messages to return": "Número máximo de mensajes a devolver",
|
||||
"The email address of the member to find": "La dirección de correo electrónico del miembro a encontrar",
|
||||
"Reply or start new thread": "Responder o iniciar un nuevo hilo",
|
||||
"Reply only (fail if thread not found)": "Responder sólo (fallar si no se encuentra el hilo)",
|
||||
"New Message": "Nuevo mensaje",
|
||||
"New Mention": "Nueva Mención",
|
||||
"Triggers when a new message is received in Google Chat.": "Se activa cuando se recibe un nuevo mensaje en Google Chat.",
|
||||
"Triggers when a new mention is received in Google Chat.": "Dispara cuando se recibe una nueva mención en Google Chat.",
|
||||
"Project": "Projekt",
|
||||
"Space Member": "Miembro del espacio",
|
||||
"Select a Google Cloud Project": "Seleccione un proyecto de Google Cloud",
|
||||
"Select a Space, leave empty for all spaces": "Selecciona un espacio, déjalo vacío para todos los espacios",
|
||||
"Select a space member, leave empty for all members": "Seleccione un miembro de espacio, deje vacío para todos los miembros"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"Google Chat is a messaging app that allows you to send and receive messages, create spaces, and more.": "Google Chat est une application de messagerie qui vous permet d'envoyer et de recevoir des messages, de créer des espaces, et plus encore.",
|
||||
"Send a Message": "Envoyer un message",
|
||||
"Get Direct Message Details": "Obtenir les détails du message direct",
|
||||
"Add a Space Member": "Ajouter un membre de l'espace",
|
||||
"Get Message Details": "Obtenir les détails du message",
|
||||
"Search Messages": "Rechercher dans les messages",
|
||||
"Find Member": "Trouver un membre",
|
||||
"Send a message to a space or direct conversation.": "Envoyer un message à un espace ou une conversation directe.",
|
||||
"Retrieve details of a specific direct message by ID.": "Récupérer les détails d'un message direct spécifique par ID.",
|
||||
"Add a user to a Google Chat space.": "Ajouter un utilisateur à un espace Google Chat.",
|
||||
"Retrieve details of a specific message by ID. Supports both system-generated and custom message IDs.": "Récupère les détails d'un message spécifique par ID. Supporte les identifiants de messages générés par le système et personnalisés",
|
||||
"Search within Chat for messages matching keywords or filters.": "Rechercher dans le chat des messages correspondant à des mots-clés ou des filtres.",
|
||||
"Search space member by email": "Rechercher un membre de l'espace par e-mail",
|
||||
"Space": "Espace libre",
|
||||
"Message": "Message",
|
||||
"Thread": "Fil de discussion",
|
||||
"Reply Behavior": "Comportement de réponse",
|
||||
"Custom Message ID": "ID de message personnalisé",
|
||||
"Send as Private Message": "Envoyer comme message privé",
|
||||
"Private Message Recipient": "Destinataire du message privé",
|
||||
"Direct Message": "Message direct",
|
||||
"Select A Person": "Sélectionner une personne",
|
||||
"Message Resource Name": "Nom de la ressource de message",
|
||||
"Keyword": "Keyword",
|
||||
"Max Results": "Nombre maximum de résultats",
|
||||
"Member Email": "E-mail du membre",
|
||||
"Select a Space": "Sélectionnez un espace",
|
||||
"The message content to send. Supports basic formatting like *bold*, _italic_, and @mentions.": "Le contenu du message à envoyer. Supporte le formatage de base comme *bold*, _italic_, et @mentions.",
|
||||
"Select a thread to reply to, leave empty for new thread": "Sélectionnez un fil de discussion auquel répondre, laissez vide pour un nouveau fil",
|
||||
"How to handle replies when thread ID is provided.": "Comment gérer les réponses lorsque l'ID du fil est fourni.",
|
||||
"Optional unique ID for this message (auto-generated if empty). Useful for deduplication.": "Identifiant unique optionnel pour ce message (généré automatiquement si vide). Utile pour la déduplication",
|
||||
"Send this message privately to a specific user. Requires app authentication.": "Envoyer ce message en privé à un utilisateur spécifique. Nécessite l'authentification de l'application.",
|
||||
"Select the user who can view this private message.": "Sélectionnez l'utilisateur qui peut voir ce message privé.",
|
||||
"Select a Direct Message": "Sélectionnez un message direct",
|
||||
"Select a person": "Sélectionner une personne",
|
||||
"The full resource name of the message. Format: spaces/{space}/messages/{message}": "Le nom complet de la ressource du message. Format: espaces/{space}/messages/{message}",
|
||||
"Search for messages containing this text": "Rechercher des messages contenant ce texte",
|
||||
"Maximum number of messages to return": "Nombre maximum de messages à retourner",
|
||||
"The email address of the member to find": "L'adresse email du membre à trouver",
|
||||
"Reply or start new thread": "Répondre ou démarrer un nouveau sujet",
|
||||
"Reply only (fail if thread not found)": "Répondre seulement (échouer si le fil n'est pas trouvé)",
|
||||
"New Message": "Nouveau message",
|
||||
"New Mention": "Nouvelle mention",
|
||||
"Triggers when a new message is received in Google Chat.": "Déclenche lorsqu'un nouveau message est reçu dans Google Chat.",
|
||||
"Triggers when a new mention is received in Google Chat.": "Déclenche quand une nouvelle mention est reçue dans Google Chat.",
|
||||
"Project": "Votre compte",
|
||||
"Space Member": "Membre de l'espace",
|
||||
"Select a Google Cloud Project": "Sélectionnez un projet Google Cloud",
|
||||
"Select a Space, leave empty for all spaces": "Sélectionnez un espace, laissez vide pour tous les espaces",
|
||||
"Select a space member, leave empty for all members": "Sélectionnez un membre de l'espace, laissez vide pour tous les membres"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"Google Chat is a messaging app that allows you to send and receive messages, create spaces, and more.": "Googleチャットは、メッセージの送受信、スペースの作成などを可能にするメッセージングアプリです。",
|
||||
"Send a Message": "メッセージを送信",
|
||||
"Get Direct Message Details": "ダイレクトメッセージの詳細を取得する",
|
||||
"Add a Space Member": "スペースメンバーを追加",
|
||||
"Get Message Details": "メッセージの詳細を取得",
|
||||
"Search Messages": "メッセージを検索",
|
||||
"Find Member": "メンバーを探す",
|
||||
"Send a message to a space or direct conversation.": "メッセージをスペースまたは直接会話に送信します。",
|
||||
"Retrieve details of a specific direct message by ID.": "IDによる特定のダイレクトメッセージの詳細を取得します。",
|
||||
"Add a user to a Google Chat space.": "ユーザーをGoogleチャットスペースに追加します。",
|
||||
"Retrieve details of a specific message by ID. Supports both system-generated and custom message IDs.": "IDで特定のメッセージの詳細を取得します。システムで生成されたメッセージIDとカスタムメッセージIDの両方をサポートしています。",
|
||||
"Search within Chat for messages matching keywords or filters.": "キーワードまたはフィルターに一致するメッセージをチャット内で検索します。",
|
||||
"Search space member by email": "Eメールでスペースメンバーを検索",
|
||||
"Space": "スペース",
|
||||
"Message": "メッセージ",
|
||||
"Thread": "スレッド",
|
||||
"Reply Behavior": "返信の動作",
|
||||
"Custom Message ID": "カスタムメッセージID",
|
||||
"Send as Private Message": "プライベートメッセージとして送信",
|
||||
"Private Message Recipient": "プライベートメッセージの受信者",
|
||||
"Direct Message": "ダイレクトメッセージ",
|
||||
"Select A Person": "人を選択",
|
||||
"Message Resource Name": "メッセージリソース名",
|
||||
"Keyword": "Keyword",
|
||||
"Max Results": "最大結果",
|
||||
"Member Email": "メンバーのメールアドレス",
|
||||
"Select a Space": "スペースを選択",
|
||||
"The message content to send. Supports basic formatting like *bold*, _italic_, and @mentions.": "送信するメッセージの内容。*bold*、_italic_、@mentionsのような基本的なフォーマットに対応しています。",
|
||||
"Select a thread to reply to, leave empty for new thread": "返信するスレッドを選択します。新しいスレッドの場合は空にします。",
|
||||
"How to handle replies when thread ID is provided.": "スレッドIDが与えられたときに返信を処理する方法。",
|
||||
"Optional unique ID for this message (auto-generated if empty). Useful for deduplication.": "このメッセージの任意の一意のID(空の場合は自動生成されます)。重複排除に便利です。",
|
||||
"Send this message privately to a specific user. Requires app authentication.": "このメッセージを個人的に特定のユーザーに送信します。アプリ認証が必要です。",
|
||||
"Select the user who can view this private message.": "このプライベートメッセージを表示できるユーザを選択します。",
|
||||
"Select a Direct Message": "ダイレクトメッセージを選択",
|
||||
"Select a person": "人を選択",
|
||||
"The full resource name of the message. Format: spaces/{space}/messages/{message}": "メッセージの完全なリソース名。フォーマット: spaces/{space}/messages/{message}",
|
||||
"Search for messages containing this text": "このテキストを含むメッセージを検索",
|
||||
"Maximum number of messages to return": "Maximum number of messages to return",
|
||||
"The email address of the member to find": "見つけるメンバーのメールアドレス",
|
||||
"Reply or start new thread": "新しいスレッドに返信または開始する",
|
||||
"Reply only (fail if thread not found)": "返信のみ (スレッドが見つからない場合は失敗)",
|
||||
"New Message": "新しいメッセージ",
|
||||
"New Mention": "新規メンション",
|
||||
"Triggers when a new message is received in Google Chat.": "Google チャットで新しいメッセージを受信したときにトリガーします。",
|
||||
"Triggers when a new mention is received in Google Chat.": "Google チャットで新しいメンションが受信されたときにトリガーします。",
|
||||
"Project": "プロジェクト",
|
||||
"Space Member": "スペースメンバー",
|
||||
"Select a Google Cloud Project": "Google Cloud プロジェクトを選択",
|
||||
"Select a Space, leave empty for all spaces": "スペースを選択します。すべてのスペースは空のままにします。",
|
||||
"Select a space member, leave empty for all members": "スペースメンバーを選択し、すべてのメンバーに空白のままにします"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"Google Chat is a messaging app that allows you to send and receive messages, create spaces, and more.": "Google Chat is een berichten-app waarmee u berichten kunt verzenden en ontvangen, spaties kunt maken en meer.",
|
||||
"Send a Message": "Stuur een bericht",
|
||||
"Get Direct Message Details": "Krijg direct bericht details",
|
||||
"Add a Space Member": "Voeg een ruimtelid toe",
|
||||
"Get Message Details": "Krijg berichtdetails",
|
||||
"Search Messages": "Zoek berichten",
|
||||
"Find Member": "Lid zoeken",
|
||||
"Send a message to a space or direct conversation.": "Stuur een bericht naar een spatie of een direct gesprek.",
|
||||
"Retrieve details of a specific direct message by ID.": "Haal details op van een specifiek direct bericht met ID.",
|
||||
"Add a user to a Google Chat space.": "Voeg een gebruiker toe aan een Google-chatruimte.",
|
||||
"Retrieve details of a specific message by ID. Supports both system-generated and custom message IDs.": "Ophalen details van een specifiek bericht door ID. Ondersteunt zowel door systeem gegenereerde en aangepaste bericht-ID's.",
|
||||
"Search within Chat for messages matching keywords or filters.": "Zoeken in Chat naar trefwoorden of filters.",
|
||||
"Search space member by email": "Zoek ruimtellid via e-mail",
|
||||
"Space": "Spatiebalk",
|
||||
"Message": "bericht",
|
||||
"Thread": "Conversatie",
|
||||
"Reply Behavior": "Antwoord gedrag",
|
||||
"Custom Message ID": "Aangepast bericht-ID",
|
||||
"Send as Private Message": "Versturen als privébericht",
|
||||
"Private Message Recipient": "Ontvanger privébericht",
|
||||
"Direct Message": "Direct Bericht",
|
||||
"Select A Person": "Selecteer een persoon",
|
||||
"Message Resource Name": "Berichtbron naam",
|
||||
"Keyword": "Keyword",
|
||||
"Max Results": "Max. aantal resultaten",
|
||||
"Member Email": "E-mail gebruiker",
|
||||
"Select a Space": "Selecteer een ruimte",
|
||||
"The message content to send. Supports basic formatting like *bold*, _italic_, and @mentions.": "De inhoud van het te verzenden bericht. Ondersteunt de basisopmaak zoals *bold*, _italic_, en @mentions.",
|
||||
"Select a thread to reply to, leave empty for new thread": "Selecteer een thread waarop u wilt reageren, laat leeg voor nieuwe thread",
|
||||
"How to handle replies when thread ID is provided.": "Hoe te handelen met antwoorden wanneer thread-ID wordt verstrekt.",
|
||||
"Optional unique ID for this message (auto-generated if empty). Useful for deduplication.": "Optionele unieke ID voor dit bericht (automatisch gegenereerd indien leeg). Nuttig voor deduplicatie.",
|
||||
"Send this message privately to a specific user. Requires app authentication.": "Stuur dit bericht privé naar een specifieke gebruiker. Vereist app-authenticatie.",
|
||||
"Select the user who can view this private message.": "Selecteer de gebruiker die dit privébericht kan bekijken.",
|
||||
"Select a Direct Message": "Selecteer een persoonlijk bericht",
|
||||
"Select a person": "Selecteer een persoon",
|
||||
"The full resource name of the message. Format: spaces/{space}/messages/{message}": "De volledige resourcenaam van het bericht. Formaat: spaties/{space}/messages/{message}",
|
||||
"Search for messages containing this text": "Zoeken naar berichten die deze tekst bevatten",
|
||||
"Maximum number of messages to return": "Maximum aantal berichten om te retourneren",
|
||||
"The email address of the member to find": "Het e-mailadres van het lid om te vinden",
|
||||
"Reply or start new thread": "Antwoord of begin nieuwe thread",
|
||||
"Reply only (fail if thread not found)": "Alleen antwoorden (mislukt als discussie niet is gevonden)",
|
||||
"New Message": "Nieuw bericht",
|
||||
"New Mention": "Nieuwe vermelding",
|
||||
"Triggers when a new message is received in Google Chat.": "Triggert wanneer een nieuw bericht wordt ontvangen in Google Chat.",
|
||||
"Triggers when a new mention is received in Google Chat.": "Triggert wanneer een nieuwe vermelding wordt ontvangen in Google Chat.",
|
||||
"Project": "Project",
|
||||
"Space Member": "Ruimte lid",
|
||||
"Select a Google Cloud Project": "Selecteer een Google Cloud project",
|
||||
"Select a Space, leave empty for all spaces": "Selecteer een ruimte, laat leeg voor alle ruimtes",
|
||||
"Select a space member, leave empty for all members": "Selecteer een ruimte-lid, laat leeg voor alle leden"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"Google Chat is a messaging app that allows you to send and receive messages, create spaces, and more.": "O Google Chat é um aplicativo de mensagens que lhe permite enviar e receber mensagens, criar espaços e muito mais.",
|
||||
"Send a Message": "Enviar uma mensagem",
|
||||
"Get Direct Message Details": "Obter os detalhes da mensagem direta",
|
||||
"Add a Space Member": "Adicionar um membro ao espaço",
|
||||
"Get Message Details": "Obter detalhes da mensagem",
|
||||
"Search Messages": "Pesquisar mensagens",
|
||||
"Find Member": "Localizar Membro",
|
||||
"Send a message to a space or direct conversation.": "Enviar uma mensagem a um espaço ou conversa direta.",
|
||||
"Retrieve details of a specific direct message by ID.": "Recuperar detalhes de uma mensagem direta específica por ID.",
|
||||
"Add a user to a Google Chat space.": "Adicionar um usuário para o Espaço de Chat do Google.",
|
||||
"Retrieve details of a specific message by ID. Supports both system-generated and custom message IDs.": "Recuperar detalhes de uma mensagem específica por ID. Suporta IDs de mensagem gerados pelo sistema e personalizados.",
|
||||
"Search within Chat for messages matching keywords or filters.": "Buscar no bate-papo por mensagens que correspondam a palavras-chave ou filtros.",
|
||||
"Search space member by email": "Pesquisar membro da comunidade por e-mail",
|
||||
"Space": "Sala",
|
||||
"Message": "mensagem",
|
||||
"Thread": "Tópico",
|
||||
"Reply Behavior": "Comportamento de Resposta",
|
||||
"Custom Message ID": "ID da mensagem personalizada",
|
||||
"Send as Private Message": "Enviar como mensagem privada",
|
||||
"Private Message Recipient": "Destinatário da Mensagem Privada",
|
||||
"Direct Message": "Mensagem direta",
|
||||
"Select A Person": "Selecionar uma pessoa",
|
||||
"Message Resource Name": "Nome do recurso",
|
||||
"Keyword": "Keyword",
|
||||
"Max Results": "Resultados no Máx.",
|
||||
"Member Email": "E-mail de membro",
|
||||
"Select a Space": "Selecione um Espaço",
|
||||
"The message content to send. Supports basic formatting like *bold*, _italic_, and @mentions.": "O conteúdo da mensagem a enviar. Suporta formatação básica como *bold*, _italic_, e @menções.",
|
||||
"Select a thread to reply to, leave empty for new thread": "Selecione um tópico para responder, deixe vazio para o novo tópico",
|
||||
"How to handle replies when thread ID is provided.": "Como manipular respostas quando o ID do tópico é fornecido.",
|
||||
"Optional unique ID for this message (auto-generated if empty). Useful for deduplication.": "ID única opcional para esta mensagem (gerada automaticamente se vazia). Útil para desduplicação.",
|
||||
"Send this message privately to a specific user. Requires app authentication.": "Enviar esta mensagem em particular para um usuário específico. Requer autenticação de aplicativos.",
|
||||
"Select the user who can view this private message.": "Selecione o usuário que pode ver esta mensagem privada.",
|
||||
"Select a Direct Message": "Selecione uma mensagem direta",
|
||||
"Select a person": "Selecione uma pessoa",
|
||||
"The full resource name of the message. Format: spaces/{space}/messages/{message}": "O nome completo do recurso da mensagem. Formato: espaços/{space}/mensagens/{message}",
|
||||
"Search for messages containing this text": "Procurar mensagens que contenham este texto",
|
||||
"Maximum number of messages to return": "Número máximo de mensagens para retornar",
|
||||
"The email address of the member to find": "O endereço de e-mail do membro para localizar",
|
||||
"Reply or start new thread": "Responder ou começar um novo tópico",
|
||||
"Reply only (fail if thread not found)": "Responder apenas (falha se o tópico não for encontrado)",
|
||||
"New Message": "Nova mensagem",
|
||||
"New Mention": "Nova menção",
|
||||
"Triggers when a new message is received in Google Chat.": "Aciona quando uma nova mensagem é recebida no Google Chat.",
|
||||
"Triggers when a new mention is received in Google Chat.": "Dispara quando uma nova menção é recebida no Google Chat.",
|
||||
"Project": "Projecto",
|
||||
"Space Member": "Membro do Espaço",
|
||||
"Select a Google Cloud Project": "Selecione um projeto no Google Cloud",
|
||||
"Select a Space, leave empty for all spaces": "Selecione um Espaço, deixe em branco para todos os espaços",
|
||||
"Select a space member, leave empty for all members": "Selecione um membro do espaço, deixe em branco para todos os membros"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"Google Chat is a messaging app that allows you to send and receive messages, create spaces, and more.": "Google Chat is a messaging app that allows you to send and receive messages, create spaces, and more.",
|
||||
"Send a Message": "Send a Message",
|
||||
"Get Direct Message Details": "Get Direct Message Details",
|
||||
"Add a Space Member": "Add a Space Member",
|
||||
"Get Message Details": "Get Message Details",
|
||||
"Search Messages": "Search Messages",
|
||||
"Find Member": "Find Member",
|
||||
"Send a message to a space or direct conversation.": "Send a message to a space or direct conversation.",
|
||||
"Retrieve details of a specific direct message by ID.": "Retrieve details of a specific direct message by ID.",
|
||||
"Add a user to a Google Chat space.": "Add a user to a Google Chat space.",
|
||||
"Retrieve details of a specific message by ID. Supports both system-generated and custom message IDs.": "Retrieve details of a specific message by ID. Supports both system-generated and custom message IDs.",
|
||||
"Search within Chat for messages matching keywords or filters.": "Search within Chat for messages matching keywords or filters.",
|
||||
"Search space member by email": "Search space member by email",
|
||||
"Space": "Space",
|
||||
"Message": "Message",
|
||||
"Thread": "Thread",
|
||||
"Reply Behavior": "Reply Behavior",
|
||||
"Custom Message ID": "Custom Message ID",
|
||||
"Send as Private Message": "Send as Private Message",
|
||||
"Private Message Recipient": "Private Message Recipient",
|
||||
"Direct Message": "Direct Message",
|
||||
"Select A Person": "Select A Person",
|
||||
"Message Resource Name": "Message Resource Name",
|
||||
"Keyword": "Keyword",
|
||||
"Max Results": "Max Results",
|
||||
"Member Email": "Member Email",
|
||||
"Select a Space": "Select a Space",
|
||||
"The message content to send. Supports basic formatting like *bold*, _italic_, and @mentions.": "The message content to send. Supports basic formatting like *bold*, _italic_, and @mentions.",
|
||||
"Select a thread to reply to, leave empty for new thread": "Select a thread to reply to, leave empty for new thread",
|
||||
"How to handle replies when thread ID is provided.": "How to handle replies when thread ID is provided.",
|
||||
"Optional unique ID for this message (auto-generated if empty). Useful for deduplication.": "Optional unique ID for this message (auto-generated if empty). Useful for deduplication.",
|
||||
"Send this message privately to a specific user. Requires app authentication.": "Send this message privately to a specific user. Requires app authentication.",
|
||||
"Select the user who can view this private message.": "Select the user who can view this private message.",
|
||||
"Select a Direct Message": "Select a Direct Message",
|
||||
"Select a person": "Select a person",
|
||||
"The full resource name of the message. Format: spaces/{space}/messages/{message}": "The full resource name of the message. Format: spaces/{space}/messages/{message}",
|
||||
"Search for messages containing this text": "Search for messages containing this text",
|
||||
"Maximum number of messages to return": "Maximum number of messages to return",
|
||||
"The email address of the member to find": "The email address of the member to find",
|
||||
"Reply or start new thread": "Reply or start new thread",
|
||||
"Reply only (fail if thread not found)": "Reply only (fail if thread not found)",
|
||||
"New Message": "New Message",
|
||||
"New Mention": "New Mention",
|
||||
"Triggers when a new message is received in Google Chat.": "Triggers when a new message is received in Google Chat.",
|
||||
"Triggers when a new mention is received in Google Chat.": "Triggers when a new mention is received in Google Chat.",
|
||||
"Project": "Project",
|
||||
"Space Member": "Space Member",
|
||||
"Select a Google Cloud Project": "Select a Google Cloud Project",
|
||||
"Select a Space, leave empty for all spaces": "Select a Space, leave empty for all spaces",
|
||||
"Select a space member, leave empty for all members": "Select a space member, leave empty for all members"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"Google Chat is a messaging app that allows you to send and receive messages, create spaces, and more.": "Google Chat is a messaging app that allows you to send and receive messages, create spaces, and more.",
|
||||
"Send a Message": "Send a Message",
|
||||
"Get Direct Message Details": "Get Direct Message Details",
|
||||
"Add a Space Member": "Add a Space Member",
|
||||
"Get Message Details": "Get Message Details",
|
||||
"Search Messages": "Search Messages",
|
||||
"Find Member": "Find Member",
|
||||
"Send a message to a space or direct conversation.": "Send a message to a space or direct conversation.",
|
||||
"Retrieve details of a specific direct message by ID.": "Retrieve details of a specific direct message by ID.",
|
||||
"Add a user to a Google Chat space.": "Add a user to a Google Chat space.",
|
||||
"Retrieve details of a specific message by ID. Supports both system-generated and custom message IDs.": "Retrieve details of a specific message by ID. Supports both system-generated and custom message IDs.",
|
||||
"Search within Chat for messages matching keywords or filters.": "Search within Chat for messages matching keywords or filters.",
|
||||
"Search space member by email": "Search space member by email",
|
||||
"Space": "Space",
|
||||
"Message": "Message",
|
||||
"Thread": "Thread",
|
||||
"Reply Behavior": "Reply Behavior",
|
||||
"Custom Message ID": "Custom Message ID",
|
||||
"Send as Private Message": "Send as Private Message",
|
||||
"Private Message Recipient": "Private Message Recipient",
|
||||
"Direct Message": "Direct Message",
|
||||
"Select A Person": "Select A Person",
|
||||
"Message Resource Name": "Message Resource Name",
|
||||
"Keyword": "Keyword",
|
||||
"Max Results": "Max Results",
|
||||
"Member Email": "Member Email",
|
||||
"Select a Space": "Select a Space",
|
||||
"The message content to send. Supports basic formatting like *bold*, _italic_, and @mentions.": "The message content to send. Supports basic formatting like *bold*, _italic_, and @mentions.",
|
||||
"Select a thread to reply to, leave empty for new thread": "Select a thread to reply to, leave empty for new thread",
|
||||
"How to handle replies when thread ID is provided.": "How to handle replies when thread ID is provided.",
|
||||
"Optional unique ID for this message (auto-generated if empty). Useful for deduplication.": "Optional unique ID for this message (auto-generated if empty). Useful for deduplication.",
|
||||
"Send this message privately to a specific user. Requires app authentication.": "Send this message privately to a specific user. Requires app authentication.",
|
||||
"Select the user who can view this private message.": "Select the user who can view this private message.",
|
||||
"Select a Direct Message": "Select a Direct Message",
|
||||
"Select a person": "Select a person",
|
||||
"The full resource name of the message. Format: spaces/{space}/messages/{message}": "The full resource name of the message. Format: spaces/{space}/messages/{message}",
|
||||
"Search for messages containing this text": "Search for messages containing this text",
|
||||
"Maximum number of messages to return": "Maximum number of messages to return",
|
||||
"The email address of the member to find": "The email address of the member to find",
|
||||
"Reply or start new thread": "Reply or start new thread",
|
||||
"Reply only (fail if thread not found)": "Reply only (fail if thread not found)",
|
||||
"New Message": "New Message",
|
||||
"New Mention": "New Mention",
|
||||
"Triggers when a new message is received in Google Chat.": "Triggers when a new message is received in Google Chat.",
|
||||
"Triggers when a new mention is received in Google Chat.": "Triggers when a new mention is received in Google Chat.",
|
||||
"Project": "项目",
|
||||
"Space Member": "Space Member",
|
||||
"Select a Google Cloud Project": "Select a Google Cloud Project",
|
||||
"Select a Space, leave empty for all spaces": "Select a Space, leave empty for all spaces",
|
||||
"Select a space member, leave empty for all members": "Select a space member, leave empty for all members"
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { createPiece, PieceAuth } from '@activepieces/pieces-framework';
|
||||
import { googleChatApiAuth } from './lib/common/constants';
|
||||
import { newMessage } from './lib/triggers/new-message';
|
||||
import { newMention } from './lib/triggers/new-mention';
|
||||
import { sendAMessage } from './lib/actions/send-a-message';
|
||||
import { getDirectMessageDetails } from './lib/actions/get-direct-message-details';
|
||||
import { addASpaceMember } from './lib/actions/add-a-space-member';
|
||||
import { getMessageDetails } from './lib/actions/get-message';
|
||||
import { searchMessages } from './lib/actions/search-messages';
|
||||
import { findMember } from './lib/actions/find-member';
|
||||
import { PieceCategory } from '@activepieces/shared';
|
||||
|
||||
export const googlechat = createPiece({
|
||||
displayName: 'Google Chat',
|
||||
auth: googleChatApiAuth,
|
||||
minimumSupportedRelease: '0.36.1',
|
||||
description: 'Google Chat is a messaging app that allows you to send and receive messages, create spaces, and more.',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/googlechat.png',
|
||||
categories: [PieceCategory.COMMUNICATION],
|
||||
authors: ["gs03-dev", "onyedikachi-david"],
|
||||
actions: [
|
||||
sendAMessage,
|
||||
getDirectMessageDetails,
|
||||
addASpaceMember,
|
||||
getMessageDetails,
|
||||
searchMessages,
|
||||
findMember
|
||||
],
|
||||
triggers: [
|
||||
newMessage,
|
||||
newMention
|
||||
],
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { propsValidation } from '@activepieces/pieces-common';
|
||||
import { googleChatApiAuth, googleChatCommon } from '../common';
|
||||
import { peoplesDropdown, spacesDropdown, spacesMembersDropdown } from '../common/props';
|
||||
import { googleChatAPIService } from '../common/requests';
|
||||
|
||||
export const addASpaceMember = createAction({
|
||||
auth: googleChatApiAuth,
|
||||
name: 'addASpaceMember',
|
||||
displayName: 'Add a Space Member',
|
||||
description: 'Add a user to a Google Chat space.',
|
||||
props: {
|
||||
spaceId: spacesDropdown({ refreshers: ['auth'], required: true }),
|
||||
personId: peoplesDropdown(['auth']),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
await propsValidation.validateZod(propsValue, googleChatCommon.addSpaceMemberSchema);
|
||||
|
||||
const { spaceId, personId } = propsValue;
|
||||
|
||||
const userId = (personId as string).replace('people', 'users');
|
||||
|
||||
const response = await googleChatAPIService.AddASpaceMember({
|
||||
accessToken: auth.access_token,
|
||||
spaceId: spaceId as string,
|
||||
userId: userId as string
|
||||
})
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { propsValidation } from '@activepieces/pieces-common';
|
||||
import { googleChatApiAuth, googleChatCommon } from '../common';
|
||||
import { spacesDropdown } from '../common/props';
|
||||
import { googleChatAPIService } from '../common/requests';
|
||||
|
||||
export const findMember = createAction({
|
||||
auth: googleChatApiAuth,
|
||||
name: 'findMember',
|
||||
displayName: 'Find Member',
|
||||
description: 'Search space member by email',
|
||||
props: {
|
||||
spaceId: spacesDropdown({ refreshers: ['auth'], required: true }),
|
||||
email: Property.ShortText({
|
||||
displayName: 'Member Email',
|
||||
description: 'The email address of the member to find',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
await propsValidation.validateZod(propsValue, googleChatCommon.findMemberSchema);
|
||||
|
||||
const { spaceId, email } = propsValue;
|
||||
const accessToken = auth.access_token;
|
||||
|
||||
try {
|
||||
const people = await googleChatAPIService.fetchPeople(
|
||||
accessToken
|
||||
);
|
||||
|
||||
const person = people.find((p: any) =>
|
||||
p?.emailAddresses?.some(
|
||||
(e: any) => e.value.toLowerCase() === email.toLowerCase()
|
||||
)
|
||||
);
|
||||
|
||||
if (!person) return { error: `No user found with email ${email}` };
|
||||
|
||||
const spaceMemberId = (person.resourceName as string).replace('people', 'users');
|
||||
|
||||
const spaceMembers = await googleChatAPIService.fetchSpaceMembers(
|
||||
accessToken,
|
||||
spaceId as string
|
||||
);
|
||||
|
||||
const matchingMember = spaceMembers.find(
|
||||
(m: any) => m.member?.name === spaceMemberId
|
||||
);
|
||||
|
||||
if (!matchingMember) return {
|
||||
error: `${email} is not a member of space ${spaceId}`,
|
||||
};
|
||||
|
||||
return matchingMember;
|
||||
} catch (e) {
|
||||
console.error('Error finding member by email', e);
|
||||
return { error: 'Failed to retrieve member information' };
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { propsValidation } from '@activepieces/pieces-common';
|
||||
import { googleChatApiAuth, googleChatCommon } from '../common';
|
||||
import { directMessagesDropdown, spacesDropdown } from '../common/props';
|
||||
import { googleChatAPIService } from '../common/requests';
|
||||
|
||||
export const getDirectMessageDetails = createAction({
|
||||
auth: googleChatApiAuth,
|
||||
name: 'getDirectMessageDetails',
|
||||
displayName: 'Get Direct Message Details',
|
||||
description: 'Retrieve details of a specific direct message by ID.',
|
||||
props: {
|
||||
directMessageId: directMessagesDropdown({ refreshers: ['auth'], required: true }),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
await propsValidation.validateZod(propsValue, googleChatCommon.getDirectMessageDetailsSchema);
|
||||
|
||||
const { directMessageId } = propsValue;
|
||||
|
||||
const response = await googleChatAPIService.getSpace({
|
||||
accessToken: auth.access_token,
|
||||
spaceId: directMessageId as string,
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { propsValidation } from '@activepieces/pieces-common';
|
||||
import { googleChatApiAuth, googleChatCommon } from '../common';
|
||||
import { googleChatAPIService } from '../common/requests';
|
||||
|
||||
export const getMessageDetails = createAction({
|
||||
auth: googleChatApiAuth,
|
||||
name: 'getMessageDetails',
|
||||
displayName: 'Get Message Details',
|
||||
description: 'Retrieve details of a specific message by ID. Supports both system-generated and custom message IDs.',
|
||||
props: {
|
||||
name: Property.ShortText({
|
||||
displayName: 'Message Resource Name',
|
||||
description: 'The full resource name of the message. Format: spaces/{space}/messages/{message}',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
await propsValidation.validateZod(propsValue, googleChatCommon.getMessageSchema);
|
||||
|
||||
const { name } = propsValue;
|
||||
|
||||
const message = await googleChatAPIService.getMessage(
|
||||
auth.access_token,
|
||||
name
|
||||
);
|
||||
|
||||
return message;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { propsValidation } from '@activepieces/pieces-common';
|
||||
import { googleChatApiAuth, googleChatCommon } from '../common';
|
||||
import { allSpacesDropdown } from '../common/props';
|
||||
import { googleChatAPIService } from '../common/requests';
|
||||
|
||||
export const searchMessages = createAction({
|
||||
auth: googleChatApiAuth,
|
||||
name: 'searchMessages',
|
||||
displayName: 'Search Messages',
|
||||
description: 'Search within Chat for messages matching keywords or filters.',
|
||||
props: {
|
||||
spaceId: allSpacesDropdown({ refreshers: ['auth'], required: true }),
|
||||
keyword: Property.ShortText({
|
||||
displayName: 'Keyword',
|
||||
description: 'Search for messages containing this text',
|
||||
required: true,
|
||||
}),
|
||||
limit: Property.Number({
|
||||
displayName: 'Max Results',
|
||||
description: 'Maximum number of messages to return',
|
||||
required: false,
|
||||
defaultValue: 50,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
await propsValidation.validateZod(propsValue, googleChatCommon.searchMessagesSchema);
|
||||
|
||||
const { spaceId, keyword, limit } = propsValue;
|
||||
|
||||
const response = await googleChatAPIService.listMessages(
|
||||
auth.access_token,
|
||||
spaceId as string,
|
||||
limit
|
||||
);
|
||||
|
||||
const messages = response.messages || [];
|
||||
|
||||
const filtered = messages.filter((msg: any) =>
|
||||
msg.text?.toLowerCase().includes(keyword.toLowerCase())
|
||||
);
|
||||
|
||||
return filtered;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,110 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { propsValidation } from '@activepieces/pieces-common';
|
||||
import { googleChatApiAuth, googleChatCommon } from '../common';
|
||||
import { allSpacesDropdown, spacesDropdown, peoplesDropdown, threadsDropdown } from '../common/props';
|
||||
import { googleChatAPIService } from '../common/requests';
|
||||
|
||||
export const sendAMessage = createAction({
|
||||
auth: googleChatApiAuth,
|
||||
name: 'sendAMessage',
|
||||
displayName: 'Send a Message',
|
||||
description: 'Send a message to a space or direct conversation.',
|
||||
props: {
|
||||
spaceId: allSpacesDropdown({ refreshers: ['auth'], required: true }),
|
||||
text: Property.LongText({
|
||||
displayName: 'Message',
|
||||
description: 'The message content to send. Supports basic formatting like *bold*, _italic_, and @mentions.',
|
||||
required: true,
|
||||
}),
|
||||
thread: threadsDropdown({ refreshers: ['auth', 'spaceId'], required: false }),
|
||||
messageReplyOption: Property.StaticDropdown({
|
||||
displayName: 'Reply Behavior',
|
||||
description: 'How to handle replies when thread ID is provided.',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{
|
||||
label: 'Reply or start new thread',
|
||||
value: 'REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD',
|
||||
},
|
||||
{
|
||||
label: 'Reply only (fail if thread not found)',
|
||||
value: 'REPLY_MESSAGE_OR_FAIL',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
customMessageId: Property.ShortText({
|
||||
displayName: 'Custom Message ID',
|
||||
description: 'Optional unique ID for this message (auto-generated if empty). Useful for deduplication.',
|
||||
required: false,
|
||||
}),
|
||||
isPrivate: Property.Checkbox({
|
||||
displayName: 'Send as Private Message',
|
||||
description: 'Send this message privately to a specific user. Requires app authentication.',
|
||||
required: false,
|
||||
}),
|
||||
privateMessageViewer: Property.Dropdown({
|
||||
displayName: 'Private Message Recipient',
|
||||
description: 'Select the user who can view this private message.',
|
||||
required: false,
|
||||
refreshers: ['auth'],
|
||||
auth: googleChatApiAuth,
|
||||
async options({ auth }) {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Connect your Google account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const members = await googleChatAPIService.fetchPeople(
|
||||
auth.access_token
|
||||
);
|
||||
|
||||
return {
|
||||
options: members
|
||||
.map((member: any) => {
|
||||
const nameObj =
|
||||
member.names?.find((n: any) => n.metadata.primary) ||
|
||||
member.names?.[0];
|
||||
if (!nameObj) return null;
|
||||
|
||||
return {
|
||||
label: nameObj.displayName,
|
||||
value: member.resourceName,
|
||||
};
|
||||
})
|
||||
.filter(Boolean),
|
||||
};
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch people', e);
|
||||
return {
|
||||
options: [],
|
||||
placeholder: 'Unable to load people',
|
||||
};
|
||||
}
|
||||
},
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
await propsValidation.validateZod(propsValue, googleChatCommon.sendMessageSchema);
|
||||
|
||||
const { spaceId, text, thread, messageReplyOption, customMessageId, isPrivate, privateMessageViewer } = propsValue;
|
||||
|
||||
const response = await googleChatAPIService.sendMessage({
|
||||
accessToken: auth.access_token,
|
||||
spaceId: spaceId as string,
|
||||
text,
|
||||
thread,
|
||||
messageReplyOption,
|
||||
customMessageId,
|
||||
isPrivate,
|
||||
privateMessageViewer,
|
||||
});
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
import { PieceAuth } from "@activepieces/pieces-framework";
|
||||
|
||||
export const googleChatApiAuth = PieceAuth.OAuth2({
|
||||
authUrl: 'https://accounts.google.com/o/oauth2/auth',
|
||||
tokenUrl: 'https://oauth2.googleapis.com/token',
|
||||
required: true,
|
||||
scope: [
|
||||
'https://www.googleapis.com/auth/chat.messages',
|
||||
'https://www.googleapis.com/auth/chat.spaces',
|
||||
'https://www.googleapis.com/auth/chat.memberships',
|
||||
'https://www.googleapis.com/auth/cloud-platform',
|
||||
'https://www.googleapis.com/auth/directory.readonly',
|
||||
],
|
||||
});
|
||||
|
||||
export const GOOGLE_SERVICE_ENTITIES = {
|
||||
chat: 'chat',
|
||||
cloudresourcemanager: 'cloudresourcemanager',
|
||||
pubsub: 'pubsub',
|
||||
workspaceevents: 'workspaceevents',
|
||||
people: 'people',
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
export * from './schemas';
|
||||
export * from './constants';
|
||||
export * from './props';
|
||||
export * from './requests';
|
||||
|
||||
import * as schemas from './schemas';
|
||||
|
||||
export const googleChatCommon = {
|
||||
sendMessageSchema: schemas.sendMessageSchema,
|
||||
getMessageSchema: schemas.getMessageSchema,
|
||||
addSpaceMemberSchema: schemas.addSpaceMemberSchema,
|
||||
findMemberSchema: schemas.findMemberSchema,
|
||||
searchMessagesSchema: schemas.searchMessagesSchema,
|
||||
getDirectMessageDetailsSchema: schemas.getDirectMessageDetailsSchema,
|
||||
newMessageTriggerSchema: schemas.newMessageTriggerSchema,
|
||||
newMentionTriggerSchema: schemas.newMentionTriggerSchema,
|
||||
};
|
||||
@@ -0,0 +1,332 @@
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { googleChatAPIService } from './requests';
|
||||
import { googleChatApiAuth } from './constants';
|
||||
|
||||
export const projectsDropdown = (refreshers: string[]) =>
|
||||
Property.Dropdown({
|
||||
displayName: 'Project',
|
||||
description: 'Select a Google Cloud Project',
|
||||
required: true,
|
||||
refreshers,
|
||||
auth: googleChatApiAuth,
|
||||
async options({ auth }: any) {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Connect your Google account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const projects = await googleChatAPIService.fetchProjects(
|
||||
auth.access_token
|
||||
);
|
||||
|
||||
return {
|
||||
options: projects.map((project: any) => ({
|
||||
label: project.name,
|
||||
value: project.projectId,
|
||||
})),
|
||||
};
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch projects', e);
|
||||
return {
|
||||
options: [],
|
||||
placeholder: 'Unable to load projects',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const spacesDropdown = ({
|
||||
refreshers,
|
||||
required = false,
|
||||
}: {
|
||||
refreshers: string[];
|
||||
required?: boolean;
|
||||
}) =>
|
||||
Property.Dropdown({
|
||||
auth: googleChatApiAuth,
|
||||
displayName: 'Space',
|
||||
description: `Select a Space${
|
||||
required ? '' : ', leave empty for all spaces'
|
||||
}`,
|
||||
required,
|
||||
refreshers,
|
||||
async options({ auth }: any) {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Connect your Google account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const spaces = await googleChatAPIService.fetchSpaces(
|
||||
auth.access_token
|
||||
);
|
||||
|
||||
return {
|
||||
options: spaces.map((space: any) => ({
|
||||
label: space.displayName || space.name,
|
||||
value: space.name,
|
||||
})),
|
||||
};
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch spaces', e);
|
||||
return {
|
||||
options: [],
|
||||
placeholder: 'Unable to load spaces',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const allSpacesDropdown = ({
|
||||
refreshers,
|
||||
required = false,
|
||||
}: {
|
||||
refreshers: string[];
|
||||
required?: boolean;
|
||||
}) =>
|
||||
Property.Dropdown({
|
||||
auth: googleChatApiAuth,
|
||||
displayName: 'Space',
|
||||
description: `Select a Space${
|
||||
required ? '' : ', leave empty for all spaces'
|
||||
}`,
|
||||
required,
|
||||
refreshers,
|
||||
async options({ auth }: any) {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Connect your Google account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const spaces = await googleChatAPIService.fetchAllSpaces(
|
||||
auth.access_token
|
||||
);
|
||||
|
||||
return {
|
||||
options: spaces.map((space: any) => ({
|
||||
label: space.displayName || space.name,
|
||||
value: space.name,
|
||||
})),
|
||||
};
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch spaces', e);
|
||||
return {
|
||||
options: [],
|
||||
placeholder: 'Unable to load spaces',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const directMessagesDropdown = ({
|
||||
refreshers,
|
||||
required = false,
|
||||
}: {
|
||||
refreshers: string[];
|
||||
required?: boolean;
|
||||
}) =>
|
||||
Property.Dropdown({
|
||||
auth: googleChatApiAuth,
|
||||
displayName: 'Direct Message',
|
||||
description: `Select a Direct Message${
|
||||
required ? '' : ', leave empty for all spaces'
|
||||
}`,
|
||||
required,
|
||||
refreshers,
|
||||
async options({ auth }: any) {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Connect your Google account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const spaces = await googleChatAPIService.fetchDirectMessages(
|
||||
auth.access_token
|
||||
);
|
||||
|
||||
return {
|
||||
options: spaces.map((space: any) => ({
|
||||
label: space.displayName || space.name,
|
||||
value: space.name,
|
||||
})),
|
||||
};
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch spaces', e);
|
||||
return {
|
||||
options: [],
|
||||
placeholder: 'Unable to load spaces',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const spacesMembersDropdown = (refreshers: string[]) =>
|
||||
Property.Dropdown({
|
||||
auth: googleChatApiAuth,
|
||||
displayName: 'Space Member',
|
||||
description: 'Select a space member, leave empty for all members',
|
||||
required: false,
|
||||
refreshers,
|
||||
async options({ auth, spaceId }) {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Connect your Google account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
if (!spaceId || typeof spaceId !== 'string') {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please select a space first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const members = await googleChatAPIService.fetchSpaceMembers(
|
||||
auth.access_token,
|
||||
spaceId
|
||||
);
|
||||
|
||||
return {
|
||||
options: members.map((member: any) => ({
|
||||
label: member.member.name,
|
||||
value: member.member.name,
|
||||
})),
|
||||
};
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch space members', e);
|
||||
return {
|
||||
options: [],
|
||||
placeholder: 'Unable to load space members',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const peoplesDropdown = (refreshers: string[]) =>
|
||||
Property.Dropdown({
|
||||
auth: googleChatApiAuth,
|
||||
displayName: 'Select A Person',
|
||||
description: 'Select a person',
|
||||
required: true,
|
||||
refreshers,
|
||||
async options({ auth }) {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Connect your Google account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const members = await googleChatAPIService.fetchPeople(
|
||||
auth.access_token
|
||||
);
|
||||
|
||||
return {
|
||||
options: members
|
||||
.map((member: any) => {
|
||||
const nameObj =
|
||||
member.names?.find((n: any) => n.metadata.primary) ||
|
||||
member.names?.[0];
|
||||
if (!nameObj) return null;
|
||||
|
||||
return {
|
||||
label: nameObj.displayName,
|
||||
value: member.resourceName,
|
||||
};
|
||||
})
|
||||
.filter(Boolean),
|
||||
};
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch people', e);
|
||||
return {
|
||||
options: [],
|
||||
placeholder: 'Unable to load people',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const threadsDropdown = ({
|
||||
refreshers,
|
||||
required = false,
|
||||
}: {
|
||||
refreshers: string[];
|
||||
required?: boolean;
|
||||
}) =>
|
||||
Property.Dropdown({
|
||||
auth: googleChatApiAuth,
|
||||
displayName: 'Thread',
|
||||
description: `Select a thread to reply to${required ? '' : ', leave empty for new thread'}`,
|
||||
required,
|
||||
refreshers,
|
||||
async options({ auth, spaceId }) {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Connect your Google account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
if (!spaceId || typeof spaceId !== 'string') {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please select a space first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
if (!spaceId.startsWith('spaces/')) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Invalid space ID format. Please select a valid space.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const threads = await googleChatAPIService.fetchThreads(
|
||||
auth.access_token,
|
||||
spaceId
|
||||
);
|
||||
|
||||
const options = threads.map((thread: any) => ({
|
||||
label: thread.displayName || thread.name,
|
||||
value: thread.name,
|
||||
}));
|
||||
|
||||
options.unshift({
|
||||
label: 'Start new thread',
|
||||
value: '',
|
||||
});
|
||||
|
||||
return { options };
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch threads', e);
|
||||
return {
|
||||
options: [],
|
||||
placeholder: 'Unable to load threads',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,480 @@
|
||||
import { HttpMethod, httpClient } from '@activepieces/pieces-common';
|
||||
import { GOOGLE_SERVICE_ENTITIES } from './constants';
|
||||
|
||||
async function fireHttpRequest({
|
||||
method,
|
||||
path,
|
||||
entity,
|
||||
body,
|
||||
accessToken,
|
||||
}: {
|
||||
accessToken: string;
|
||||
method: HttpMethod;
|
||||
path: string;
|
||||
entity: keyof typeof GOOGLE_SERVICE_ENTITIES;
|
||||
body?: unknown;
|
||||
}) {
|
||||
const BASE_URL = `https://${GOOGLE_SERVICE_ENTITIES[entity]}.googleapis.com`;
|
||||
|
||||
return await httpClient
|
||||
.sendRequest({
|
||||
method,
|
||||
url: `${BASE_URL}${path}`,
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${accessToken}`,
|
||||
},
|
||||
body,
|
||||
})
|
||||
.then((res) => res.body)
|
||||
.catch((err) => {
|
||||
throw new Error(err);
|
||||
});
|
||||
}
|
||||
|
||||
export const googleChatAPIService = {
|
||||
async fetchProjects(accessToken: string) {
|
||||
const response = await fireHttpRequest({
|
||||
method: HttpMethod.GET,
|
||||
path: '/v1/projects',
|
||||
entity: 'cloudresourcemanager',
|
||||
accessToken,
|
||||
});
|
||||
|
||||
return response.projects;
|
||||
},
|
||||
async sendMessage({
|
||||
accessToken,
|
||||
spaceId,
|
||||
text,
|
||||
thread,
|
||||
messageReplyOption,
|
||||
customMessageId,
|
||||
isPrivate,
|
||||
privateMessageViewer,
|
||||
}: {
|
||||
accessToken: string;
|
||||
spaceId: string;
|
||||
text: string;
|
||||
thread?: string;
|
||||
messageReplyOption?: string;
|
||||
customMessageId?: string;
|
||||
isPrivate?: boolean;
|
||||
privateMessageViewer?: string;
|
||||
}) {
|
||||
const body: any = { text };
|
||||
|
||||
if (thread) {
|
||||
body.thread = { name: thread };
|
||||
}
|
||||
|
||||
if (messageReplyOption) {
|
||||
body.messageReplyOption = messageReplyOption;
|
||||
}
|
||||
|
||||
if (customMessageId) {
|
||||
const cleanId = customMessageId.toLowerCase().replace(/[^a-z0-9-]/g, '');
|
||||
body.messageId = `client-${cleanId}`;
|
||||
}
|
||||
|
||||
if (isPrivate && privateMessageViewer) {
|
||||
body.privateMessageViewer = { name: privateMessageViewer };
|
||||
}
|
||||
|
||||
return await fireHttpRequest({
|
||||
method: HttpMethod.POST,
|
||||
entity: 'chat',
|
||||
accessToken,
|
||||
path: `/v1/${spaceId}/messages`,
|
||||
body,
|
||||
});
|
||||
},
|
||||
async AddASpaceMember({
|
||||
accessToken,
|
||||
spaceId,
|
||||
userId,
|
||||
}: {
|
||||
accessToken: string;
|
||||
spaceId: string;
|
||||
userId: string;
|
||||
}) {
|
||||
return await fireHttpRequest({
|
||||
method: HttpMethod.POST,
|
||||
accessToken: accessToken,
|
||||
entity: 'chat',
|
||||
path: `/v1/${spaceId}/members`,
|
||||
body: {
|
||||
member: {
|
||||
name: userId,
|
||||
type: 'HUMAN',
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
async getMessage(accessToken: string, messageName: string) {
|
||||
return await fireHttpRequest({
|
||||
method: HttpMethod.GET,
|
||||
entity: 'chat',
|
||||
accessToken,
|
||||
path: `/v1/${messageName}`,
|
||||
});
|
||||
},
|
||||
async getSpace({
|
||||
accessToken,
|
||||
spaceId,
|
||||
}: {
|
||||
accessToken: string;
|
||||
spaceId: string;
|
||||
}) {
|
||||
return await fireHttpRequest({
|
||||
method: HttpMethod.GET,
|
||||
entity: 'chat',
|
||||
path: `/v1/${spaceId}`,
|
||||
accessToken,
|
||||
});
|
||||
},
|
||||
async listMessages(
|
||||
accessToken: string,
|
||||
spaceId: string,
|
||||
pageSize = 50
|
||||
) {
|
||||
return await fireHttpRequest({
|
||||
method: HttpMethod.GET,
|
||||
entity: 'chat',
|
||||
accessToken,
|
||||
path: `/v1/${spaceId}/messages?pageSize=${pageSize}`,
|
||||
});
|
||||
},
|
||||
async fetchAllSpaces(accessToken: string) {
|
||||
const response = await fireHttpRequest({
|
||||
method: HttpMethod.GET,
|
||||
path: `/v1/spaces`,
|
||||
entity: 'chat',
|
||||
accessToken,
|
||||
});
|
||||
|
||||
return response.spaces;
|
||||
},
|
||||
async fetchSpaces(accessToken: string) {
|
||||
const filter = encodeURIComponent('spaceType = "SPACE"');
|
||||
const response = await fireHttpRequest({
|
||||
method: HttpMethod.GET,
|
||||
path: `/v1/spaces?filter=${filter}`,
|
||||
entity: 'chat',
|
||||
accessToken,
|
||||
});
|
||||
|
||||
return response.spaces;
|
||||
},
|
||||
async fetchDirectMessages(accessToken: string) {
|
||||
const filter = encodeURIComponent('spaceType = "DIRECT_MESSAGE"');
|
||||
const response = await fireHttpRequest({
|
||||
method: HttpMethod.GET,
|
||||
path: `/v1/spaces?filter=${filter}`,
|
||||
entity: 'chat',
|
||||
accessToken,
|
||||
});
|
||||
|
||||
return response.spaces;
|
||||
},
|
||||
async fetchThreads(accessToken: string, spaceId: string) {
|
||||
const response = await fireHttpRequest({
|
||||
method: HttpMethod.GET,
|
||||
path: `/v1/${spaceId}/messages?pageSize=50`,
|
||||
entity: 'chat',
|
||||
accessToken,
|
||||
});
|
||||
|
||||
const threads = new Map();
|
||||
response.messages?.forEach((message: any) => {
|
||||
if (message.thread && message.thread.name && !message.threadReply) {
|
||||
threads.set(message.thread.name, {
|
||||
name: message.thread.name,
|
||||
displayName: message.text?.substring(0, 50) + (message.text?.length > 50 ? '...' : ''),
|
||||
lastActivity: message.createTime,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return Array.from(threads.values());
|
||||
},
|
||||
async fetchSpaceMembers(accessToken: string, spaceId: string) {
|
||||
const response = await fireHttpRequest({
|
||||
method: HttpMethod.GET,
|
||||
path: `/v1/${spaceId}/members`,
|
||||
entity: 'chat',
|
||||
accessToken,
|
||||
});
|
||||
|
||||
return response.memberships;
|
||||
},
|
||||
async fetchPeople(accessToken: string) {
|
||||
const response = await fireHttpRequest({
|
||||
method: HttpMethod.GET,
|
||||
path: `/v1/people:listDirectoryPeople?sources=DIRECTORY_SOURCE_TYPE_DOMAIN_PROFILE&sources=DIRECTORY_SOURCE_TYPE_DOMAIN_CONTACT&readMask=names,emailAddresses`,
|
||||
entity: 'people',
|
||||
accessToken,
|
||||
});
|
||||
|
||||
return response.people;
|
||||
},
|
||||
async deleteWorkspaceEventsSubscription({
|
||||
accessToken,
|
||||
subscriptionName,
|
||||
}: {
|
||||
accessToken: string;
|
||||
subscriptionName: string;
|
||||
}) {
|
||||
return await fireHttpRequest({
|
||||
method: HttpMethod.DELETE,
|
||||
entity: 'workspaceevents',
|
||||
accessToken,
|
||||
path: `/v1/${subscriptionName}`,
|
||||
});
|
||||
},
|
||||
async grantTopicPermissions({
|
||||
accessToken,
|
||||
projectId,
|
||||
topicName,
|
||||
}: {
|
||||
accessToken: string;
|
||||
projectId: string;
|
||||
topicName: string;
|
||||
}) {
|
||||
const policy = {
|
||||
bindings: [
|
||||
{
|
||||
role: 'roles/pubsub.publisher',
|
||||
members: [`serviceAccount:chat-api-push@system.gserviceaccount.com`],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
return await fireHttpRequest({
|
||||
method: HttpMethod.POST,
|
||||
entity: 'pubsub',
|
||||
accessToken,
|
||||
path: `/v1/projects/${projectId}/topics/${topicName}:setIamPolicy`,
|
||||
body: { policy },
|
||||
});
|
||||
},
|
||||
async createPubSubTopic({
|
||||
accessToken,
|
||||
projectId,
|
||||
topicName,
|
||||
}: {
|
||||
accessToken: string;
|
||||
projectId: string;
|
||||
topicName: string;
|
||||
}) {
|
||||
return await fireHttpRequest({
|
||||
method: HttpMethod.PUT,
|
||||
entity: 'pubsub',
|
||||
accessToken,
|
||||
path: `/v1/projects/${projectId}/topics/${topicName}`,
|
||||
});
|
||||
},
|
||||
async deletePubSubTopic({
|
||||
accessToken,
|
||||
projectId,
|
||||
topicName,
|
||||
}: {
|
||||
accessToken: string;
|
||||
projectId: string;
|
||||
topicName: string;
|
||||
}) {
|
||||
return await fireHttpRequest({
|
||||
method: HttpMethod.DELETE,
|
||||
entity: 'pubsub',
|
||||
accessToken,
|
||||
path: `/v1/projects/${projectId}/topics/${topicName}`,
|
||||
});
|
||||
},
|
||||
async createWorkspaceEventsSubscription({
|
||||
accessToken,
|
||||
projectId,
|
||||
subscriptionName,
|
||||
targetResource,
|
||||
eventTypes,
|
||||
topicName,
|
||||
includeResource = false,
|
||||
}: {
|
||||
accessToken: string;
|
||||
projectId: string;
|
||||
subscriptionName: string;
|
||||
targetResource: string;
|
||||
eventTypes: string[];
|
||||
topicName: string;
|
||||
includeResource?: boolean;
|
||||
}) {
|
||||
const subscription = {
|
||||
targetResource,
|
||||
eventTypes,
|
||||
notificationEndpoint: {
|
||||
pubsubTopic: `projects/${projectId}/topics/${topicName}`,
|
||||
},
|
||||
payloadOptions: {
|
||||
includeResource,
|
||||
},
|
||||
};
|
||||
|
||||
return await fireHttpRequest({
|
||||
method: HttpMethod.POST,
|
||||
entity: 'workspaceevents',
|
||||
accessToken,
|
||||
path: `/v1/subscriptions`,
|
||||
body: subscription,
|
||||
});
|
||||
},
|
||||
async createPubSubSubscription({
|
||||
accessToken,
|
||||
projectId,
|
||||
subscriptionName,
|
||||
topicName,
|
||||
pushEndpoint,
|
||||
}: {
|
||||
accessToken: string;
|
||||
projectId: string;
|
||||
subscriptionName: string;
|
||||
topicName: string;
|
||||
pushEndpoint: string;
|
||||
}) {
|
||||
const subscription = {
|
||||
topic: `projects/${projectId}/topics/${topicName}`,
|
||||
pushConfig: {
|
||||
pushEndpoint,
|
||||
},
|
||||
ackDeadlineSeconds: 600,
|
||||
};
|
||||
|
||||
return await fireHttpRequest({
|
||||
method: HttpMethod.PUT,
|
||||
entity: 'pubsub',
|
||||
accessToken,
|
||||
path: `/v1/projects/${projectId}/subscriptions/${subscriptionName}`,
|
||||
body: subscription,
|
||||
});
|
||||
},
|
||||
async createWebhookSubscription({
|
||||
accessToken,
|
||||
projectId,
|
||||
topic,
|
||||
subscriptionName,
|
||||
webhookUrl,
|
||||
eventTypes,
|
||||
targetResource,
|
||||
}: {
|
||||
accessToken: string;
|
||||
projectId: string;
|
||||
topic: string;
|
||||
webhookUrl: string;
|
||||
subscriptionName: string;
|
||||
eventTypes: string[];
|
||||
targetResource: string;
|
||||
}) {
|
||||
const workspaceSubscription = await this.createWorkspaceEventsSubscription({
|
||||
accessToken,
|
||||
projectId,
|
||||
subscriptionName,
|
||||
targetResource,
|
||||
eventTypes,
|
||||
topicName: topic,
|
||||
includeResource: true,
|
||||
});
|
||||
|
||||
const pubsubSubscription = await this.createPubSubSubscription({
|
||||
accessToken,
|
||||
projectId,
|
||||
subscriptionName,
|
||||
topicName: topic,
|
||||
pushEndpoint: webhookUrl,
|
||||
});
|
||||
|
||||
return {
|
||||
workspaceSubscription,
|
||||
pubsubSubscription,
|
||||
};
|
||||
},
|
||||
async deletePubSubSubscription({
|
||||
accessToken,
|
||||
projectId,
|
||||
subscriptionName,
|
||||
}: {
|
||||
accessToken: string;
|
||||
projectId: string;
|
||||
subscriptionName: string;
|
||||
}) {
|
||||
return await fireHttpRequest({
|
||||
method: HttpMethod.DELETE,
|
||||
entity: 'pubsub',
|
||||
accessToken,
|
||||
path: `/v1/projects/${projectId}/subscriptions/${subscriptionName}`,
|
||||
});
|
||||
},
|
||||
async deleteWebhookSubscription({
|
||||
accessToken,
|
||||
projectId,
|
||||
subscriptionName,
|
||||
topicName,
|
||||
event_type,
|
||||
}: {
|
||||
accessToken: string;
|
||||
projectId: string;
|
||||
subscriptionName: string;
|
||||
topicName: string;
|
||||
event_type: string;
|
||||
}) {
|
||||
return await this.cleanupWebhookResources({
|
||||
accessToken,
|
||||
projectId,
|
||||
event_type,
|
||||
});
|
||||
},
|
||||
async fetchWorkSpaceSubscriptions({
|
||||
accessToken,
|
||||
event_type,
|
||||
}: {
|
||||
accessToken: string;
|
||||
event_type: string;
|
||||
}) {
|
||||
const response = await fireHttpRequest({
|
||||
method: HttpMethod.GET,
|
||||
entity: 'workspaceevents',
|
||||
accessToken,
|
||||
path: `/v1/subscriptions?filter=event_types:"${event_type}"`,
|
||||
});
|
||||
|
||||
return response.subscriptions;
|
||||
},
|
||||
async cleanupWebhookResources({
|
||||
accessToken,
|
||||
projectId,
|
||||
event_type,
|
||||
}: {
|
||||
accessToken: string;
|
||||
projectId: string;
|
||||
event_type: string;
|
||||
}) {
|
||||
try {
|
||||
const workspaceSubscriptions = await this.fetchWorkSpaceSubscriptions({
|
||||
accessToken,
|
||||
event_type,
|
||||
});
|
||||
|
||||
for (const sub of workspaceSubscriptions || []) {
|
||||
try {
|
||||
await this.deleteWorkspaceEventsSubscription({
|
||||
accessToken,
|
||||
subscriptionName: sub.name,
|
||||
});
|
||||
} catch (err: any) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('Error cleaning up workspace subscriptions:', err);
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,147 @@
|
||||
import z from 'zod';
|
||||
|
||||
export const sendMessageSchema = {
|
||||
spaceId: z.string().min(1, 'Space ID is required'),
|
||||
text: z.string().min(1, 'Message text is required'),
|
||||
thread: z.string().optional(),
|
||||
messageReplyOption: z.enum([
|
||||
'REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD',
|
||||
'REPLY_MESSAGE_OR_FAIL'
|
||||
]).optional(),
|
||||
customMessageId: z.string().regex(
|
||||
/^[a-z0-9-]+$/,
|
||||
'Custom message ID must contain only lowercase letters, numbers, and hyphens'
|
||||
).max(63, 'Custom message ID must be 63 characters or less').optional(),
|
||||
isPrivate: z.boolean().optional(),
|
||||
privateMessageViewer: z.string().optional(),
|
||||
};
|
||||
|
||||
export const spaceIdSchema = z.string().regex(
|
||||
/^spaces\/[a-zA-Z0-9_-]+$/,
|
||||
'Space ID must be in format: spaces/{space}'
|
||||
);
|
||||
|
||||
export const threadIdSchema = z.string().regex(
|
||||
/^spaces\/[a-zA-Z0-9_-]+\/threads\/[a-zA-Z0-9_-]+$/,
|
||||
'Thread ID must be in format: spaces/{space}/threads/{thread}'
|
||||
);
|
||||
|
||||
export const userResourceNameSchema = z.string().regex(
|
||||
/^people\/[a-zA-Z0-9_-]+$/,
|
||||
'User resource name must be in format: people/{person}'
|
||||
);
|
||||
|
||||
export const customMessageIdSchema = z.string()
|
||||
.regex(
|
||||
/^client-[a-z0-9-]+$/,
|
||||
'Custom message ID must start with "client-" and contain only lowercase letters, numbers, and hyphens'
|
||||
)
|
||||
.max(63, 'Custom message ID must be 63 characters or less');
|
||||
|
||||
export const messageTextSchema = z.string()
|
||||
.min(1, 'Message text cannot be empty')
|
||||
.max(32000, 'Message text cannot exceed 32,000 characters');
|
||||
|
||||
export const validateSpaceFromDropdown = z.object({
|
||||
value: spaceIdSchema,
|
||||
label: z.string(),
|
||||
});
|
||||
|
||||
export const validateThreadFromDropdown = z.object({
|
||||
value: z.union([z.literal(''), threadIdSchema]),
|
||||
label: z.string(),
|
||||
});
|
||||
|
||||
export const validateUserFromDropdown = z.object({
|
||||
value: userResourceNameSchema,
|
||||
label: z.string(),
|
||||
});
|
||||
|
||||
export const getMessageSchema = {
|
||||
name: z.string()
|
||||
.min(1, 'Message resource name is required')
|
||||
.regex(
|
||||
/^spaces\/[a-zA-Z0-9_-]+\/messages\/[a-zA-Z0-9_-]+$/,
|
||||
'Message resource name must be in format: spaces/{space}/messages/{message}'
|
||||
),
|
||||
};
|
||||
|
||||
export const addSpaceMemberSchema = {
|
||||
spaceId: z.string()
|
||||
.min(1, 'Space ID is required')
|
||||
.regex(
|
||||
/^spaces\/[a-zA-Z0-9_-]+$/,
|
||||
'Space ID must be in format: spaces/{space}'
|
||||
),
|
||||
personId: z.string()
|
||||
.min(1, 'Person ID is required')
|
||||
.regex(
|
||||
/^people\/[a-zA-Z0-9_-]+$/,
|
||||
'Person ID must be in format: people/{person}'
|
||||
),
|
||||
};
|
||||
|
||||
export const findMemberSchema = {
|
||||
spaceId: z.string()
|
||||
.min(1, 'Space ID is required')
|
||||
.regex(
|
||||
/^spaces\/[a-zA-Z0-9_-]+$/,
|
||||
'Space ID must be in format: spaces/{space}'
|
||||
),
|
||||
email: z.string()
|
||||
.min(1, 'Email is required')
|
||||
.email('Please enter a valid email address'),
|
||||
};
|
||||
|
||||
export const searchMessagesSchema = {
|
||||
spaceId: z.string()
|
||||
.min(1, 'Space ID is required')
|
||||
.regex(
|
||||
/^spaces\/[a-zA-Z0-9_-]+$/,
|
||||
'Space ID must be in format: spaces/{space}'
|
||||
),
|
||||
keyword: z.string()
|
||||
.min(1, 'Search keyword is required')
|
||||
.min(2, 'Search keyword must be at least 2 characters long'),
|
||||
limit: z.number()
|
||||
.min(1, 'Limit must be at least 1')
|
||||
.max(1000, 'Limit cannot exceed 1000')
|
||||
.optional(),
|
||||
};
|
||||
|
||||
export const getDirectMessageDetailsSchema = {
|
||||
directMessageId: z.string()
|
||||
.min(1, 'Direct message ID is required')
|
||||
.regex(
|
||||
/^spaces\/[a-zA-Z0-9_-]+$/,
|
||||
'Direct message ID must be in format: spaces/{space}'
|
||||
),
|
||||
};
|
||||
|
||||
export const newMessageTriggerSchema = {
|
||||
projectId: z.string()
|
||||
.min(1, 'Project ID is required'),
|
||||
spaceId: z.string()
|
||||
.regex(
|
||||
/^spaces\/[a-zA-Z0-9_-]+$/,
|
||||
'Space ID must be in format: spaces/{space}'
|
||||
)
|
||||
.optional(),
|
||||
};
|
||||
|
||||
export const newMentionTriggerSchema = {
|
||||
projectId: z.string()
|
||||
.min(1, 'Project ID is required'),
|
||||
spaceId: z.string()
|
||||
.regex(
|
||||
/^spaces\/[a-zA-Z0-9_-]+$/,
|
||||
'Space ID must be in format: spaces/{space}'
|
||||
)
|
||||
.optional(),
|
||||
spaceMemberId: z.string()
|
||||
.regex(
|
||||
/^users\/[a-zA-Z0-9_-]+$/,
|
||||
'Space member ID must be in format: users/{user}'
|
||||
)
|
||||
.optional(),
|
||||
};
|
||||
@@ -0,0 +1,111 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { propsValidation } from '@activepieces/pieces-common';
|
||||
import { googleChatApiAuth, googleChatCommon } from '../common';
|
||||
import { projectsDropdown, spacesDropdown, spacesMembersDropdown } from '../common/props';
|
||||
import { googleChatAPIService } from '../common/requests';
|
||||
|
||||
export const newMention = createTrigger({
|
||||
auth: googleChatApiAuth,
|
||||
name: 'newMention',
|
||||
displayName: 'New Mention',
|
||||
description: 'Triggers when a new mention is received in Google Chat.',
|
||||
props: {
|
||||
projectId: projectsDropdown(['auth']),
|
||||
spaceId: spacesDropdown({refreshers: ['auth']}),
|
||||
spaceMemberId: spacesMembersDropdown(['auth', 'spaceId']),
|
||||
},
|
||||
sampleData: {},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
async onEnable({ auth, propsValue, webhookUrl, store }) {
|
||||
await propsValidation.validateZod(propsValue, googleChatCommon.newMentionTriggerSchema);
|
||||
|
||||
const { projectId, spaceId } = propsValue;
|
||||
const accessToken = auth.access_token;
|
||||
|
||||
const topicName = `acp-topic-${Date.now()}`;
|
||||
const subscriptionName = `acp-sub-${Date.now()}`;
|
||||
|
||||
await googleChatAPIService
|
||||
.cleanupWebhookResources({
|
||||
accessToken,
|
||||
event_type: 'google.workspace.chat.message.v1.created',
|
||||
projectId: projectId as string,
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('Error cleaning up webhook resources', err);
|
||||
});
|
||||
|
||||
await googleChatAPIService.createPubSubTopic({
|
||||
accessToken,
|
||||
projectId: projectId as string,
|
||||
topicName,
|
||||
});
|
||||
|
||||
await googleChatAPIService.grantTopicPermissions({
|
||||
accessToken,
|
||||
projectId: projectId as string,
|
||||
topicName,
|
||||
});
|
||||
|
||||
const targetResource = `//chat.googleapis.com/${
|
||||
spaceId ? spaceId : 'spaces/-'
|
||||
}`;
|
||||
|
||||
await googleChatAPIService.createWebhookSubscription({
|
||||
accessToken,
|
||||
projectId: projectId as string,
|
||||
topic: topicName,
|
||||
subscriptionName,
|
||||
webhookUrl,
|
||||
eventTypes: ['google.workspace.chat.message.v1.created'],
|
||||
targetResource,
|
||||
});
|
||||
},
|
||||
async onDisable({ auth, propsValue: { projectId }, store }) {
|
||||
const accessToken = auth.access_token;
|
||||
|
||||
await googleChatAPIService
|
||||
.cleanupWebhookResources({
|
||||
accessToken,
|
||||
event_type: 'google.workspace.chat.message.v1.created',
|
||||
projectId: projectId as string,
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('Error cleaning up webhook resources during disable', err);
|
||||
});
|
||||
},
|
||||
async run(context) {
|
||||
const messageData = JSON.parse(
|
||||
Buffer.from(
|
||||
(context.payload.body as any).message.data,
|
||||
'base64'
|
||||
).toString('utf-8')
|
||||
);
|
||||
|
||||
const { spaceMemberId } = context.propsValue;
|
||||
|
||||
if (!messageData.message?.annotations) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const mentions = messageData.message.annotations.filter(
|
||||
(a: any) => a.type === 'USER_MENTION'
|
||||
);
|
||||
|
||||
if (mentions.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (spaceMemberId) {
|
||||
const isMatch = mentions.some(
|
||||
(m: any) => m.userMention?.user?.name === spaceMemberId
|
||||
);
|
||||
|
||||
if (!isMatch) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
return [messageData];
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,86 @@
|
||||
import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { propsValidation } from '@activepieces/pieces-common';
|
||||
import { googleChatApiAuth, googleChatCommon } from '../common';
|
||||
import { projectsDropdown, spacesDropdown } from '../common/props';
|
||||
import { googleChatAPIService } from '../common/requests';
|
||||
|
||||
export const newMessage = createTrigger({
|
||||
auth: googleChatApiAuth,
|
||||
name: 'newMessage',
|
||||
displayName: 'New Message',
|
||||
description: 'Triggers when a new message is received in Google Chat.',
|
||||
props: {
|
||||
projectId: projectsDropdown(['auth']),
|
||||
spaceId: spacesDropdown({ refreshers: ['auth'] }),
|
||||
},
|
||||
sampleData: {},
|
||||
type: TriggerStrategy.WEBHOOK,
|
||||
async onEnable({ auth, propsValue, webhookUrl, store }) {
|
||||
await propsValidation.validateZod(propsValue, googleChatCommon.newMessageTriggerSchema);
|
||||
|
||||
const { projectId, spaceId } = propsValue;
|
||||
const accessToken = auth.access_token;
|
||||
|
||||
const topicName = `acp-topic-${Date.now()}`;
|
||||
const subscriptionName = `acp-sub-${Date.now()}`;
|
||||
|
||||
await googleChatAPIService
|
||||
.cleanupWebhookResources({
|
||||
accessToken,
|
||||
event_type: 'google.workspace.chat.message.v1.created',
|
||||
projectId: projectId as string,
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('Error cleaning up webhook resources', err);
|
||||
});
|
||||
|
||||
await googleChatAPIService.createPubSubTopic({
|
||||
accessToken,
|
||||
projectId: projectId as string,
|
||||
topicName,
|
||||
});
|
||||
|
||||
await googleChatAPIService.grantTopicPermissions({
|
||||
accessToken,
|
||||
projectId: projectId as string,
|
||||
topicName,
|
||||
});
|
||||
|
||||
const targetResource = `//chat.googleapis.com/${
|
||||
spaceId ? spaceId : 'spaces/-'
|
||||
}`;
|
||||
|
||||
await googleChatAPIService.createWebhookSubscription({
|
||||
accessToken,
|
||||
projectId: projectId as string,
|
||||
topic: topicName,
|
||||
subscriptionName,
|
||||
webhookUrl,
|
||||
eventTypes: ['google.workspace.chat.message.v1.created'],
|
||||
targetResource,
|
||||
});
|
||||
},
|
||||
async onDisable({ auth, propsValue: { projectId }, store }) {
|
||||
const accessToken = auth.access_token;
|
||||
|
||||
await googleChatAPIService
|
||||
.cleanupWebhookResources({
|
||||
accessToken,
|
||||
event_type: 'google.workspace.chat.message.v1.created',
|
||||
projectId: projectId as string,
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('Error cleaning up webhook resources during disable', err);
|
||||
});
|
||||
},
|
||||
async run(context) {
|
||||
const messageData = JSON.parse(
|
||||
Buffer.from(
|
||||
(context.payload.body as any).message.data,
|
||||
'base64'
|
||||
).toString('utf-8')
|
||||
);
|
||||
|
||||
return [messageData];
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"importHelpers": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noPropertyAccessFromIndexSignature": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user