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.json"
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"!**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx",
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# pieces-microsoft-teams
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build pieces-microsoft-teams` to build the library.
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "@activepieces/piece-microsoft-teams",
|
||||
"version": "0.2.3",
|
||||
"dependencies": {
|
||||
"@microsoft/microsoft-graph-client": "3.0.7",
|
||||
"@microsoft/microsoft-graph-types": "2.40.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"name": "pieces-microsoft-teams",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/microsoft-teams/src",
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/packages/pieces/community/microsoft-teams",
|
||||
"tsConfig": "packages/pieces/community/microsoft-teams/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/microsoft-teams/package.json",
|
||||
"main": "packages/pieces/community/microsoft-teams/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/microsoft-teams/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/microsoft-teams/src/i18n",
|
||||
"output": "./src/i18n",
|
||||
"glob": "**/!(i18n.json)"
|
||||
}
|
||||
],
|
||||
"buildableProjectDepsInPackageJsonType": "dependencies",
|
||||
"updateBuildableProjectDepsInPackageJson": true
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
"prebuild"
|
||||
]
|
||||
},
|
||||
"publish": {
|
||||
"command": "node tools/scripts/publish.mjs pieces-microsoft-teams {args.ver} {args.tag}",
|
||||
"dependsOn": [
|
||||
"build"
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
],
|
||||
"options": {
|
||||
"lintFilePatterns": [
|
||||
"packages/pieces/community/microsoft-teams/**/*.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"prebuild": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"cwd": "packages/pieces/community/microsoft-teams",
|
||||
"command": "bun install --no-save --silent"
|
||||
},
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
]
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"Microsoft Teams": "Microsoft Teams",
|
||||
"Create Channel": "Create Channel",
|
||||
"Send Channel Message": "Send Channel Message",
|
||||
"Send Chat Message": "Send Chat Message",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Create a new channel in Microsoft Teams.": "Create a new channel in Microsoft Teams.",
|
||||
"Sends a message to a teams's channel.": "Sends a message to a teams's channel.",
|
||||
"Sends a message in an existing chat.": "Sends a message in an existing chat.",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Team ID": "Team ID",
|
||||
"Channel Name": "Channel Name",
|
||||
"Channel Description": "Channel Description",
|
||||
"Channel ID": "Channel ID",
|
||||
"Content Type": "Content Type",
|
||||
"Message": "Message",
|
||||
"Chat ID": "Chat ID",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"Text": "Text",
|
||||
"HTML": "HTML",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Channel Message": "New Channel Message",
|
||||
"Triggers when a new message is posted in a channel.": "Triggers when a new message is posted in a channel."
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"\n1. Sign in to [Microsoft Azure Portal](https://portal.azure.com/).\n2. From the left sidebar, go to **Microsoft Enfra ID**.\n3. Under **Manage**, click on **App registrations**.\n4. Click the **New registration** button.\n5. Enter a **Name** for your app.\n6. For **Supported account types**, choose:\n - **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**\n - Or select based on your requirement.\n7. In **Redirect URI**, select **Web** and ad": "\n1. Melden Sie sich bei [Microsoft Azure Portal](https://portal.azure.com/).\n. Von der linken Seitenleiste gehen Sie zu **Microsoft Enfra ID**.\n. Unter **Verwalten** klicken Sie auf **App-Registrierungen**.\n4. Klicken Sie auf die **Neue Registrierung** Schaltfläche.\nGib einen **Name** für deine App ein.\nFür **unterstützte Kontotypen**, auswählen:\n - **Konten in jedem Organisationsverzeichnis (jeder Microsoft-Entra-ID-Mieter - Multitenant) und persönlichen Microsoft-Konten**\n - Oder wählen Sie nach Ihren Anforderungen aus.\n7. In **Umleitungs-URI** wählen Sie **Web** und fügen Sie die angegebene URL hinzu.\n8. Klicken Sie auf **Registrieren**.\n9. Nach der Registrierung werden Sie zur Übersichtsseite der App weitergeleitet. Kopieren Sie die **Application (Client) ID**.\n10. Vom linken Menü gehen Sie zu **Zertifikate & Geheimnisse**.\n - Unter **Kundengeheimnis**, klicke **Neues Kundengeheimnis**.\n - Geben Sie eine Beschreibung an, setzen Sie ein Ablaufdatum und klicken Sie auf **Hinzufügen**.\n - Kopieren Sie den **Wert** des Client-Geheimnisses (dies wird nicht wieder angezeigt).\n11. Gehe zu **API-Berechtigungen** vom linken Menü.\n - Klicke auf **Berechtigung hinzufügen**.\n - Wähle **Microsoft Graph** → **Delegierte Berechtigungen**.\n - Fügen Sie folgende Bereiche hinzu:\n\t - Benutzer. ead\n - Channel.Create \n - Channel.ReadBasic. ll\n\t - ChannelMessage.Senden Sie\n\t - Team.ReadBasic.Alle\n\t - Chat.ReadWrite\n\t - ChannelMessage. ead.All\n\t - User.ReadBasic.All\n\t - Presence.Read.All\n\t - Teammitglied. ead.Alle\n - openid\n - E-Mail\n - Profil \n - offline_access\n - Klicken Sie auf **Berechtigungen hinzufügen**.\n12. Kopieren Sie Ihre **Client-ID** und **Client-Geheimnis**.\n",
|
||||
"Create Channel": "Kanal erstellen",
|
||||
"Send Channel Message": "Kanalnachricht senden",
|
||||
"Send Chat Message": "Chat-Nachricht senden",
|
||||
"Reply to Channel Message": "Auf Kanal-Nachricht antworten",
|
||||
"Create Chat & Send Message": "Chat erstellen & Nachricht senden",
|
||||
"Create Private Channel": "Privaten Kanal erstellen",
|
||||
"Get Chat Message": "Chat-Nachricht erhalten",
|
||||
"Get Channel Message": "Kanalnachricht erhalten",
|
||||
"Find Channel": "Kanal finden",
|
||||
"Find Team Member": "Teammitglied finden",
|
||||
"Custom API Call": "Eigener API-Aufruf",
|
||||
"Create a new channel in Microsoft Teams.": "Erstellen Sie einen neuen Kanal in Microsoft Teams.",
|
||||
"Sends a message to a teams's channel.": "Sendet eine Nachricht an den Kanal eines Teams.",
|
||||
"Sends a message in an existing chat.": "Sendet eine Nachricht in einem bestehenden Chat.",
|
||||
"Post a reply to an existing channel message.": "Sende eine Antwort auf eine vorhandene Kanal-Nachricht.",
|
||||
"Start a new chat and send an initial message.": "Starten Sie einen neuen Chat und senden Sie eine erste Nachricht.",
|
||||
"Create a new private channel in a team.": "Erstelle einen neuen privaten Kanal in einem Team.",
|
||||
"Fetch a specific chat message by chat and message ID.": "Holen Sie eine bestimmte Chat-Nachricht per Chat und Nachrichten-ID.",
|
||||
"Fetch a specific channel message by team, channel, and message ID (optionally a reply).": "Rufe eine bestimmte Kanalnachricht per Team, Kanal und Nachrichten-ID ab (optional eine Antwort).",
|
||||
"Finds channels by name.": "Findet Kanäle nach Namen.",
|
||||
"Finds a team member by email or display name.": "Findet ein Teammitglied per E-Mail oder Anzeigenamen.",
|
||||
"Make a custom API call to a specific endpoint": "Einen benutzerdefinierten API-Aufruf an einen bestimmten Endpunkt machen",
|
||||
"Team ID": "Team-ID",
|
||||
"Channel Name": "Kanalname",
|
||||
"Channel Description": "Kanalbeschreibung",
|
||||
"Channel ID": "Kanal-ID",
|
||||
"Content Type": "Inhaltstyp",
|
||||
"Message": "Nachricht",
|
||||
"Chat ID": "Chat-ID",
|
||||
"Message ID": "Nachrichten-ID",
|
||||
"Member": "Mitglied",
|
||||
"Message Content Type": "Nachrichteninhaltstyp",
|
||||
"Initial Message": "Anfangsnachricht",
|
||||
"Reply ID (optional)": "Antwort-ID (optional)",
|
||||
"Search By": "Suche nach",
|
||||
"searchValue": "suchwert",
|
||||
"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)",
|
||||
"ID of the parent message to reply to.": "ID der zu antwortenden übergeordneten Nachricht.",
|
||||
"The ID of the message to retrieve.": "Die ID der zu holenden Nachricht.",
|
||||
"The ID of the channel message to retrieve.": "Die ID der zu ermittelnden Kanalnachricht.",
|
||||
"Provide to fetch a specific reply under the message.": "Geben Sie an, eine bestimmte Antwort unter der Nachricht abzurufen.",
|
||||
"Email address or name to search for.": "E-Mail-Adresse oder Name, nach dem gesucht werden soll.",
|
||||
"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..",
|
||||
"Text": "Text",
|
||||
"HTML": "HTML",
|
||||
"Email": "E-Mail",
|
||||
"Name": "Name",
|
||||
"GET": "ERHALTEN",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "LÖSCHEN",
|
||||
"HEAD": "HEAD",
|
||||
"New Channel Message": "Neue Kanal-Nachricht",
|
||||
"New Channel": "Neuer Kanal",
|
||||
"New Chat": "Neuer Chat",
|
||||
"New Chat Message": "Neue Chat-Nachricht",
|
||||
"Triggers when a new message is posted in a channel.": "Wird ausgelöst, wenn eine neue Nachricht in einem Kanal veröffentlicht wird.",
|
||||
"Triggers when a new channel is created in a team.": "Wird ausgelöst, wenn ein neuer Kanal in einem Team erstellt wird.",
|
||||
"Triggers when a new chat is created.": "Wird ausgelöst, wenn ein neuer Chat erstellt wird.",
|
||||
"Triggers when a new message is received in a chat.": "Wird ausgelöst, wenn eine neue Nachricht in einem Chat empfangen wird."
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"\n1. Sign in to [Microsoft Azure Portal](https://portal.azure.com/).\n2. From the left sidebar, go to **Microsoft Enfra ID**.\n3. Under **Manage**, click on **App registrations**.\n4. Click the **New registration** button.\n5. Enter a **Name** for your app.\n6. For **Supported account types**, choose:\n - **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**\n - Or select based on your requirement.\n7. In **Redirect URI**, select **Web** and ad": "\n1. Sign in to [Microsoft Azure Portal](https://portal.azure.com/).\n2. From the left sidebar, go to **Microsoft Enfra ID**.\n3. Under **Manage**, click on **App registrations**.\n4. Click the **New registration** button.\n5. Enter a **Name** for your app.\n6. For **Supported account types**, choose:\n - **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**\n - Or select based on your requirement.\n7. In **Redirect URI**, select **Web** and add the given URL.\n8. Click **Register**.\n9. After registration, you’ll be redirected to the app’s overview page. Copy the **Application (client) ID**.\n10. From the left menu, go to **Certificates & secrets**.\n - Under **Client secrets**, click **New client secret**.\n - Provide a description, set an expiry, and click **Add**.\n - Copy the **Value** of the client secret (this will not be shown again).\n11. Go to **API permissions** from the left menu.\n - Click **Add a permission**.\n - Select **Microsoft Graph** → **Delegated permissions**.\n - Add the following scopes:\n\t - User.Read\n - Channel.Create\n\t - Channel.ReadBasic.All\n\t - ChannelMessage.Send\n\t - Team.ReadBasic.All\n\t - Chat.ReadWrite\n\t - ChannelMessage.Read.All\n\t - User.ReadBasic.All\n\t - Presence.Read.All\n\t - TeamMember.Read.All\n - openid\n - email\n - profile\n\t - offline_access\n - Click **Add permissions**.\n12. Copy your **Client ID** and **Client Secret**.\n",
|
||||
"Create Channel": "Crear canal",
|
||||
"Send Channel Message": "Enviar Mensaje del Canal",
|
||||
"Send Chat Message": "Enviar mensaje de chat",
|
||||
"Reply to Channel Message": "Responder al mensaje del canal",
|
||||
"Create Chat & Send Message": "Crear Mensaje de Chat y Enviar",
|
||||
"Create Private Channel": "Crear canal privado",
|
||||
"Get Chat Message": "Obtener Mensaje de Chat",
|
||||
"Get Channel Message": "Obtener mensaje de canal",
|
||||
"Find Channel": "Buscar canal",
|
||||
"Find Team Member": "Buscar miembro del equipo",
|
||||
"Custom API Call": "Llamada API personalizada",
|
||||
"Create a new channel in Microsoft Teams.": "Crear un nuevo canal en equipos de Microsoft.",
|
||||
"Sends a message to a teams's channel.": "Envía un mensaje al canal de un equipo.",
|
||||
"Sends a message in an existing chat.": "Envía un mensaje en un chat existente.",
|
||||
"Post a reply to an existing channel message.": "Publicar una respuesta a un mensaje de canal existente.",
|
||||
"Start a new chat and send an initial message.": "Iniciar un nuevo chat y enviar un mensaje inicial.",
|
||||
"Create a new private channel in a team.": "Crear un nuevo canal privado en un equipo.",
|
||||
"Fetch a specific chat message by chat and message ID.": "Obtener un mensaje de chat específico por el chat y el mensaje ID.",
|
||||
"Fetch a specific channel message by team, channel, and message ID (optionally a reply).": "Obtener un mensaje específico de canal por equipo, canal e ID de mensaje (opcionalmente una respuesta).",
|
||||
"Finds channels by name.": "Encuentra canales por nombre.",
|
||||
"Finds a team member by email or display name.": "Encuentra a un miembro del equipo por correo electrónico o por nombre mostrado.",
|
||||
"Make a custom API call to a specific endpoint": "Hacer una llamada API personalizada a un extremo específico",
|
||||
"Team ID": "ID de equipo",
|
||||
"Channel Name": "Nombre del canal",
|
||||
"Channel Description": "Descripción del canal",
|
||||
"Channel ID": "ID del canal",
|
||||
"Content Type": "Tipo de contenido",
|
||||
"Message": "Mensaje",
|
||||
"Chat ID": "ID de chat",
|
||||
"Message ID": "ID del mensaje",
|
||||
"Member": "Miembro",
|
||||
"Message Content Type": "Tipo de contenido del mensaje",
|
||||
"Initial Message": "Mensaje inicial",
|
||||
"Reply ID (optional)": "Responder ID (opcional)",
|
||||
"Search By": "Buscar por",
|
||||
"searchValue": "busquedaValor",
|
||||
"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)",
|
||||
"ID of the parent message to reply to.": "ID del mensaje padre al que responder.",
|
||||
"The ID of the message to retrieve.": "El ID del mensaje a recuperar.",
|
||||
"The ID of the channel message to retrieve.": "El ID del mensaje del canal a recuperar.",
|
||||
"Provide to fetch a specific reply under the message.": "Proporcione para obtener una respuesta específica bajo el mensaje.",
|
||||
"Email address or name to search for.": "Dirección de correo electrónico o nombre para buscar.",
|
||||
"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.",
|
||||
"Text": "Texto",
|
||||
"HTML": "HTML",
|
||||
"Email": "E-mail",
|
||||
"Name": "Nombre",
|
||||
"GET": "RECOGER",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "BORRAR",
|
||||
"HEAD": "LIMPIO",
|
||||
"New Channel Message": "Nuevo mensaje de canal",
|
||||
"New Channel": "Nuevo canal",
|
||||
"New Chat": "Nuevo chat",
|
||||
"New Chat Message": "Nuevo mensaje de chat",
|
||||
"Triggers when a new message is posted in a channel.": "Dispara cuando un nuevo mensaje es publicado en un canal.",
|
||||
"Triggers when a new channel is created in a team.": "Dispara cuando se crea un nuevo canal en un equipo.",
|
||||
"Triggers when a new chat is created.": "Dispara cuando se crea un nuevo chat.",
|
||||
"Triggers when a new message is received in a chat.": "Dispara cuando se recibe un nuevo mensaje en un chat."
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"\n1. Sign in to [Microsoft Azure Portal](https://portal.azure.com/).\n2. From the left sidebar, go to **Microsoft Enfra ID**.\n3. Under **Manage**, click on **App registrations**.\n4. Click the **New registration** button.\n5. Enter a **Name** for your app.\n6. For **Supported account types**, choose:\n - **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**\n - Or select based on your requirement.\n7. In **Redirect URI**, select **Web** and ad": "\n1. Sign in to [Microsoft Azure Portal](https://portal.azure.com/).\n2. From the left sidebar, go to **Microsoft Enfra ID**.\n3. Under **Manage**, click on **App registrations**.\n4. Click the **New registration** button.\n5. Enter a **Name** for your app.\n6. For **Supported account types**, choose:\n - **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**\n - Or select based on your requirement.\n7. In **Redirect URI**, select **Web** and add the given URL.\n8. Click **Register**.\n9. After registration, you’ll be redirected to the app’s overview page. Copy the **Application (client) ID**.\n10. From the left menu, go to **Certificates & secrets**.\n - Under **Client secrets**, click **New client secret**.\n - Provide a description, set an expiry, and click **Add**.\n - Copy the **Value** of the client secret (this will not be shown again).\n11. Go to **API permissions** from the left menu.\n - Click **Add a permission**.\n - Select **Microsoft Graph** → **Delegated permissions**.\n - Add the following scopes:\n\t - User.Read\n - Channel.Create\n\t - Channel.ReadBasic.All\n\t - ChannelMessage.Send\n\t - Team.ReadBasic.All\n\t - Chat.ReadWrite\n\t - ChannelMessage.Read.All\n\t - User.ReadBasic.All\n\t - Presence.Read.All\n\t - TeamMember.Read.All\n - openid\n - email\n - profile\n\t - offline_access\n - Click **Add permissions**.\n12. Copy your **Client ID** and **Client Secret**.\n",
|
||||
"Create Channel": "Créer un canal",
|
||||
"Send Channel Message": "Envoyer un message dans un channel",
|
||||
"Send Chat Message": "Envoyer un message de chat",
|
||||
"Reply to Channel Message": "Répondre au message du salon",
|
||||
"Create Chat & Send Message": "Créer un chat et envoyer un message",
|
||||
"Create Private Channel": "Créer un canal privé",
|
||||
"Get Chat Message": "Recevoir un message de chat",
|
||||
"Get Channel Message": "Recevoir le message du salon",
|
||||
"Find Channel": "Trouver un canal",
|
||||
"Find Team Member": "Trouver un membre de l'équipe",
|
||||
"Custom API Call": "Appel API personnalisé",
|
||||
"Create a new channel in Microsoft Teams.": "Créer un nouveau canal dans les équipes Microsoft.",
|
||||
"Sends a message to a teams's channel.": "Envoie un message au canal d'une équipe.",
|
||||
"Sends a message in an existing chat.": "Envoie un message dans un chat existant.",
|
||||
"Post a reply to an existing channel message.": "Poster une réponse à un message de canal existant.",
|
||||
"Start a new chat and send an initial message.": "Commencez un nouveau chat et envoyez un message initial.",
|
||||
"Create a new private channel in a team.": "Créer un nouveau canal privé dans une équipe.",
|
||||
"Fetch a specific chat message by chat and message ID.": "Récupère un message de chat spécifique par ID de chat et de message.",
|
||||
"Fetch a specific channel message by team, channel, and message ID (optionally a reply).": "Récupère un message de canal spécifique par équipe, canal et ID de message (éventuellement une réponse).",
|
||||
"Finds channels by name.": "Trouve les salons par nom.",
|
||||
"Finds a team member by email or display name.": "Trouve un membre de l'équipe par email ou par nom d'affichage.",
|
||||
"Make a custom API call to a specific endpoint": "Passez un appel API personnalisé à un point de terminaison spécifique",
|
||||
"Team ID": "ID d'équipe",
|
||||
"Channel Name": "Nom du canal",
|
||||
"Channel Description": "Description du canal",
|
||||
"Channel ID": "ID du canal",
|
||||
"Content Type": "Type de contenu",
|
||||
"Message": "Message",
|
||||
"Chat ID": "ID du chat",
|
||||
"Message ID": "ID du message",
|
||||
"Member": "Membre",
|
||||
"Message Content Type": "Type de contenu du message",
|
||||
"Initial Message": "Message initial",
|
||||
"Reply ID (optional)": "ID de réponse (facultatif)",
|
||||
"Search By": "Rechercher par",
|
||||
"searchValue": "Chercher valeur",
|
||||
"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)",
|
||||
"ID of the parent message to reply to.": "ID du message parent auquel répondre.",
|
||||
"The ID of the message to retrieve.": "L'ID du message à récupérer.",
|
||||
"The ID of the channel message to retrieve.": "L'ID du message du salon à récupérer.",
|
||||
"Provide to fetch a specific reply under the message.": "Fournir pour récupérer une réponse spécifique sous le message.",
|
||||
"Email address or name to search for.": "Adresse e-mail ou nom à rechercher.",
|
||||
"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.",
|
||||
"Text": "Texte du texte",
|
||||
"HTML": "HTML",
|
||||
"Email": "Courriel",
|
||||
"Name": "Nom",
|
||||
"GET": "OBTENIR",
|
||||
"POST": "POSTER",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "SUPPRIMER",
|
||||
"HEAD": "HEAD",
|
||||
"New Channel Message": "Nouveau message dans un channel",
|
||||
"New Channel": "Nouveau canal",
|
||||
"New Chat": "Nouveau chat",
|
||||
"New Chat Message": "Nouveau message de chat",
|
||||
"Triggers when a new message is posted in a channel.": "Déclenche lorsqu'un nouveau message est posté dans un canal.",
|
||||
"Triggers when a new channel is created in a team.": "Déclenche lorsqu'un nouveau canal est créé dans une équipe.",
|
||||
"Triggers when a new chat is created.": "Déclenche quand un nouveau chat est créé.",
|
||||
"Triggers when a new message is received in a chat.": "Déclenche lorsqu'un nouveau message est reçu dans un chat."
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"Microsoft Teams": "Microsoft Teams",
|
||||
"Create Channel": "Create Channel",
|
||||
"Send Channel Message": "Send Channel Message",
|
||||
"Send Chat Message": "Send Chat Message",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Create a new channel in Microsoft Teams.": "Create a new channel in Microsoft Teams.",
|
||||
"Sends a message to a teams's channel.": "Sends a message to a teams's channel.",
|
||||
"Sends a message in an existing chat.": "Sends a message in an existing chat.",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Team ID": "Team ID",
|
||||
"Channel Name": "Channel Name",
|
||||
"Channel Description": "Channel Description",
|
||||
"Channel ID": "Channel ID",
|
||||
"Content Type": "Content Type",
|
||||
"Message": "Message",
|
||||
"Chat ID": "Chat ID",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"Text": "Text",
|
||||
"HTML": "HTML",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Channel Message": "New Channel Message",
|
||||
"Triggers when a new message is posted in a channel.": "Triggers when a new message is posted in a channel."
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"Microsoft Teams": "Microsoft Teams",
|
||||
"Create Channel": "Create Channel",
|
||||
"Send Channel Message": "Send Channel Message",
|
||||
"Send Chat Message": "Send Chat Message",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Create a new channel in Microsoft Teams.": "Create a new channel in Microsoft Teams.",
|
||||
"Sends a message to a teams's channel.": "Sends a message to a teams's channel.",
|
||||
"Sends a message in an existing chat.": "Sends a message in an existing chat.",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Team ID": "Team ID",
|
||||
"Channel Name": "Channel Name",
|
||||
"Channel Description": "Channel Description",
|
||||
"Channel ID": "Channel ID",
|
||||
"Content Type": "Content Type",
|
||||
"Message": "Message",
|
||||
"Chat ID": "Chat ID",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"Text": "Text",
|
||||
"HTML": "HTML",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Channel Message": "New Channel Message",
|
||||
"Triggers when a new message is posted in a channel.": "Triggers when a new message is posted in a channel."
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"\n1. Sign in to [Microsoft Azure Portal](https://portal.azure.com/).\n2. From the left sidebar, go to **Microsoft Enfra ID**.\n3. Under **Manage**, click on **App registrations**.\n4. Click the **New registration** button.\n5. Enter a **Name** for your app.\n6. For **Supported account types**, choose:\n - **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**\n - Or select based on your requirement.\n7. In **Redirect URI**, select **Web** and ad": "\n1. Sign in to [Microsoft Azure Portal](https://portal.azure.com/).\n2. From the left sidebar, go to **Microsoft Enfra ID**.\n3. Under **Manage**, click on **App registrations**.\n4. Click the **New registration** button.\n5. Enter a **Name** for your app.\n6. For **Supported account types**, choose:\n - **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**\n - Or select based on your requirement.\n7. In **Redirect URI**, select **Web** and add the given URL.\n8. Click **Register**.\n9. After registration, you’ll be redirected to the app’s overview page. Copy the **Application (client) ID**.\n10. From the left menu, go to **Certificates & secrets**.\n - Under **Client secrets**, click **New client secret**.\n - Provide a description, set an expiry, and click **Add**.\n - Copy the **Value** of the client secret (this will not be shown again).\n11. Go to **API permissions** from the left menu.\n - Click **Add a permission**.\n - Select **Microsoft Graph** → **Delegated permissions**.\n - Add the following scopes:\n\t - User.Read\n - Channel.Create\n\t - Channel.ReadBasic.All\n\t - ChannelMessage.Send\n\t - Team.ReadBasic.All\n\t - Chat.ReadWrite\n\t - ChannelMessage.Read.All\n\t - User.ReadBasic.All\n\t - Presence.Read.All\n\t - TeamMember.Read.All\n - openid\n - email\n - profile\n\t - offline_access\n - Click **Add permissions**.\n12. Copy your **Client ID** and **Client Secret**.\n",
|
||||
"Create Channel": "チャンネルを作成",
|
||||
"Send Channel Message": "僅用於中文",
|
||||
"Send Chat Message": "僅用於中文",
|
||||
"Reply to Channel Message": "僅用於中文",
|
||||
"Create Chat & Send Message": "チャットを作成してメッセージを送信",
|
||||
"Create Private Channel": "プライベートチャンネルを作成",
|
||||
"Get Chat Message": "チャットメッセージを取得",
|
||||
"Get Channel Message": "チャンネルメッセージを取得",
|
||||
"Find Channel": "チャンネルを検索",
|
||||
"Find Team Member": "チームメンバーを探す",
|
||||
"Custom API Call": "カスタムAPI通話",
|
||||
"Create a new channel in Microsoft Teams.": "Microsoft Teamsに新しいチャンネルを作成します。",
|
||||
"Sends a message to a teams's channel.": "チームのチャンネルにメッセージを送信します。",
|
||||
"Sends a message in an existing chat.": "既存のチャットにメッセージを送信します。",
|
||||
"Post a reply to an existing channel message.": "既存のチャンネルメッセージに返信を投稿します。",
|
||||
"Start a new chat and send an initial message.": "新しいチャットを開始し、最初のメッセージを送信します。",
|
||||
"Create a new private channel in a team.": "チームに新しいプライベートチャンネルを作成します。",
|
||||
"Fetch a specific chat message by chat and message ID.": "チャットIDとメッセージIDで特定のチャットメッセージを取得します。",
|
||||
"Fetch a specific channel message by team, channel, and message ID (optionally a reply).": "チーム、チャネル、およびメッセージ ID (任意の返信) で特定のチャンネルメッセージを取得します。",
|
||||
"Finds channels by name.": "名前でチャンネルを検索します。",
|
||||
"Finds a team member by email or display name.": "メールまたは表示名でチームメンバーを検索します。",
|
||||
"Make a custom API call to a specific endpoint": "特定のエンドポイントへのカスタム API コールを実行します。",
|
||||
"Team ID": "チームID",
|
||||
"Channel Name": "チャンネル名",
|
||||
"Channel Description": "チャンネルの説明",
|
||||
"Channel ID": "チャンネル ID",
|
||||
"Content Type": "コンテンツタイプ",
|
||||
"Message": "メッセージ",
|
||||
"Chat ID": "チャット ID",
|
||||
"Message ID": "メッセージID",
|
||||
"Member": "メンバー",
|
||||
"Message Content Type": "メッセージコンテンツタイプ",
|
||||
"Initial Message": "最初のメッセージ",
|
||||
"Reply ID (optional)": "返信ID (オプション)",
|
||||
"Search By": "検索",
|
||||
"searchValue": "searchValue",
|
||||
"Method": "方法",
|
||||
"Headers": "ヘッダー",
|
||||
"Query Parameters": "クエリパラメータ",
|
||||
"Body": "本文",
|
||||
"Response is Binary ?": "応答はバイナリですか?",
|
||||
"No Error on Failure": "失敗時にエラーはありません",
|
||||
"Timeout (in seconds)": "タイムアウト(秒)",
|
||||
"ID of the parent message to reply to.": "返信する親メッセージのID。",
|
||||
"The ID of the message to retrieve.": "取得するメッセージのID。",
|
||||
"The ID of the channel message to retrieve.": "取得するチャネルメッセージの ID。",
|
||||
"Provide to fetch a specific reply under the message.": "メッセージの下に特定の返信を取得するように指定します。",
|
||||
"Email address or name to search for.": "メールアドレスまたは検索する名前。",
|
||||
"Authorization headers are injected automatically from your connection.": "認証ヘッダは接続から自動的に注入されます。",
|
||||
"Enable for files like PDFs, images, etc..": "PDF、画像などのファイルを有効にします。",
|
||||
"Text": "テキスト",
|
||||
"HTML": "HTML",
|
||||
"Email": "Eメールアドレス",
|
||||
"Name": "Name",
|
||||
"GET": "取得",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "削除",
|
||||
"HEAD": "頭",
|
||||
"New Channel Message": "新しいチャンネルメッセージ",
|
||||
"New Channel": "新しいチャンネル",
|
||||
"New Chat": "新しいチャット",
|
||||
"New Chat Message": "新しいチャットメッセージ",
|
||||
"Triggers when a new message is posted in a channel.": "チャンネルに新しいメッセージが投稿されたときにトリガーします。",
|
||||
"Triggers when a new channel is created in a team.": "チームで新しいチャンネルが作成されたときにトリガーします。",
|
||||
"Triggers when a new chat is created.": "新しいチャットが作成されたときにトリガーします。",
|
||||
"Triggers when a new message is received in a chat.": "チャットで新しいメッセージを受信したときにトリガーします。"
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"\n1. Sign in to [Microsoft Azure Portal](https://portal.azure.com/).\n2. From the left sidebar, go to **Microsoft Enfra ID**.\n3. Under **Manage**, click on **App registrations**.\n4. Click the **New registration** button.\n5. Enter a **Name** for your app.\n6. For **Supported account types**, choose:\n - **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**\n - Or select based on your requirement.\n7. In **Redirect URI**, select **Web** and ad": "\n1. Meld je aan bij [Microsoft Azure Portal](https://portal.azure.com/).\n. Ga naar **Microsoft Enfra ID**.\n. Klik onder **Beheren**, op **App registraties**.\n4. Klik op de **Nieuwe registratie** knop.\n5. Voer een **naam** in voor uw app.\n6. Voor **Ondersteunde accounttypen**, kies keuze:\n - **Accounts in elke map van de organisatie (Any Microsoft Entra ID-tenant - Multitenant) en persoonlijke Microsoft accounts**\n - Of selecteer gebaseerd op uw vereiste.\n7. In **Redirect URI** selecteer **Web** en voeg de opgegeven URL toe.\n8. Klik op **Register**.\n9. Na registratie wordt u doorverwezen naar de overzichtspagina. Kopieer de **Applicatie (client) ID**.\n10. Vanuit het linkermenu ga naar **Certificaten & geheimen**.\n - Klik onder **Client geheimen** op **Nieuwe client geheim**.\n - Geef een beschrijving, verloop, en klik **Toevoegen**.\n - Kopieer de **waarde** van de client secret (dit zal niet meer worden weergegeven).\n11. Ga naar **API permissies** in het linkermenu.\n - Klik **Een machtiging toevoegen**.\n - Selecteer **Microsoft Graph** → **Toegewezen machtigingen**.\n - Voeg de volgende toepassingsgebieden toe:\n\t - gebruiker. ead\n - Kanaal.Create \n - Channel.ReadBasic. tot\n\t - ChannelMessage.Send\n\t - Team.ReadBasic.All\n\t - Chat.ReadWrite\n\t - ChannelMessage. ead.All\n\t - User.ReadBasic.All\n\t - Presence.Read.All\n\t - Teamli. ead.Alle\n - openid\n - e-mail\n - profiel \n - offline_access\n - Klik **Rechten toevoegen**.\n12. Kopieer de **Client ID** en **Client Secret**.\n",
|
||||
"Create Channel": "Kanaal aanmaken",
|
||||
"Send Channel Message": "Zend kanaal bericht",
|
||||
"Send Chat Message": "Verstuur chatbericht",
|
||||
"Reply to Channel Message": "Antwoord op Kanaalbericht",
|
||||
"Create Chat & Send Message": "Chat maken en bericht verzenden",
|
||||
"Create Private Channel": "Privékanaal aanmaken",
|
||||
"Get Chat Message": "Ontvang chatbericht",
|
||||
"Get Channel Message": "Krijg Kanaal Bericht",
|
||||
"Find Channel": "Zoek kanaal",
|
||||
"Find Team Member": "Vind Team Lid",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Create a new channel in Microsoft Teams.": "Maak een nieuw kanaal aan in Microsoft Teams.",
|
||||
"Sends a message to a teams's channel.": "Stuurt een bericht naar het kanaal van een team.",
|
||||
"Sends a message in an existing chat.": "Stuurt een bericht in een bestaande chat.",
|
||||
"Post a reply to an existing channel message.": "Plaats een antwoord op een bestaand zenderbericht.",
|
||||
"Start a new chat and send an initial message.": "Start een nieuwe chat en stuur een eerste bericht.",
|
||||
"Create a new private channel in a team.": "Maak een nieuw privékanaal aan in een team.",
|
||||
"Fetch a specific chat message by chat and message ID.": "Haal een specifiek chatbericht op via chat en bericht-ID.",
|
||||
"Fetch a specific channel message by team, channel, and message ID (optionally a reply).": "Ophalen van een specifiek kanaalbericht door het team, kanaal en bericht-ID (optioneel)",
|
||||
"Finds channels by name.": "Zenders op naam gevonden.",
|
||||
"Finds a team member by email or display name.": "Vindt een teamlid via e-mail of weergavenaam.",
|
||||
"Make a custom API call to a specific endpoint": "Maak een aangepaste API call naar een specifiek eindpunt",
|
||||
"Team ID": "Team ID",
|
||||
"Channel Name": "Kanaal naam",
|
||||
"Channel Description": "Kanaal beschrijving",
|
||||
"Channel ID": "Kanaal ID",
|
||||
"Content Type": "Type inhoud",
|
||||
"Message": "bericht",
|
||||
"Chat ID": "Chat ID",
|
||||
"Message ID": "Bericht ID",
|
||||
"Member": "Lid",
|
||||
"Message Content Type": "Bericht Content Type",
|
||||
"Initial Message": "Eerste bericht",
|
||||
"Reply ID (optional)": "Antwoord ID (optioneel)",
|
||||
"Search By": "Zoeken op",
|
||||
"searchValue": "zoekWaarde",
|
||||
"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)",
|
||||
"ID of the parent message to reply to.": "ID van het bovenliggende bericht waarop u wilt reageren.",
|
||||
"The ID of the message to retrieve.": "Het ID van het op te halen bericht.",
|
||||
"The ID of the channel message to retrieve.": "Het op te halen zender-bericht.",
|
||||
"Provide to fetch a specific reply under the message.": "Geef aan om een specifiek antwoord op te halen onder het bericht.",
|
||||
"Email address or name to search for.": "E-mailadres of naam om naar te zoeken",
|
||||
"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..",
|
||||
"Text": "Tekstveld",
|
||||
"HTML": "HTML",
|
||||
"Email": "E-mail",
|
||||
"Name": "Naam",
|
||||
"GET": "KRIJG",
|
||||
"POST": "POSTE",
|
||||
"PATCH": "BEKIJK",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "VERWIJDEREN",
|
||||
"HEAD": "HOOFD",
|
||||
"New Channel Message": "Nieuw kanaalbericht",
|
||||
"New Channel": "Nieuw kanaal",
|
||||
"New Chat": "Nieuwe chat",
|
||||
"New Chat Message": "Nieuw chatbericht",
|
||||
"Triggers when a new message is posted in a channel.": "Triggert wanneer een nieuw bericht in een kanaal is geplaatst.",
|
||||
"Triggers when a new channel is created in a team.": "Triggert wanneer een nieuw kanaal wordt aangemaakt in een team.",
|
||||
"Triggers when a new chat is created.": "Triggert wanneer een nieuwe chat wordt aangemaakt.",
|
||||
"Triggers when a new message is received in a chat.": "Triggert wanneer een nieuw bericht wordt ontvangen in een chat."
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"\n1. Sign in to [Microsoft Azure Portal](https://portal.azure.com/).\n2. From the left sidebar, go to **Microsoft Enfra ID**.\n3. Under **Manage**, click on **App registrations**.\n4. Click the **New registration** button.\n5. Enter a **Name** for your app.\n6. For **Supported account types**, choose:\n - **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**\n - Or select based on your requirement.\n7. In **Redirect URI**, select **Web** and ad": "\n1. Entre no [Microsoft Azure Portal](https://portal.azure.com/).\n. Na barra lateral esquerda, vá até **Microsoft Enfra ID**.\n. Sob **Gerenciar**, clique em **Aplicativos registrados**.\n4. Clique no botão **Novo registro**.\n5. Digite um **nome** para o seu aplicativo.\n6. Para **Tipos de conta suportados**, escolha:\n - **Contas em qualquer diretório organizacional (qualquer inquilino de ID da Microsoft Entra - Multitenant) e contas pessoais da Microsoft**\n - Ou selecione com base nos seus requisitos.\n7. Em **URI de redirecionamento**, selecione **Web** e adicione a URL fornecida.\n8. Clique em **Registrar**.\n9. Após o registro, você será redirecionado para a página de visão geral do aplicativo. Copie o **aplicativo (cliente) ID**.\n10. Do menu à esquerda, vá para **Certificados e segredos**.\n - Em **Segredos do Cliente**, clique em **Novo segredo do Cliente**.\n - Fornece uma descrição, define um vencimento e clique em **Adicionar**.\n - Copiar o **Valor** do segredo do cliente (isso não será exibido novamente).\n11. Vá para **permissões de API** no menu à esquerda.\n - Clique em **Adicionar uma permissão**.\n - Selecione **Microsoft Graph** → **Delegated permissions**.\n - Adicione os seguintes escopos:\n\t - Usuário. ead\n - Canal.Create \n - Channel.ReadBasic. ll\n\t - ChannelMessage.Send\n\t - Team.ReadBasic.All\n\t - Chat.ReadWrite\n\t - ChannelMessage. ead.All\n\t - User.ReadBasic.All\n\t - Presença.Read.All\n\t - Membro. ead.All\n - openid\n - email\n - perfil \n - offline_access\n - Clique em **Adicionar permissões**.\n12. Copie seu **ID do cliente** e **Segredo do cliente**.\n",
|
||||
"Create Channel": "Criar Canal",
|
||||
"Send Channel Message": "Enviar Mensagem de Canal",
|
||||
"Send Chat Message": "Enviar Mensagem de Chat",
|
||||
"Reply to Channel Message": "Responder Mensagem de Canal",
|
||||
"Create Chat & Send Message": "Criar Chat e Enviar Mensagem",
|
||||
"Create Private Channel": "Criar canal privado",
|
||||
"Get Chat Message": "Obter mensagem de bate-papo",
|
||||
"Get Channel Message": "Obter mensagem do canal",
|
||||
"Find Channel": "Encontrar canal",
|
||||
"Find Team Member": "Localizar membro da equipe",
|
||||
"Custom API Call": "Chamada de API personalizada",
|
||||
"Create a new channel in Microsoft Teams.": "Crie um novo canal em Equipes Microsoft.",
|
||||
"Sends a message to a teams's channel.": "Envia uma mensagem para o canal de uma equipe.",
|
||||
"Sends a message in an existing chat.": "Envia uma mensagem em um chat existente.",
|
||||
"Post a reply to an existing channel message.": "Publicar uma resposta a uma mensagem de canal existente.",
|
||||
"Start a new chat and send an initial message.": "Inicie um novo bate-papo e envie uma mensagem inicial.",
|
||||
"Create a new private channel in a team.": "Crie um novo canal privado na equipe.",
|
||||
"Fetch a specific chat message by chat and message ID.": "Obter uma mensagem de bate-papo específica por ID de bate-papo e mensagem.",
|
||||
"Fetch a specific channel message by team, channel, and message ID (optionally a reply).": "Obter uma mensagem específica do canal por equipe, canal e ID da mensagem (opcionalmente uma resposta).",
|
||||
"Finds channels by name.": "Localiza canais por nome.",
|
||||
"Finds a team member by email or display name.": "Encontra um membro da equipe por e-mail ou nome de exibição.",
|
||||
"Make a custom API call to a specific endpoint": "Faça uma chamada de API personalizada para um ponto de extremidade específico",
|
||||
"Team ID": "ID da Equipe",
|
||||
"Channel Name": "Nome do Canal",
|
||||
"Channel Description": "Descrição do canal",
|
||||
"Channel ID": "ID do canal",
|
||||
"Content Type": "Tipo de Conteúdo",
|
||||
"Message": "mensagem",
|
||||
"Chat ID": "ID do Chat",
|
||||
"Message ID": "ID da mensagem",
|
||||
"Member": "Membro",
|
||||
"Message Content Type": "Tipo de Conteúdo",
|
||||
"Initial Message": "Mensagem inicial",
|
||||
"Reply ID (optional)": "ID da resposta (opcional)",
|
||||
"Search By": "Pesquisar por",
|
||||
"searchValue": "pesquisarValor",
|
||||
"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)",
|
||||
"ID of the parent message to reply to.": "ID da mensagem pai para responder.",
|
||||
"The ID of the message to retrieve.": "O ID da mensagem a recuperar.",
|
||||
"The ID of the channel message to retrieve.": "A ID da mensagem de canal a ser recuperada.",
|
||||
"Provide to fetch a specific reply under the message.": "Enviar para busca de uma resposta específica sob a mensagem.",
|
||||
"Email address or name to search for.": "Endereço de e-mail ou nome para busca.",
|
||||
"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..",
|
||||
"Text": "texto",
|
||||
"HTML": "HTML",
|
||||
"Email": "e-mail",
|
||||
"Name": "Nome",
|
||||
"GET": "OBTER",
|
||||
"POST": "POSTAR",
|
||||
"PATCH": "COMPRAR",
|
||||
"PUT": "COLOCAR",
|
||||
"DELETE": "EXCLUIR",
|
||||
"HEAD": "CABEÇA",
|
||||
"New Channel Message": "Nova mensagem de canal",
|
||||
"New Channel": "Novo Canal",
|
||||
"New Chat": "Novo Bate-Papo",
|
||||
"New Chat Message": "Nova mensagem de bate-papo",
|
||||
"Triggers when a new message is posted in a channel.": "Aciona quando uma nova mensagem é postada em um canal.",
|
||||
"Triggers when a new channel is created in a team.": "Dispara quando um novo canal é criado em equipe.",
|
||||
"Triggers when a new chat is created.": "Dispara quando um novo chat é criado.",
|
||||
"Triggers when a new message is received in a chat.": "Aciona quando uma nova mensagem é recebida em um chat."
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"Microsoft Teams": "Команды Microsoft",
|
||||
"Create Channel": "Создать канал",
|
||||
"Send Channel Message": "Отправить сообщение канала",
|
||||
"Send Chat Message": "Отправить сообщение в чат",
|
||||
"Custom API Call": "Пользовательский вызов API",
|
||||
"Create a new channel in Microsoft Teams.": "Создайте новый канал в командах Microsoft.",
|
||||
"Sends a message to a teams's channel.": "Отправляет сообщение в канал команд.",
|
||||
"Sends a message in an existing chat.": "Отправляет сообщение в существующий чат.",
|
||||
"Make a custom API call to a specific endpoint": "Сделать пользовательский API вызов к определенной конечной точке",
|
||||
"Team ID": "ID команды",
|
||||
"Channel Name": "Название канала",
|
||||
"Channel Description": "Описание канала",
|
||||
"Channel ID": "ID канала",
|
||||
"Content Type": "Тип контента",
|
||||
"Message": "Сообщение",
|
||||
"Chat ID": "Чат ID",
|
||||
"Method": "Метод",
|
||||
"Headers": "Заголовки",
|
||||
"Query Parameters": "Параметры запроса",
|
||||
"Body": "Тело",
|
||||
"No Error on Failure": "Нет ошибок при ошибке",
|
||||
"Timeout (in seconds)": "Таймаут (в секундах)",
|
||||
"Authorization headers are injected automatically from your connection.": "Заголовки авторизации включаются автоматически из вашего соединения.",
|
||||
"Text": "Текст",
|
||||
"HTML": "HTML",
|
||||
"GET": "ПОЛУЧИТЬ",
|
||||
"POST": "ПОСТ",
|
||||
"PATCH": "ПАТЧ",
|
||||
"PUT": "ПОКУПИТЬ",
|
||||
"DELETE": "УДАЛИТЬ",
|
||||
"HEAD": "HEAD",
|
||||
"New Channel Message": "Новое сообщение канала",
|
||||
"Triggers when a new message is posted in a channel.": "Включает при отправке нового сообщения в канал."
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"\n1. Sign in to [Microsoft Azure Portal](https://portal.azure.com/).\n2. From the left sidebar, go to **Microsoft Enfra ID**.\n3. Under **Manage**, click on **App registrations**.\n4. Click the **New registration** button.\n5. Enter a **Name** for your app.\n6. For **Supported account types**, choose:\n - **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**\n - Or select based on your requirement.\n7. In **Redirect URI**, select **Web** and ad": "\n1. Sign in to [Microsoft Azure Portal](https://portal.azure.com/).\n2. From the left sidebar, go to **Microsoft Enfra ID**.\n3. Under **Manage**, click on **App registrations**.\n4. Click the **New registration** button.\n5. Enter a **Name** for your app.\n6. For **Supported account types**, choose:\n - **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**\n - Or select based on your requirement.\n7. In **Redirect URI**, select **Web** and add the given URL.\n8. Click **Register**.\n9. After registration, you’ll be redirected to the app’s overview page. Copy the **Application (client) ID**.\n10. From the left menu, go to **Certificates & secrets**.\n - Under **Client secrets**, click **New client secret**.\n - Provide a description, set an expiry, and click **Add**.\n - Copy the **Value** of the client secret (this will not be shown again).\n11. Go to **API permissions** from the left menu.\n - Click **Add a permission**.\n - Select **Microsoft Graph** → **Delegated permissions**.\n - Add the following scopes:\n\t - User.Read\n - Channel.Create\n\t - Channel.ReadBasic.All\n\t - ChannelMessage.Send\n\t - Team.ReadBasic.All\n\t - Chat.ReadWrite\n\t - ChannelMessage.Read.All\n\t - User.ReadBasic.All\n\t - Presence.Read.All\n\t - TeamMember.Read.All\n - openid\n - email\n - profile\n\t - offline_access\n - Click **Add permissions**.\n12. Copy your **Client ID** and **Client Secret**.\n",
|
||||
"Create Channel": "Create Channel",
|
||||
"Send Channel Message": "Send Channel Message",
|
||||
"Send Chat Message": "Send Chat Message",
|
||||
"Reply to Channel Message": "Reply to Channel Message",
|
||||
"Create Chat & Send Message": "Create Chat & Send Message",
|
||||
"Create Private Channel": "Create Private Channel",
|
||||
"Get Chat Message": "Get Chat Message",
|
||||
"Get Channel Message": "Get Channel Message",
|
||||
"Find Channel": "Find Channel",
|
||||
"Find Team Member": "Find Team Member",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Create a new channel in Microsoft Teams.": "Create a new channel in Microsoft Teams.",
|
||||
"Sends a message to a teams's channel.": "Sends a message to a teams's channel.",
|
||||
"Sends a message in an existing chat.": "Sends a message in an existing chat.",
|
||||
"Post a reply to an existing channel message.": "Post a reply to an existing channel message.",
|
||||
"Start a new chat and send an initial message.": "Start a new chat and send an initial message.",
|
||||
"Create a new private channel in a team.": "Create a new private channel in a team.",
|
||||
"Fetch a specific chat message by chat and message ID.": "Fetch a specific chat message by chat and message ID.",
|
||||
"Fetch a specific channel message by team, channel, and message ID (optionally a reply).": "Fetch a specific channel message by team, channel, and message ID (optionally a reply).",
|
||||
"Finds channels by name.": "Finds channels by name.",
|
||||
"Finds a team member by email or display name.": "Finds a team member by email or display name.",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Team ID": "Team ID",
|
||||
"Channel Name": "Channel Name",
|
||||
"Channel Description": "Channel Description",
|
||||
"Channel ID": "Channel ID",
|
||||
"Content Type": "Content Type",
|
||||
"Message": "Message",
|
||||
"Chat ID": "Chat ID",
|
||||
"Message ID": "Message ID",
|
||||
"Member": "Member",
|
||||
"Message Content Type": "Message Content Type",
|
||||
"Initial Message": "Initial Message",
|
||||
"Reply ID (optional)": "Reply ID (optional)",
|
||||
"Search By": "Search By",
|
||||
"searchValue": "searchValue",
|
||||
"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)",
|
||||
"ID of the parent message to reply to.": "ID of the parent message to reply to.",
|
||||
"The ID of the message to retrieve.": "The ID of the message to retrieve.",
|
||||
"The ID of the channel message to retrieve.": "The ID of the channel message to retrieve.",
|
||||
"Provide to fetch a specific reply under the message.": "Provide to fetch a specific reply under the message.",
|
||||
"Email address or name to search for.": "Email address or name to search for.",
|
||||
"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..",
|
||||
"Text": "Text",
|
||||
"HTML": "HTML",
|
||||
"Email": "Email",
|
||||
"Name": "Name",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Channel Message": "New Channel Message",
|
||||
"New Channel": "New Channel",
|
||||
"New Chat": "New Chat",
|
||||
"New Chat Message": "New Chat Message",
|
||||
"Triggers when a new message is posted in a channel.": "Triggers when a new message is posted in a channel.",
|
||||
"Triggers when a new channel is created in a team.": "Triggers when a new channel is created in a team.",
|
||||
"Triggers when a new chat is created.": "Triggers when a new chat is created.",
|
||||
"Triggers when a new message is received in a chat.": "Triggers when a new message is received in a chat."
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"Microsoft Teams": "Microsoft Teams",
|
||||
"Create Channel": "Create Channel",
|
||||
"Send Channel Message": "Send Channel Message",
|
||||
"Send Chat Message": "Send Chat Message",
|
||||
"Custom API Call": "Custom API Call",
|
||||
"Create a new channel in Microsoft Teams.": "Create a new channel in Microsoft Teams.",
|
||||
"Sends a message to a teams's channel.": "Sends a message to a teams's channel.",
|
||||
"Sends a message in an existing chat.": "Sends a message in an existing chat.",
|
||||
"Make a custom API call to a specific endpoint": "Make a custom API call to a specific endpoint",
|
||||
"Team ID": "Team ID",
|
||||
"Channel Name": "Channel Name",
|
||||
"Channel Description": "Channel Description",
|
||||
"Channel ID": "Channel ID",
|
||||
"Content Type": "Content Type",
|
||||
"Message": "Message",
|
||||
"Chat ID": "Chat ID",
|
||||
"Method": "Method",
|
||||
"Headers": "Headers",
|
||||
"Query Parameters": "Query Parameters",
|
||||
"Body": "Body",
|
||||
"No Error on Failure": "No Error on Failure",
|
||||
"Timeout (in seconds)": "Timeout (in seconds)",
|
||||
"Authorization headers are injected automatically from your connection.": "Authorization headers are injected automatically from your connection.",
|
||||
"Text": "Text",
|
||||
"HTML": "HTML",
|
||||
"GET": "GET",
|
||||
"POST": "POST",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "PUT",
|
||||
"DELETE": "DELETE",
|
||||
"HEAD": "HEAD",
|
||||
"New Channel Message": "New Channel Message",
|
||||
"Triggers when a new message is posted in a channel.": "Triggers when a new message is posted in a channel."
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"\n1. Sign in to [Microsoft Azure Portal](https://portal.azure.com/).\n2. From the left sidebar, go to **Microsoft Enfra ID**.\n3. Under **Manage**, click on **App registrations**.\n4. Click the **New registration** button.\n5. Enter a **Name** for your app.\n6. For **Supported account types**, choose:\n - **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**\n - Or select based on your requirement.\n7. In **Redirect URI**, select **Web** and ad": "\n1. Sign in to [Microsoft Azure Portal](https://portal.azure.com/).\n2. From the left sidebar, go to **Microsoft Enfra ID**.\n3. Under **Manage**, click on **App registrations**.\n4. Click the **New registration** button.\n5. Enter a **Name** for your app.\n6. For **Supported account types**, choose:\n - **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**\n - Or select based on your requirement.\n7. In **Redirect URI**, select **Web** and add the given URL.\n8. Click **Register**.\n9. After registration, you’ll be redirected to the app’s overview page. Copy the **Application (client) ID**.\n10. From the left menu, go to **Certificates & secrets**.\n - Under **Client secrets**, click **New client secret**.\n - Provide a description, set an expiry, and click **Add**.\n - Copy the **Value** of the client secret (this will not be shown again).\n11. Go to **API permissions** from the left menu.\n - Click **Add a permission**.\n - Select **Microsoft Graph** → **Delegated permissions**.\n - Add the following scopes:\n\t - User.Read\n - Channel.Create\n\t - Channel.ReadBasic.All\n\t - ChannelMessage.Send\n\t - Team.ReadBasic.All\n\t - Chat.ReadWrite\n\t - ChannelMessage.Read.All\n\t - User.ReadBasic.All\n\t - Presence.Read.All\n\t - TeamMember.Read.All\n - openid\n - email\n - profile\n\t - offline_access\n - Click **Add permissions**.\n12. Copy your **Client ID** and **Client Secret**.\n",
|
||||
"Create Channel": "Create Channel",
|
||||
"Send Channel Message": "Send Channel Message",
|
||||
"Send Chat Message": "Send Chat Message",
|
||||
"Reply to Channel Message": "Reply to Channel Message",
|
||||
"Create Chat & Send Message": "Create Chat & Send Message",
|
||||
"Create Private Channel": "Create Private Channel",
|
||||
"Get Chat Message": "Get Chat Message",
|
||||
"Get Channel Message": "Get Channel Message",
|
||||
"Find Channel": "Find Channel",
|
||||
"Find Team Member": "Find Team Member",
|
||||
"Custom API Call": "自定义 API 呼叫",
|
||||
"Create a new channel in Microsoft Teams.": "Create a new channel in Microsoft Teams.",
|
||||
"Sends a message to a teams's channel.": "Sends a message to a teams's channel.",
|
||||
"Sends a message in an existing chat.": "Sends a message in an existing chat.",
|
||||
"Post a reply to an existing channel message.": "Post a reply to an existing channel message.",
|
||||
"Start a new chat and send an initial message.": "Start a new chat and send an initial message.",
|
||||
"Create a new private channel in a team.": "Create a new private channel in a team.",
|
||||
"Fetch a specific chat message by chat and message ID.": "Fetch a specific chat message by chat and message ID.",
|
||||
"Fetch a specific channel message by team, channel, and message ID (optionally a reply).": "Fetch a specific channel message by team, channel, and message ID (optionally a reply).",
|
||||
"Finds channels by name.": "Finds channels by name.",
|
||||
"Finds a team member by email or display name.": "Finds a team member by email or display name.",
|
||||
"Make a custom API call to a specific endpoint": "将一个自定义 API 调用到一个特定的终点",
|
||||
"Team ID": "Team ID",
|
||||
"Channel Name": "Channel Name",
|
||||
"Channel Description": "Channel Description",
|
||||
"Channel ID": "Channel ID",
|
||||
"Content Type": "Content Type",
|
||||
"Message": "Message",
|
||||
"Chat ID": "Chat ID",
|
||||
"Message ID": "Message ID",
|
||||
"Member": "成员",
|
||||
"Message Content Type": "Message Content Type",
|
||||
"Initial Message": "Initial Message",
|
||||
"Reply ID (optional)": "Reply ID (optional)",
|
||||
"Search By": "Search By",
|
||||
"searchValue": "searchValue",
|
||||
"Method": "方法",
|
||||
"Headers": "信头",
|
||||
"Query Parameters": "查询参数",
|
||||
"Body": "正文内容",
|
||||
"Response is Binary ?": "Response is Binary ?",
|
||||
"No Error on Failure": "失败时没有错误",
|
||||
"Timeout (in seconds)": "超时(秒)",
|
||||
"ID of the parent message to reply to.": "ID of the parent message to reply to.",
|
||||
"The ID of the message to retrieve.": "The ID of the message to retrieve.",
|
||||
"The ID of the channel message to retrieve.": "The ID of the channel message to retrieve.",
|
||||
"Provide to fetch a specific reply under the message.": "Provide to fetch a specific reply under the message.",
|
||||
"Email address or name to search for.": "Email address or name to search for.",
|
||||
"Authorization headers are injected automatically from your connection.": "授权头自动从您的连接中注入。",
|
||||
"Enable for files like PDFs, images, etc..": "Enable for files like PDFs, images, etc..",
|
||||
"Text": "文本",
|
||||
"HTML": "HTML",
|
||||
"Email": "电子邮件地址",
|
||||
"Name": "名称",
|
||||
"GET": "获取",
|
||||
"POST": "帖子",
|
||||
"PATCH": "PATCH",
|
||||
"PUT": "弹出",
|
||||
"DELETE": "删除",
|
||||
"HEAD": "黑色",
|
||||
"New Channel Message": "New Channel Message",
|
||||
"New Channel": "New Channel",
|
||||
"New Chat": "New Chat",
|
||||
"New Chat Message": "New Chat Message",
|
||||
"Triggers when a new message is posted in a channel.": "Triggers when a new message is posted in a channel.",
|
||||
"Triggers when a new channel is created in a team.": "Triggers when a new channel is created in a team.",
|
||||
"Triggers when a new chat is created.": "Triggers when a new chat is created.",
|
||||
"Triggers when a new message is received in a chat.": "Triggers when a new message is received in a chat."
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
import {
|
||||
createPiece,
|
||||
PieceAuth,
|
||||
PiecePropValueSchema,
|
||||
OAuth2PropertyValue,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { PieceCategory } from '@activepieces/shared';
|
||||
import { createChannelAction } from './lib/actions/create-channel';
|
||||
import { sendChannelMessageAction } from './lib/actions/send-channel-message';
|
||||
import { sendChatMessageAction } from './lib/actions/send-chat-message';
|
||||
import { replyToChannelMessageAction } from './lib/actions/reply-to-channel-message';
|
||||
import { createCustomApiCallAction } from '@activepieces/pieces-common';
|
||||
import { newChannelMessageTrigger } from './lib/triggers/new-channel-message';
|
||||
import { newChannelTrigger } from './lib/triggers/new-channel';
|
||||
import { newChatTrigger } from './lib/triggers/new-chat';
|
||||
import { newChatMessageTrigger } from './lib/triggers/new-chat-message';
|
||||
import { createChatAndSendMessageAction } from './lib/actions/create-chat-and-send-message';
|
||||
import { createPrivateChannelAction } from './lib/actions/create-private-channel';
|
||||
import { getChatMessageAction } from './lib/actions/get-chat-message';
|
||||
import { getChannelMessageAction } from './lib/actions/get-channel-message';
|
||||
import { findChannelAction } from './lib/actions/find-channel';
|
||||
import { findTeamMemberAction } from './lib/actions/find-team-member';
|
||||
import { createGraphClient, withGraphRetry } from './lib/common/graph';
|
||||
|
||||
const authDesc = `
|
||||
1. Sign in to [Microsoft Azure Portal](https://portal.azure.com/).
|
||||
2. From the left sidebar, go to **Microsoft Enfra ID**.
|
||||
3. Under **Manage**, click on **App registrations**.
|
||||
4. Click the **New registration** button.
|
||||
5. Enter a **Name** for your app.
|
||||
6. For **Supported account types**, choose:
|
||||
- **Accounts in any organizational directory (Any Microsoft Entra ID tenant - Multitenant) and personal Microsoft accounts**
|
||||
- Or select based on your requirement.
|
||||
7. In **Redirect URI**, select **Web** and add the given URL.
|
||||
8. Click **Register**.
|
||||
9. After registration, you’ll be redirected to the app’s overview page. Copy the **Application (client) ID**.
|
||||
10. From the left menu, go to **Certificates & secrets**.
|
||||
- Under **Client secrets**, click **New client secret**.
|
||||
- Provide a description, set an expiry, and click **Add**.
|
||||
- Copy the **Value** of the client secret (this will not be shown again).
|
||||
11. Go to **API permissions** from the left menu.
|
||||
- Click **Add a permission**.
|
||||
- Select **Microsoft Graph** → **Delegated permissions**.
|
||||
- Add the following scopes:
|
||||
- User.Read
|
||||
- Channel.Create
|
||||
- Channel.ReadBasic.All
|
||||
- ChannelMessage.Send
|
||||
- Team.ReadBasic.All
|
||||
- Chat.ReadWrite
|
||||
- ChannelMessage.Read.All
|
||||
- User.ReadBasic.All
|
||||
- Presence.Read.All
|
||||
- TeamMember.Read.All
|
||||
- openid
|
||||
- email
|
||||
- profile
|
||||
- offline_access
|
||||
- Click **Add permissions**.
|
||||
12. Copy your **Client ID** and **Client Secret**.
|
||||
`
|
||||
|
||||
export const microsoftTeamsAuth = PieceAuth.OAuth2({
|
||||
description:authDesc,
|
||||
required: true,
|
||||
scope: [
|
||||
'openid',
|
||||
'email',
|
||||
'profile',
|
||||
'offline_access',
|
||||
'User.Read',
|
||||
'Channel.Create',
|
||||
'Channel.ReadBasic.All',
|
||||
'ChannelMessage.Send',
|
||||
'Team.ReadBasic.All',
|
||||
'Chat.ReadWrite',
|
||||
'ChannelMessage.Read.All',
|
||||
'TeamMember.Read.All',
|
||||
'User.ReadBasic.All',
|
||||
'Presence.Read.All',
|
||||
],
|
||||
prompt: 'omit',
|
||||
authUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
|
||||
tokenUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
|
||||
validate: async ({ auth }) => {
|
||||
try {
|
||||
const authValue = auth as PiecePropValueSchema<typeof microsoftTeamsAuth>;
|
||||
const client = createGraphClient(authValue.access_token);
|
||||
await withGraphRetry(() => client.api('/me').get());
|
||||
return { valid: true };
|
||||
} catch (error) {
|
||||
return { valid: false, error: 'Invalid Credentials.' };
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
export const microsoftTeams = createPiece({
|
||||
displayName: 'Microsoft Teams',
|
||||
auth: microsoftTeamsAuth,
|
||||
minimumSupportedRelease: '0.30.0',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/microsoft-teams.png',
|
||||
categories: [PieceCategory.BUSINESS_INTELLIGENCE, PieceCategory.COMMUNICATION],
|
||||
authors: ['kishanprmr'],
|
||||
actions: [
|
||||
createChannelAction,
|
||||
sendChannelMessageAction,
|
||||
sendChatMessageAction,
|
||||
replyToChannelMessageAction,
|
||||
createChatAndSendMessageAction,
|
||||
createPrivateChannelAction,
|
||||
getChatMessageAction,
|
||||
getChannelMessageAction,
|
||||
findChannelAction,
|
||||
findTeamMemberAction,
|
||||
createCustomApiCallAction({
|
||||
auth: microsoftTeamsAuth,
|
||||
baseUrl: () => 'https://graph.microsoft.com/v1.0/teams',
|
||||
authMapping: async (auth) => ({
|
||||
Authorization: `Bearer ${(auth as OAuth2PropertyValue).access_token}`,
|
||||
}),
|
||||
}),
|
||||
],
|
||||
triggers: [newChannelMessageTrigger, newChannelTrigger, newChatTrigger, newChatMessageTrigger],
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import { microsoftTeamsAuth } from '../../';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { Client } from '@microsoft/microsoft-graph-client';
|
||||
import { microsoftTeamsCommon } from '../common';
|
||||
|
||||
export const createChannelAction = createAction({
|
||||
auth: microsoftTeamsAuth,
|
||||
name: 'microsoft_teams_create_channel',
|
||||
displayName: 'Create Channel',
|
||||
description: 'Create a new channel in Microsoft Teams.',
|
||||
props: {
|
||||
teamId: microsoftTeamsCommon.teamId,
|
||||
channelDisplayName: Property.ShortText({
|
||||
displayName: 'Channel Name',
|
||||
required: true,
|
||||
}),
|
||||
channelDescription: Property.LongText({
|
||||
displayName: 'Channel Description',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { teamId, channelDescription, channelDisplayName } = context.propsValue;
|
||||
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(context.auth.access_token),
|
||||
},
|
||||
});
|
||||
|
||||
const channel = {
|
||||
displayName: channelDisplayName,
|
||||
description: channelDescription,
|
||||
};
|
||||
|
||||
return await client.api(`/teams/${teamId}/channels`).post(channel);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,92 @@
|
||||
import { microsoftTeamsAuth } from '../../';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { Client } from '@microsoft/microsoft-graph-client';
|
||||
import { microsoftTeamsCommon } from '../common';
|
||||
import { isNil } from '@activepieces/shared';
|
||||
import { Chat } from '@microsoft/microsoft-graph-types';
|
||||
|
||||
export const createChatAndSendMessageAction = createAction({
|
||||
auth: microsoftTeamsAuth,
|
||||
name: 'microsoft_teams_create_chat_and_send_message',
|
||||
displayName: 'Create Chat & Send Message',
|
||||
description: 'Start a new chat and send an initial message.',
|
||||
props: {
|
||||
teamId: microsoftTeamsCommon.teamId,
|
||||
members:microsoftTeamsCommon.memberIds(true),
|
||||
contentType: Property.StaticDropdown({
|
||||
displayName: 'Message Content Type',
|
||||
required: true,
|
||||
defaultValue: 'text',
|
||||
options: {
|
||||
disabled: false,
|
||||
options: [
|
||||
{ label: 'Text', value: 'text' },
|
||||
{ label: 'HTML', value: 'html' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
content: Property.LongText({
|
||||
displayName: 'Initial Message',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { members, contentType, content } = context.propsValue;
|
||||
|
||||
|
||||
if (isNil(members)) {
|
||||
throw new Error('For one-on-one chats, provide exactly one other member.');
|
||||
}
|
||||
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(context.auth.access_token),
|
||||
},
|
||||
});
|
||||
|
||||
// Resolve current user to include as a member
|
||||
const me = await client.api('/me').select('id,userPrincipalName').get();
|
||||
const currentUserBind = `https://graph.microsoft.com/v1.0/users('${me.id}')`;
|
||||
|
||||
// Parse provided members
|
||||
const otherMembersRaw: string[] = members.map((member)=>`https://graph.microsoft.com/v1.0/users('${member}')`)
|
||||
|
||||
|
||||
const membersPayload = [
|
||||
{
|
||||
'@odata.type': '#microsoft.graph.aadUserConversationMember',
|
||||
roles: ['owner'],
|
||||
'user@odata.bind': currentUserBind,
|
||||
},
|
||||
...otherMembersRaw.map((m) => ({
|
||||
'@odata.type': '#microsoft.graph.aadUserConversationMember',
|
||||
roles: ['owner'],
|
||||
'user@odata.bind': m,
|
||||
})),
|
||||
];
|
||||
|
||||
const chatBody: Chat = {
|
||||
chatType: otherMembersRaw.length ===1 ? 'oneOnOne':'group',
|
||||
members: membersPayload,
|
||||
};
|
||||
|
||||
// Create or get existing chat
|
||||
const chat = await client.api('/chats').post(chatBody);
|
||||
|
||||
// Send initial message
|
||||
const chatMessage = {
|
||||
body: {
|
||||
content: content,
|
||||
contentType: contentType,
|
||||
},
|
||||
};
|
||||
const messageResponse = await client.api(`/chats/${chat.id}/messages`).post(chatMessage);
|
||||
|
||||
return {
|
||||
chat,
|
||||
message: messageResponse,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { microsoftTeamsAuth } from '../../';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { Client } from '@microsoft/microsoft-graph-client';
|
||||
import { microsoftTeamsCommon } from '../common';
|
||||
import { createGraphClient, withGraphRetry } from '../common/graph';
|
||||
|
||||
export const createPrivateChannelAction = createAction({
|
||||
auth: microsoftTeamsAuth,
|
||||
name: 'microsoft_teams_create_private_channel',
|
||||
displayName: 'Create Private Channel',
|
||||
description: 'Create a new private channel in a team.',
|
||||
props: {
|
||||
teamId: microsoftTeamsCommon.teamId,
|
||||
channelDisplayName: Property.ShortText({
|
||||
displayName: 'Channel Name',
|
||||
required: true,
|
||||
}),
|
||||
channelDescription: Property.LongText({
|
||||
displayName: 'Channel Description',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { teamId, channelDescription, channelDisplayName } = context.propsValue;
|
||||
|
||||
const client = createGraphClient(context.auth.access_token);
|
||||
|
||||
const channel = {
|
||||
displayName: channelDisplayName,
|
||||
description: channelDescription,
|
||||
membershipType: 'private',
|
||||
};
|
||||
|
||||
// https://learn.microsoft.com/graph/api/channel-post?view=graph-rest-1.0
|
||||
return await withGraphRetry(() => client.api(`/teams/${teamId}/channels`).post(channel));
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { microsoftTeamsAuth } from '../../';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { Client, PageCollection } from '@microsoft/microsoft-graph-client';
|
||||
import { microsoftTeamsCommon } from '../common';
|
||||
|
||||
export const findChannelAction = createAction({
|
||||
auth: microsoftTeamsAuth,
|
||||
name: 'microsoft_teams_find_channel',
|
||||
displayName: 'Find Channel',
|
||||
description: 'Finds channels by name.',
|
||||
props: {
|
||||
teamId: microsoftTeamsCommon.teamId,
|
||||
channelName: Property.ShortText({
|
||||
displayName: 'Channel Name',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { teamId, channelName } = context.propsValue;
|
||||
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(context.auth.access_token),
|
||||
},
|
||||
});
|
||||
|
||||
const response: PageCollection = await client
|
||||
.api(`/teams/${teamId}/allChannels`)
|
||||
.filter(`displayName eq '${channelName}'`)
|
||||
.get();
|
||||
|
||||
return {
|
||||
found: response.value.length > 0,
|
||||
result: response.value,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
import { microsoftTeamsAuth } from '../../';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { Client, PageCollection } from '@microsoft/microsoft-graph-client';
|
||||
import { microsoftTeamsCommon } from '../common';
|
||||
|
||||
export const findTeamMemberAction = createAction({
|
||||
auth: microsoftTeamsAuth,
|
||||
name: 'microsoft_teams_find_team_member',
|
||||
displayName: 'Find Team Member',
|
||||
description: 'Finds a team member by email or display name.',
|
||||
props: {
|
||||
teamId: microsoftTeamsCommon.teamId,
|
||||
searchBy: Property.StaticDropdown({
|
||||
displayName: 'Search By',
|
||||
required: true,
|
||||
defaultValue: 'email',
|
||||
options: {
|
||||
disabled: false,
|
||||
options: [
|
||||
{ label: 'Email', value: 'email' },
|
||||
{ label: 'Name', value: 'name' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
searchValue: Property.ShortText({
|
||||
displayName: 'searchValue',
|
||||
required: true,
|
||||
description: 'Email address or name to search for.',
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { teamId, searchBy, searchValue } = context.propsValue
|
||||
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(context.auth.access_token),
|
||||
},
|
||||
})
|
||||
|
||||
const filter = searchBy == 'email' ?`microsoft.graph.aadUserConversationMember/email eq '${searchValue}'`:`microsoft.graph.aadUserConversationMember/displayName eq '${searchValue}'`;
|
||||
|
||||
const response: PageCollection = await client
|
||||
.api(`/teams/${teamId}/members`)
|
||||
.filter(filter)
|
||||
.get();
|
||||
|
||||
return {
|
||||
found: response.value.length > 0,
|
||||
result: response.value,
|
||||
};
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { microsoftTeamsAuth } from '../../';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { Client } from '@microsoft/microsoft-graph-client';
|
||||
import { microsoftTeamsCommon } from '../common';
|
||||
import { createGraphClient, withGraphRetry } from '../common/graph';
|
||||
|
||||
export const getChannelMessageAction = createAction({
|
||||
auth: microsoftTeamsAuth,
|
||||
name: 'microsoft_teams_get_channel_message',
|
||||
displayName: 'Get Channel Message',
|
||||
description: 'Fetch a specific channel message by team, channel, and message ID (optionally a reply).',
|
||||
props: {
|
||||
teamId: microsoftTeamsCommon.teamId,
|
||||
channelId: microsoftTeamsCommon.channelId,
|
||||
messageId: Property.ShortText({
|
||||
displayName: 'Message ID',
|
||||
required: true,
|
||||
description: 'The ID of the channel message to retrieve.',
|
||||
}),
|
||||
replyId: Property.ShortText({
|
||||
displayName: 'Reply ID (optional)',
|
||||
required: false,
|
||||
description: 'Provide to fetch a specific reply under the message.',
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { teamId, channelId, messageId, replyId } = context.propsValue;
|
||||
|
||||
const client = createGraphClient(context.auth.access_token);
|
||||
|
||||
// https://learn.microsoft.com/graph/api/chatmessage-get?view=graph-rest-1.0
|
||||
const base = `/teams/${teamId}/channels/${channelId}/messages/${messageId}`;
|
||||
const path = replyId ? `${base}/replies/${replyId}` : base;
|
||||
return await withGraphRetry(() => client.api(path).get());
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { microsoftTeamsAuth } from '../../';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { Client } from '@microsoft/microsoft-graph-client';
|
||||
import { microsoftTeamsCommon } from '../common';
|
||||
import { createGraphClient, withGraphRetry } from '../common/graph';
|
||||
|
||||
export const getChatMessageAction = createAction({
|
||||
auth: microsoftTeamsAuth,
|
||||
name: 'microsoft_teams_get_chat_message',
|
||||
displayName: 'Get Chat Message',
|
||||
description: 'Fetch a specific chat message by chat and message ID.',
|
||||
props: {
|
||||
chatId: microsoftTeamsCommon.chatId,
|
||||
messageId: Property.ShortText({
|
||||
displayName: 'Message ID',
|
||||
required: true,
|
||||
description: 'The ID of the message to retrieve.',
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { chatId, messageId } = context.propsValue;
|
||||
|
||||
const client = createGraphClient(context.auth.access_token);
|
||||
|
||||
// https://learn.microsoft.com/graph/api/chatmessage-get?view=graph-rest-1.0
|
||||
return await withGraphRetry(() => client.api(`/chats/${chatId}/messages/${messageId}`).get());
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import { microsoftTeamsAuth } from '../../';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { Client } from '@microsoft/microsoft-graph-client';
|
||||
import { microsoftTeamsCommon } from '../common';
|
||||
import { createGraphClient, withGraphRetry } from '../common/graph';
|
||||
|
||||
export const replyToChannelMessageAction = createAction({
|
||||
auth: microsoftTeamsAuth,
|
||||
name: 'microsoft_teams_reply_to_channel_message',
|
||||
displayName: 'Reply to Channel Message',
|
||||
description: 'Post a reply to an existing channel message.',
|
||||
props: {
|
||||
teamId: microsoftTeamsCommon.teamId,
|
||||
channelId: microsoftTeamsCommon.channelId,
|
||||
messageId: Property.ShortText({
|
||||
displayName: 'Message ID',
|
||||
required: true,
|
||||
description: 'ID of the parent message to reply to.'
|
||||
}),
|
||||
contentType: Property.StaticDropdown({
|
||||
displayName: 'Content Type',
|
||||
required: true,
|
||||
defaultValue: 'text',
|
||||
options: {
|
||||
disabled: false,
|
||||
options: [
|
||||
{ label: 'Text', value: 'text' },
|
||||
{ label: 'HTML', value: 'html' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
content: Property.LongText({
|
||||
displayName: 'Message',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { teamId, channelId, messageId, contentType, content } = context.propsValue;
|
||||
|
||||
const client = createGraphClient(context.auth.access_token);
|
||||
|
||||
const chatMessage = {
|
||||
body: {
|
||||
content: content,
|
||||
contentType: contentType,
|
||||
},
|
||||
};
|
||||
|
||||
// https://learn.microsoft.com/graph/api/chatmessage-post-replies?view=graph-rest-1.0
|
||||
return await withGraphRetry(() =>
|
||||
client
|
||||
.api(`/teams/${teamId}/channels/${channelId}/messages/${messageId}/replies`)
|
||||
.post(chatMessage)
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { microsoftTeamsAuth } from '../../';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { Client } from '@microsoft/microsoft-graph-client';
|
||||
import { microsoftTeamsCommon } from '../common';
|
||||
|
||||
export const sendChannelMessageAction = createAction({
|
||||
auth: microsoftTeamsAuth,
|
||||
name: 'microsoft_teams_send_channel_message',
|
||||
displayName: 'Send Channel Message',
|
||||
description: "Sends a message to a teams's channel.",
|
||||
props: {
|
||||
teamId: microsoftTeamsCommon.teamId,
|
||||
channelId: microsoftTeamsCommon.channelId,
|
||||
contentType: Property.StaticDropdown({
|
||||
displayName: 'Content Type',
|
||||
required: true,
|
||||
defaultValue: 'text',
|
||||
options: {
|
||||
disabled: false,
|
||||
options: [
|
||||
{
|
||||
label: 'Text',
|
||||
value: 'text',
|
||||
},
|
||||
{
|
||||
label: 'HTML',
|
||||
value: 'html',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
content: Property.LongText({
|
||||
displayName: 'Message',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { teamId, channelId, contentType, content } = context.propsValue;
|
||||
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(context.auth.access_token),
|
||||
},
|
||||
});
|
||||
|
||||
//https://learn.microsoft.com/en-us/graph/api/channel-post-messages?view=graph-rest-1.0&tabs=http
|
||||
const chatMessage = {
|
||||
body: {
|
||||
content: content,
|
||||
contentType: contentType,
|
||||
},
|
||||
};
|
||||
|
||||
return await client.api(`/teams/${teamId}/channels/${channelId}/messages`).post(chatMessage);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,54 @@
|
||||
import { microsoftTeamsAuth } from '../..';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { Client } from '@microsoft/microsoft-graph-client';
|
||||
import { microsoftTeamsCommon } from '../common';
|
||||
|
||||
export const sendChatMessageAction = createAction({
|
||||
auth: microsoftTeamsAuth,
|
||||
name: 'microsoft_teams_send_chat_message',
|
||||
displayName: 'Send Chat Message',
|
||||
description: 'Sends a message in an existing chat.',
|
||||
props: {
|
||||
chatId: microsoftTeamsCommon.chatId,
|
||||
contentType: Property.StaticDropdown({
|
||||
displayName: 'Content Type',
|
||||
required: true,
|
||||
defaultValue: 'text',
|
||||
options: {
|
||||
disabled: false,
|
||||
options: [
|
||||
{
|
||||
label: 'Text',
|
||||
value: 'text',
|
||||
},
|
||||
{
|
||||
label: 'HTML',
|
||||
value: 'html',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
content: Property.LongText({
|
||||
displayName: 'Message',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { chatId, contentType, content } = context.propsValue;
|
||||
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(context.auth.access_token),
|
||||
},
|
||||
});
|
||||
|
||||
const chatMessage = {
|
||||
body: {
|
||||
content: content,
|
||||
contentType: contentType,
|
||||
},
|
||||
};
|
||||
|
||||
return await client.api(`/chats/${chatId}/messages`).post(chatMessage);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,99 @@
|
||||
import { Client } from '@microsoft/microsoft-graph-client';
|
||||
|
||||
type GraphRetryOptions = {
|
||||
maxRetries?: number;
|
||||
initialDelayMs?: number;
|
||||
maxDelayMs?: number;
|
||||
};
|
||||
|
||||
export const createGraphClient = (accessToken: string): Client => {
|
||||
return Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(accessToken),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const delay = async (ms: number): Promise<void> =>
|
||||
new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
const parseRetryAfterMs = (error: any): number | null => {
|
||||
const headers: Record<string, string> | undefined =
|
||||
error?.headers ?? error?.response?.headers ?? undefined;
|
||||
const retryAfter = headers?.['Retry-After'] ?? headers?.['retry-after'];
|
||||
if (!retryAfter) return null;
|
||||
const asNumber = Number(retryAfter);
|
||||
if (!Number.isNaN(asNumber)) return asNumber * 1000;
|
||||
// Retry-After can be HTTP-date; in that case, compute delta
|
||||
const retryDate = Date.parse(retryAfter);
|
||||
if (!Number.isNaN(retryDate)) {
|
||||
return Math.max(0, retryDate - Date.now());
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const extractStatusCode = (error: any): number => {
|
||||
return (
|
||||
error?.statusCode ??
|
||||
error?.status ??
|
||||
error?.response?.status ??
|
||||
error?.response?.statusCode ??
|
||||
0
|
||||
);
|
||||
};
|
||||
|
||||
const shouldRetry = (statusCode: number, code?: string): boolean => {
|
||||
// Retry on throttling and transient errors
|
||||
if (statusCode === 429 || statusCode === 503 || statusCode === 504) return true;
|
||||
// Some concurrency conflicts can be retried
|
||||
if (statusCode === 409) return true;
|
||||
// Optionally retry generic server errors
|
||||
if (statusCode >= 500 && statusCode < 600) return true;
|
||||
// Some SDKs surface codes like 'TooManyRequests'
|
||||
if (code && /too\s*many\s*requests/i.test(code)) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
export const buildGraphErrorMessage = (error: any): string => {
|
||||
const status = extractStatusCode(error);
|
||||
const err = error?.body?.error ?? error?.error ?? {};
|
||||
const code = err?.code ?? error?.code;
|
||||
const message = err?.message ?? error?.message ?? 'Request failed';
|
||||
const inner = err?.innerError ?? err?.innererror ?? {};
|
||||
const requestId = inner?.['request-id'] ?? inner?.requestId ?? error?.requestId;
|
||||
return `Graph error (${status}${code ? ` ${code}` : ''})${requestId ? ` [request-id: ${requestId}]` : ''}: ${message}`;
|
||||
};
|
||||
|
||||
export const withGraphRetry = async <T>(
|
||||
requestFn: () => Promise<T>,
|
||||
options: GraphRetryOptions = {}
|
||||
): Promise<T> => {
|
||||
const maxRetries = options.maxRetries ?? 3;
|
||||
const initialDelayMs = options.initialDelayMs ?? 1000;
|
||||
const maxDelayMs = options.maxDelayMs ?? 10000;
|
||||
|
||||
let attempt = 0;
|
||||
let delayMs = initialDelayMs;
|
||||
|
||||
while (attempt <= maxRetries) {
|
||||
try {
|
||||
return await requestFn();
|
||||
} catch (e: any) {
|
||||
const status = extractStatusCode(e);
|
||||
const code = e?.body?.error?.code ?? e?.error?.code ?? e?.code;
|
||||
if (attempt < maxRetries && shouldRetry(status, code)) {
|
||||
const retryAfterMs = parseRetryAfterMs(e);
|
||||
await delay(Math.min(retryAfterMs ?? delayMs, maxDelayMs));
|
||||
attempt++;
|
||||
if (!retryAfterMs) {
|
||||
delayMs = Math.min(delayMs * 2, maxDelayMs);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
throw new Error(buildGraphErrorMessage(e));
|
||||
}
|
||||
}
|
||||
throw new Error("Unexpected error occured");
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
import { DropdownOption, PiecePropValueSchema, Property } from '@activepieces/pieces-framework';
|
||||
|
||||
import { Client, PageCollection } from '@microsoft/microsoft-graph-client';
|
||||
import { Team, Channel, Chat, ConversationMember } from '@microsoft/microsoft-graph-types';
|
||||
import { microsoftTeamsAuth } from '../../';
|
||||
|
||||
export const microsoftTeamsCommon = {
|
||||
teamId: Property.Dropdown({
|
||||
auth: microsoftTeamsAuth,
|
||||
displayName: 'Team ID',
|
||||
refreshers: [],
|
||||
required: true,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const authValue = auth as PiecePropValueSchema<typeof microsoftTeamsAuth>;
|
||||
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(authValue.access_token),
|
||||
},
|
||||
});
|
||||
const options: DropdownOption<string>[] = [];
|
||||
|
||||
// Pagination : https://learn.microsoft.com/en-us/graph/sdks/paging?view=graph-rest-1.0&tabs=typescript#manually-requesting-subsequent-pages
|
||||
// List Joined Channels : https://learn.microsoft.com/en-us/graph/api/user-list-joinedteams?view=graph-rest-1.0&tabs=http
|
||||
let response: PageCollection = await client.api('/me/joinedTeams').get();
|
||||
while (response.value.length > 0) {
|
||||
for (const team of response.value as Team[]) {
|
||||
options.push({ label: team.displayName!, value: team.id! });
|
||||
}
|
||||
if (response['@odata.nextLink']) {
|
||||
response = await client.api(response['@odata.nextLink']).get();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {
|
||||
disabled: false,
|
||||
options: options,
|
||||
};
|
||||
},
|
||||
}),
|
||||
channelId: Property.Dropdown({
|
||||
auth: microsoftTeamsAuth,
|
||||
displayName: 'Channel ID',
|
||||
refreshers: ['teamId'],
|
||||
required: true,
|
||||
options: async ({ auth, teamId }) => {
|
||||
if (!auth || !teamId) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first and select team.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const authValue = auth as PiecePropValueSchema<typeof microsoftTeamsAuth>;
|
||||
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(authValue.access_token),
|
||||
},
|
||||
});
|
||||
const options: DropdownOption<string>[] = [];
|
||||
|
||||
// Pagination : https://learn.microsoft.com/en-us/graph/sdks/paging?view=graph-rest-1.0&tabs=typescript#manually-requesting-subsequent-pages
|
||||
// List Channels : https://learn.microsoft.com/en-us/graph/api/channel-list?view=graph-rest-1.0&tabs=http
|
||||
let response: PageCollection = await client.api(`/teams/${teamId}/channels`).get();
|
||||
while (response.value.length > 0) {
|
||||
for (const channel of response.value as Channel[]) {
|
||||
options.push({ label: channel.displayName!, value: channel.id! });
|
||||
}
|
||||
if (response['@odata.nextLink']) {
|
||||
response = await client.api(response['@odata.nextLink']).get();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {
|
||||
disabled: false,
|
||||
options: options,
|
||||
};
|
||||
},
|
||||
}),
|
||||
memberId:(isRequired=false) =>Property.Dropdown({
|
||||
auth: microsoftTeamsAuth,
|
||||
displayName: 'Member',
|
||||
refreshers: ['teamId'],
|
||||
required: isRequired,
|
||||
options: async ({ auth, teamId }) => {
|
||||
if (!auth || !teamId) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first and select team.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const authValue = auth as PiecePropValueSchema<typeof microsoftTeamsAuth>;
|
||||
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(authValue.access_token),
|
||||
},
|
||||
});
|
||||
const options: DropdownOption<string>[] = [];
|
||||
|
||||
let response: PageCollection = await client.api(`/teams/${teamId}/members`).get();
|
||||
while (response.value.length > 0) {
|
||||
for (const member of response.value as ConversationMember[]) {
|
||||
options.push({ label: member.displayName!, value: member.id! });
|
||||
}
|
||||
if (response['@odata.nextLink']) {
|
||||
response = await client.api(response['@odata.nextLink']).get();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {
|
||||
disabled: false,
|
||||
options: options,
|
||||
};
|
||||
},
|
||||
}),
|
||||
memberIds:(isRequired=false) =>Property.MultiSelectDropdown({
|
||||
auth: microsoftTeamsAuth,
|
||||
displayName: 'Member',
|
||||
refreshers: ['teamId'],
|
||||
required: isRequired,
|
||||
options: async ({ auth, teamId }) => {
|
||||
if (!auth || !teamId) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first and select team.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const authValue = auth as PiecePropValueSchema<typeof microsoftTeamsAuth>;
|
||||
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(authValue.access_token),
|
||||
},
|
||||
});
|
||||
const options: DropdownOption<string>[] = [];
|
||||
|
||||
let response: PageCollection = await client.api(`/teams/${teamId}/members`).get();
|
||||
while (response.value.length > 0) {
|
||||
for (const member of response.value as ConversationMember[]) {
|
||||
options.push({ label: member.displayName!, value: member.id! });
|
||||
}
|
||||
if (response['@odata.nextLink']) {
|
||||
response = await client.api(response['@odata.nextLink']).get();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {
|
||||
disabled: false,
|
||||
options: options,
|
||||
};
|
||||
},
|
||||
}),
|
||||
chatId: Property.Dropdown({
|
||||
auth: microsoftTeamsAuth,
|
||||
displayName: 'Chat ID',
|
||||
refreshers: [],
|
||||
required: true,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first and select team.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
const authValue = auth as PiecePropValueSchema<typeof microsoftTeamsAuth>;
|
||||
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(authValue.access_token),
|
||||
},
|
||||
});
|
||||
const options: DropdownOption<string>[] = [];
|
||||
|
||||
// Pagination : https://learn.microsoft.com/en-us/graph/sdks/paging?view=graph-rest-1.0&tabs=typescript#manually-requesting-subsequent-pages
|
||||
// List Chats : https://learn.microsoft.com/en-us/graph/api/chat-list?view=graph-rest-1.0&tabs=http
|
||||
let response: PageCollection = await client.api('/chats').expand('members').get();
|
||||
while (response.value.length > 0) {
|
||||
for (const chat of response.value as Chat[]) {
|
||||
const chatName =
|
||||
chat.topic ??
|
||||
chat.members
|
||||
?.filter((member: ConversationMember) => member.displayName)
|
||||
.map((member: ConversationMember) => member.displayName)
|
||||
.join(',');
|
||||
options.push({
|
||||
label: `(${CHAT_TYPE[chat.chatType! as keyof typeof CHAT_TYPE]} Chat) ${chatName || '(no title)'}`,
|
||||
value: chat.id!,
|
||||
});
|
||||
}
|
||||
if (response['@odata.nextLink']) {
|
||||
response = await client.api(response['@odata.nextLink']).get();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {
|
||||
disabled: false,
|
||||
options: options,
|
||||
};
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
const CHAT_TYPE = {
|
||||
oneOnOne: '1 : 1',
|
||||
group: 'Group',
|
||||
meeting: 'Meeting',
|
||||
unknownFutureValue: 'Unknown',
|
||||
};
|
||||
@@ -0,0 +1,142 @@
|
||||
import { microsoftTeamsAuth } from '../../index';
|
||||
import { DedupeStrategy, Polling, pollingHelper } from '@activepieces/pieces-common';
|
||||
import {
|
||||
createTrigger,
|
||||
AppConnectionValueForAuthProperty,
|
||||
TriggerStrategy,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { microsoftTeamsCommon } from '../common';
|
||||
import { Client, PageCollection } from '@microsoft/microsoft-graph-client';
|
||||
import { ChatMessage } from '@microsoft/microsoft-graph-types';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import { isNil } from '@activepieces/shared';
|
||||
type Props = {
|
||||
teamId: string;
|
||||
channelId: string;
|
||||
};
|
||||
|
||||
export const newChannelMessageTrigger = createTrigger({
|
||||
auth: microsoftTeamsAuth,
|
||||
name: 'new-channel-message',
|
||||
displayName: 'New Channel Message',
|
||||
description: 'Triggers when a new message is posted in a channel.',
|
||||
props: {
|
||||
teamId: microsoftTeamsCommon.teamId,
|
||||
channelId: microsoftTeamsCommon.channelId,
|
||||
},
|
||||
type: TriggerStrategy.POLLING,
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
sampleData: {
|
||||
replyToId: null,
|
||||
etag: '1747831213175',
|
||||
messageType: 'message',
|
||||
createdDateTime: '2025-05-21T12:40:13.175Z',
|
||||
lastModifiedDateTime: '2025-05-21T12:40:13.175Z',
|
||||
lastEditedDateTime: null,
|
||||
deletedDateTime: null,
|
||||
subject: 'Test',
|
||||
summary: null,
|
||||
chatId: null,
|
||||
importance: 'normal',
|
||||
locale: 'en-us',
|
||||
webUrl:'',
|
||||
policyViolation: null,
|
||||
eventDetail: null,
|
||||
id: '1747831213175',
|
||||
from: {
|
||||
application: null,
|
||||
device: null,
|
||||
user: {
|
||||
'@odata.type': '#microsoft.graph.teamworkUserIdentity',
|
||||
id: '90b3720d-f459-42c1-a02e-a1ecb068',
|
||||
displayName: 'Activepieces',
|
||||
userIdentityType: 'aadUser',
|
||||
tenantId: '9b37335a-d996-4a8d-9ae4-a3a04c94',
|
||||
},
|
||||
},
|
||||
body: {
|
||||
contentType: 'html',
|
||||
content: '<p>Test Message</p>',
|
||||
},
|
||||
channelIdentity: {
|
||||
teamId: '99cb9-7ebe-43ee-a69b-5f77ce8a4b4e',
|
||||
channelId: '19:LiZnIkTo_1FmFY9OTsfym0q3bwo-y2UfV9FaYA1@thread.tacv2',
|
||||
},
|
||||
attachments: [],
|
||||
mentions: [],
|
||||
reactions: [],
|
||||
},
|
||||
});
|
||||
|
||||
const polling: Polling<AppConnectionValueForAuthProperty<typeof microsoftTeamsAuth>, Props> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
async items({ auth, propsValue, lastFetchEpochMS, store }) {
|
||||
const { teamId, channelId } = propsValue;
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(auth.access_token),
|
||||
},
|
||||
});
|
||||
|
||||
const messages: ChatMessage[] = [];
|
||||
|
||||
if (lastFetchEpochMS === 0) {
|
||||
const response: PageCollection = await client
|
||||
.api(`/teams/${teamId}/channels/${channelId}/messages`)
|
||||
.top(5)
|
||||
.get();
|
||||
|
||||
if (!isNil(response.value)) {
|
||||
messages.push(...response.value);
|
||||
}
|
||||
} else {
|
||||
const requestUrl =
|
||||
(await store.get<string>('deltalink')) ??
|
||||
`/teams/${teamId}/channels/${channelId}/messages/delta`;
|
||||
let nextLink: string | null = requestUrl;
|
||||
|
||||
// https://learn.microsoft.com/en-us/graph/api/chatmessage-delta?view=graph-rest-1.0&tabs=http
|
||||
while (nextLink) {
|
||||
const response: PageCollection = await client.api(nextLink).get();
|
||||
const channelMessages = response.value as ChatMessage[];
|
||||
|
||||
if (Array.isArray(channelMessages)) {
|
||||
messages.push(...channelMessages);
|
||||
}
|
||||
|
||||
nextLink = response['@odata.nextLink'] ?? null;
|
||||
|
||||
if (response['@odata.deltaLink']) {
|
||||
await store.put<string>('deltalink', response['@odata.deltaLink']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return messages.map((message: ChatMessage) => {
|
||||
return {
|
||||
epochMilliSeconds: dayjs(message.createdDateTime).valueOf(),
|
||||
data: message,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,95 @@
|
||||
import { microsoftTeamsAuth } from '../../index';
|
||||
import { DedupeStrategy, Polling, pollingHelper } from '@activepieces/pieces-common';
|
||||
import {
|
||||
createTrigger,
|
||||
AppConnectionValueForAuthProperty,
|
||||
TriggerStrategy,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { microsoftTeamsCommon } from '../common';
|
||||
import { Client, PageCollection } from '@microsoft/microsoft-graph-client';
|
||||
import { Channel } from '@microsoft/microsoft-graph-types';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import { isNil } from '@activepieces/shared';
|
||||
|
||||
type Props = {
|
||||
teamId: string;
|
||||
};
|
||||
|
||||
export const newChannelTrigger = createTrigger({
|
||||
auth: microsoftTeamsAuth,
|
||||
name: 'new-channel',
|
||||
displayName: 'New Channel',
|
||||
description: 'Triggers when a new channel is created in a team.',
|
||||
props: {
|
||||
teamId: microsoftTeamsCommon.teamId,
|
||||
},
|
||||
type: TriggerStrategy.POLLING,
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
sampleData: {
|
||||
id: '19:561fbdbbfca848a484f0a6f00ce9dbbd@thread.tacv2',
|
||||
createdDateTime: '2025-05-21T12:40:13.175Z',
|
||||
displayName: 'General',
|
||||
description: 'Auto-generated channel',
|
||||
membershipType: 'standard',
|
||||
isArchived: false,
|
||||
},
|
||||
});
|
||||
|
||||
const polling: Polling<AppConnectionValueForAuthProperty<typeof microsoftTeamsAuth>, Props> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
async items({ auth, propsValue, lastFetchEpochMS }) {
|
||||
const { teamId } = propsValue;
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(auth.access_token),
|
||||
},
|
||||
});
|
||||
const lastFetchDate = dayjs(lastFetchEpochMS).toISOString();
|
||||
|
||||
const channels: Channel[] = [];
|
||||
const filter = lastFetchEpochMS === 0 ? '' : `?$filter=createdDateTime gt ${lastFetchDate}`;
|
||||
|
||||
let response: PageCollection = await client.api(`/teams/${teamId}/channels${filter}`).get();
|
||||
|
||||
while (response.value && response.value.length > 0) {
|
||||
for (const channel of response.value as Channel[]) {
|
||||
if (isNil(channel.createdDateTime)) {
|
||||
continue;
|
||||
}
|
||||
channels.push(channel);
|
||||
}
|
||||
if (lastFetchEpochMS !== 0 && response['@odata.nextLink']) {
|
||||
response = await client.api(response['@odata.nextLink']).get();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return channels.map((channel: Channel) => {
|
||||
return {
|
||||
epochMilliSeconds: dayjs(channel.createdDateTime!).valueOf(),
|
||||
data: channel,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,138 @@
|
||||
import { microsoftTeamsAuth } from '../../index';
|
||||
import { DedupeStrategy, Polling, pollingHelper } from '@activepieces/pieces-common';
|
||||
import {
|
||||
createTrigger,
|
||||
AppConnectionValueForAuthProperty,
|
||||
TriggerStrategy,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { microsoftTeamsCommon } from '../common';
|
||||
import { Client, PageCollection } from '@microsoft/microsoft-graph-client';
|
||||
import { ChatMessage } from '@microsoft/microsoft-graph-types';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import { isNil } from '@activepieces/shared';
|
||||
|
||||
type Props = {
|
||||
chatId: string;
|
||||
};
|
||||
|
||||
export const newChatMessageTrigger = createTrigger({
|
||||
auth: microsoftTeamsAuth,
|
||||
name: 'new-chat-message',
|
||||
displayName: 'New Chat Message',
|
||||
description: 'Triggers when a new message is received in a chat.',
|
||||
props: {
|
||||
chatId: microsoftTeamsCommon.chatId,
|
||||
},
|
||||
type: TriggerStrategy.POLLING,
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
sampleData: {
|
||||
replyToId: null,
|
||||
etag: '1747831213175',
|
||||
messageType: 'message',
|
||||
createdDateTime: '2025-05-21T12:40:13.175Z',
|
||||
lastModifiedDateTime: '2025-05-21T12:40:13.175Z',
|
||||
lastEditedDateTime: null,
|
||||
deletedDateTime: null,
|
||||
subject: null,
|
||||
summary: null,
|
||||
chatId: '19:example_chat_id@unq.gbl.spaces',
|
||||
importance: 'normal',
|
||||
locale: 'en-us',
|
||||
webUrl: '',
|
||||
policyViolation: null,
|
||||
eventDetail: null,
|
||||
id: '1747831213175',
|
||||
from: {
|
||||
application: null,
|
||||
device: null,
|
||||
user: {
|
||||
'@odata.type': '#microsoft.graph.teamworkUserIdentity',
|
||||
id: '90b3720d-f459-42c1-a02e-a1ecb068',
|
||||
displayName: 'Activepieces',
|
||||
userIdentityType: 'aadUser',
|
||||
tenantId: '9b37335a-d996-4a8d-9ae4-a3a04c94',
|
||||
},
|
||||
},
|
||||
body: {
|
||||
contentType: 'html',
|
||||
content: '<p>Test Message</p>',
|
||||
},
|
||||
attachments: [],
|
||||
mentions: [],
|
||||
reactions: [],
|
||||
},
|
||||
});
|
||||
|
||||
const polling: Polling<AppConnectionValueForAuthProperty<typeof microsoftTeamsAuth>, Props> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
async items({ auth, propsValue, lastFetchEpochMS, store }) {
|
||||
const { chatId } = propsValue;
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(auth.access_token),
|
||||
},
|
||||
});
|
||||
|
||||
const messages: ChatMessage[] = [];
|
||||
|
||||
if (lastFetchEpochMS === 0) {
|
||||
const response: PageCollection = await client
|
||||
.api(`/chats/${chatId}/messages`)
|
||||
.top(5)
|
||||
.get();
|
||||
|
||||
if (!isNil(response.value)) {
|
||||
messages.push(...(response.value as ChatMessage[]));
|
||||
}
|
||||
} else {
|
||||
const requestUrl =
|
||||
(await store.get<string>('deltalink')) ?? `/chats/${chatId}/messages/delta`;
|
||||
let nextLink: string | null = requestUrl;
|
||||
|
||||
// https://learn.microsoft.com/graph/api/chatmessage-delta?view=graph-rest-1.0&tabs=http
|
||||
while (nextLink) {
|
||||
const response: PageCollection = await client.api(nextLink).get();
|
||||
const chatMessages = response.value as ChatMessage[];
|
||||
|
||||
if (Array.isArray(chatMessages)) {
|
||||
messages.push(...chatMessages);
|
||||
}
|
||||
|
||||
nextLink = response['@odata.nextLink'] ?? null;
|
||||
|
||||
if (response['@odata.deltaLink']) {
|
||||
await store.put<string>('deltalink', response['@odata.deltaLink']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return messages.map((message: ChatMessage) => {
|
||||
return {
|
||||
epochMilliSeconds: dayjs(message.createdDateTime).valueOf(),
|
||||
data: message,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import { microsoftTeamsAuth } from '../../index';
|
||||
import { DedupeStrategy, Polling, pollingHelper } from '@activepieces/pieces-common';
|
||||
import {
|
||||
createTrigger,
|
||||
AppConnectionValueForAuthProperty,
|
||||
TriggerStrategy,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { isNil } from '@activepieces/shared';
|
||||
import { Client, PageCollection } from '@microsoft/microsoft-graph-client';
|
||||
import { Chat, ChatType } from '@microsoft/microsoft-graph-types';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
type Props = {
|
||||
chatType?: ChatType;
|
||||
};
|
||||
|
||||
export const newChatTrigger = createTrigger({
|
||||
auth: microsoftTeamsAuth,
|
||||
name: 'new-chat',
|
||||
displayName: 'New Chat',
|
||||
description: 'Triggers when a new chat is created.',
|
||||
props: {},
|
||||
type: TriggerStrategy.POLLING,
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue as Props,
|
||||
});
|
||||
},
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue as Props,
|
||||
});
|
||||
},
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context as any);
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context as any);
|
||||
},
|
||||
sampleData: {
|
||||
id: '19:example_chat_id@unq.gbl.spaces',
|
||||
createdDateTime: '2025-05-21T12:40:13.175Z',
|
||||
lastUpdatedDateTime: '2025-05-21T12:40:13.175Z',
|
||||
chatType: 'oneOnOne',
|
||||
webUrl: '',
|
||||
isHiddenForAllMembers: false,
|
||||
},
|
||||
});
|
||||
|
||||
const polling: Polling<AppConnectionValueForAuthProperty<typeof microsoftTeamsAuth>, Props> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
async items({ auth, lastFetchEpochMS }) {
|
||||
const client = Client.initWithMiddleware({
|
||||
authProvider: {
|
||||
getAccessToken: () => Promise.resolve(auth.access_token),
|
||||
},
|
||||
});
|
||||
const lastFetchDate = dayjs(lastFetchEpochMS).toISOString();
|
||||
|
||||
const chats: Chat[] = [];
|
||||
const filter =
|
||||
lastFetchEpochMS === 0
|
||||
? '$top=10'
|
||||
: `$filter=createdDateTime gt ${lastFetchDate}`;
|
||||
|
||||
let response: PageCollection = await client.api(`/chats?${filter}`).get();
|
||||
|
||||
console.log('RESPONE');
|
||||
console.log(JSON.stringify(response))
|
||||
|
||||
while (response.value && response.value.length > 0) {
|
||||
for (const channel of response.value as Chat[]) {
|
||||
if (isNil(channel.createdDateTime)) {
|
||||
continue;
|
||||
}
|
||||
chats.push(channel);
|
||||
}
|
||||
if (lastFetchEpochMS !== 0 && response['@odata.nextLink']) {
|
||||
response = await client.api(response['@odata.nextLink']).get();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return chats.map((chat: Chat) => {
|
||||
return {
|
||||
epochMilliSeconds: dayjs(chat.createdDateTime!).valueOf(),
|
||||
data: chat,
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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"]
|
||||
}
|
||||
Reference in New Issue
Block a user