Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ACTION] Microsoft Teams Bot - Reply to Message #14817

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jcortes
Copy link
Collaborator

@jcortes jcortes commented Dec 3, 2024

WHY

Resolves #14758

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a module for replying to messages in Microsoft Teams, enhancing user interaction capabilities.
    • Added a new module for sending messages in Microsoft Teams, allowing users to communicate more effectively.
    • Enhanced configuration capabilities with new properties for message handling.
  • Bug Fixes

    • Removed outdated authentication method to streamline functionality.
  • Chores

    • Updated version number to 0.1.0 and added necessary dependencies in the package configuration.

@jcortes jcortes added the action New Action Request label Dec 3, 2024
@jcortes jcortes self-assigned this Dec 3, 2024
Copy link

vercel bot commented Dec 3, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

3 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Ignored (Inspect) Visit Preview Dec 5, 2024 2:57pm
pipedream-docs ⬜️ Ignored (Inspect) Dec 5, 2024 2:57pm
pipedream-docs-redirect-do-not-edit ⬜️ Ignored (Inspect) Dec 5, 2024 2:57pm

Copy link
Contributor

coderabbitai bot commented Dec 3, 2024

Walkthrough

This pull request introduces a new module for replying to messages in Microsoft Teams, identified as microsoft_teams_bot-reply-to-message. It includes properties for handling messages and a method for sending replies through the Microsoft Teams API. Additionally, several new methods for constructing and managing HTTP requests have been added to the main application file, and a new constant for versioning has been introduced. The package.json file has been updated to reflect a new version and added dependencies.

Changes

File Path Change Summary
components/microsoft_teams_bot/actions/reply-to-message/reply-to-message.mjs New module for replying to messages with properties and methods for API interaction.
components/microsoft_teams_bot/actions/send-message/send-message.mjs New module for sending messages with properties and methods for API interaction.
components/microsoft_teams_bot/common/constants.mjs Added new constant VERSION_PATH with the value "v3" for centralized version reference and ACTIVITY_TYPE for activity types.
components/microsoft_teams_bot/microsoft_teams_bot.app.mjs Introduced new methods for HTTP requests: sanitizeBaseUrl, getUrl, getHeaders, makeRequest, and post; removed authKeys.
components/microsoft_teams_bot/package.json Updated version from 0.0.1 to 0.1.0 and added dependency on @pipedream/platform version 3.0.3.

Assessment against linked issues

Objective Addressed Explanation
Implement a reply action for Microsoft Teams Bot (#14758)
Ensure proper API interaction for replying to messages (#14758)

Suggested labels

ai-assisted

Suggested reviewers

  • GTFalcao

🐰 In the meadow where messages flow,
A new reply action starts to grow.
With constants and methods, all in line,
Microsoft Teams, your replies will shine!
Hopping along, we send our cheer,
For every message, we hold dear! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (5)
components/microsoft_teams_bot/package.json (1)

3-3: Consider using a version range for @pipedream/platform dependency

While the version bump and dependency addition look good, consider using a version range (e.g., ^3.0.3) for the @pipedream/platform dependency to allow for compatible updates.

Also applies to: 15-16

components/microsoft_teams_bot/microsoft_teams_bot.app.mjs (1)

9-11: Consider URL path sanitization

While the URL construction looks correct, consider sanitizing the path parameter to ensure it starts with a forward slash to prevent potential URL construction issues.

-    return `${baseUrl}${constants.VERSION_PATH}${path}`;
+    const sanitizedPath = path.startsWith('/') ? path : `/${path}`;
+    return `${baseUrl}${constants.VERSION_PATH}${sanitizedPath}`;
components/microsoft_teams_bot/actions/reply-to-message/reply-to-message.mjs (3)

6-6: Version the documentation link

The documentation link should include a specific API version instead of using the view parameter to ensure long-term stability.

-  description: "Reply to a message in Microsoft Teams. [See the documentation](https://learn.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-connector-quickstart?view=azure-bot-service-4.0#reply-to-the-users-message).",
+  description: "Reply to a message in Microsoft Teams. [See the documentation](https://learn.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-connector-quickstart/v4.0#reply-to-the-users-message).",

11-15: Validate baseUrl format

Add validation for the baseUrl prop to ensure it's a valid URL and doesn't end with a slash.

     baseUrl: {
       type: "string",
       label: "Base URL",
       description: "The URL of the service. Eg. `https://smba.trafficmanager.net`.",
+      validate: (url) => {
+        try {
+          new URL(url);
+          if (url.endsWith('/')) {
+            return "Base URL should not end with a forward slash";
+          }
+          return true;
+        } catch (e) {
+          return "Please enter a valid URL";
+        }
+      },
     },

96-96: Enhance success message with message details

Make the success message more informative by including relevant details.

-    $.export("$summary", "Successfully replied to message.");
+    $.export("$summary", `Successfully replied to message in conversation ${conversationId}`);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between fb62fb3 and cdab94d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • components/microsoft_teams_bot/actions/reply-to-message/reply-to-message.mjs (1 hunks)
  • components/microsoft_teams_bot/common/constants.mjs (1 hunks)
  • components/microsoft_teams_bot/microsoft_teams_bot.app.mjs (1 hunks)
  • components/microsoft_teams_bot/package.json (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • components/microsoft_teams_bot/common/constants.mjs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (1)
components/microsoft_teams_bot/actions/reply-to-message/reply-to-message.mjs (1)

4-8: Consider bumping version number

Since this is a fully functional message reply implementation, consider using version "1.0.0" instead of "0.0.1" to indicate production readiness.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between cdab94d and d2b1fea.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • components/microsoft_teams_bot/actions/reply-to-message/reply-to-message.mjs (1 hunks)
  • components/microsoft_teams_bot/common/constants.mjs (1 hunks)
  • components/microsoft_teams_bot/microsoft_teams_bot.app.mjs (1 hunks)
  • components/microsoft_teams_bot/package.json (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • components/microsoft_teams_bot/common/constants.mjs
  • components/microsoft_teams_bot/package.json
🔇 Additional comments (7)
components/microsoft_teams_bot/microsoft_teams_bot.app.mjs (4)

17-23: LGTM! Secure header implementation

The headers implementation correctly uses Bearer token authentication and sets appropriate content type.


33-37: LGTM! Clean POST method implementation

The post method provides a clean wrapper for making POST requests.


24-32: 🛠️ Refactor suggestion

Add error handling and request timeout

The makeRequest method should include error handling and a request timeout for better reliability.

 makeRequest({
-  $ = this, baseUrl, path, headers, ...args
+  $ = this, baseUrl, path, headers, timeout = 10000, ...args
 } = {}) {
   return axios($, {
     url: this.getUrl(baseUrl, path),
     headers: this.getHeaders(headers),
+    timeout,
+    validateStatus: (status) => status < 500,
     ...args,
-  });
+  }).catch((error) => {
+    const status = error?.response?.status;
+    const message = error?.response?.data?.message || error.message;
+    throw new Error(`Request failed with status ${status}: ${message}`);
+  });
 },

14-16: Verify VERSION_PATH constant

The method relies on VERSION_PATH from constants. Let's verify its existence and format.

✅ Verification successful

VERSION_PATH constant is properly defined and used

The constant is correctly defined in components/microsoft_teams_bot/common/constants.mjs with a value of "v3" and is properly exported. The getUrl method's usage of this constant is valid.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if VERSION_PATH is defined and properly formatted
ast-grep --pattern 'export default {
  $$$
  VERSION_PATH: $_,
  $$$
}' components/microsoft_teams_bot/common/constants.mjs

Length of output: 125


Script:

#!/bin/bash
# Let's try a broader search for VERSION_PATH constant
rg "VERSION_PATH" components/microsoft_teams_bot/ -A 2

# Also check the constants file directly to see its content
cat components/microsoft_teams_bot/common/constants.mjs

Length of output: 794

components/microsoft_teams_bot/actions/reply-to-message/reply-to-message.mjs (3)

9-51: LGTM! Well-documented props configuration

The props are comprehensively defined with clear descriptions and example mappings from event data.


53-60: 🛠️ Refactor suggestion

Fix typo and add input validation

The method should validate required parameters.

 replyToMessage({
   conversationId, activityId, ...args
 } = {}) {
+  if (!conversationId || !activityId) {
+    throw new Error("Both conversation ID and activity ID are required");
+  }
   return this.app.post({
     path: `/conversations/${conversationId}/activities/${activityId}`,
     ...args,
   });
 },

62-101: 🛠️ Refactor suggestion

Add type checking and response validation

The run method should validate input types and verify the response structure.

 async run({ $ }) {
   const {
     replyToMessage,
     baseUrl,
     text,
     fromId,
     fromName,
     conversationId,
     toId,
     toName,
     activityId,
   } = this;

+  // Validate required inputs
+  if (!text?.trim()) {
+    throw new Error("Message text is required");
+  }
+  
+  if (!conversationId || !fromId || !toId) {
+    throw new Error("Conversation ID, sender ID, and recipient ID are required");
+  }

   const response = await replyToMessage({
     $,
     baseUrl,
     conversationId,
     activityId,
     data: {
       type: "message",
       from: {
         id: fromId,
         name: fromName,
       },
       conversation: {
         id: conversationId,
       },
       recipient: {
         id: toId,
         name: toName,
       },
       text,
       replyToId: activityId,
     },
   });

+  // Validate response
+  if (!response?.id) {
+    throw new Error("Invalid response from Teams API");
+  }

   $.export("$summary", "Successfully replied to message.");

   return response;
 },

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (2)
components/microsoft_teams_bot/common/constants.mjs (1)

1-1: Consider making version configurable

The hard-coded version "v3" could make future API version updates challenging. Consider making this configurable through environment variables.

-const VERSION_PATH = "v3";
+const VERSION_PATH = process.env.MS_TEAMS_API_VERSION || "v3";
components/microsoft_teams_bot/actions/reply-to-message/reply-to-message.mjs (1)

24-28: Add validation for activityId property

While the description is clear, consider adding validation to ensure the activityId follows the expected format from Teams API.

     activityId: {
       type: "string",
       label: "Reply To ID",
       description: "ID of the message being replied to. Required for threading messages correctly in Teams conversations. Maps to `event.body.id` from the trigger event.",
+      validation: {
+        required: true,
+        pattern: "^[0-9]+$",
+        error: "Activity ID must be a valid Teams message identifier"
+      }
     },
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between d2b1fea and 309171f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • components/microsoft_teams_bot/actions/reply-to-message/reply-to-message.mjs (1 hunks)
  • components/microsoft_teams_bot/actions/send-message/send-message.mjs (1 hunks)
  • components/microsoft_teams_bot/common/constants.mjs (1 hunks)
  • components/microsoft_teams_bot/microsoft_teams_bot.app.mjs (1 hunks)
  • components/microsoft_teams_bot/package.json (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/microsoft_teams_bot/package.json
🔇 Additional comments (8)
components/microsoft_teams_bot/common/constants.mjs (1)

3-19: LGTM! Well-structured activity types

The ACTIVITY_TYPE constant provides a comprehensive list of all possible Microsoft Teams activity types, making the code more maintainable and type-safe.

components/microsoft_teams_bot/microsoft_teams_bot.app.mjs (3)

8-42: LGTM! Well-documented prop definitions

The property definitions are well-structured with clear labels and helpful descriptions that include example values.


45-49: Add input validation to URL sanitization

The URL sanitization could be more robust by validating the input.


60-68: Add error handling and request timeout

The makeRequest method should include error handling and a request timeout for better reliability.

components/microsoft_teams_bot/actions/reply-to-message/reply-to-message.mjs (4)

1-9: LGTM! Well-structured component definition with clear documentation.

The component is properly defined with appropriate imports and metadata. The documentation link provides valuable reference to the Microsoft Teams API.


61-68: Add input validation for required parameters

The method should validate required parameters before making the API call.


70-109: 🛠️ Refactor suggestion

Add error handling and input validation

The run method should include:

  1. Validation of required fields before API call
  2. Error handling for API response
  3. Proper type checking for input parameters
   async run({ $ }) {
     const {
       replyToMessage,
       baseUrl,
       text,
       fromId,
       fromName,
       conversationId,
       toId,
       toName,
       activityId,
     } = this;
 
+    // Validate required fields
+    if (!text?.trim()) {
+      throw new Error("Message text cannot be empty");
+    }
+    if (!conversationId || !activityId) {
+      throw new Error("Conversation ID and Activity ID are required");
+    }
+    if (!fromId || !toId) {
+      throw new Error("Sender and recipient IDs are required");
+    }
+
     const response = await replyToMessage({
       $,
       baseUrl,
       conversationId,
       activityId,
       data: {
         type: constants.ACTIVITY_TYPE.MESSAGE,
         from: {
           id: fromId,
           name: fromName,
         },
         conversation: {
           id: conversationId,
         },
         recipient: {
           id: toId,
           name: toName,
         },
         text,
         replyToId: activityId,
       },
     });
 
+    // Validate response
+    if (!response?.id) {
+      throw new Error("Failed to send message: Invalid response from Teams API");
+    }
+
     $.export("$summary", "Successfully replied to message.");
 
     return response;
   },

Likely invalid or redundant comment.


65-65: Verify the API endpoint structure

Let's verify that the API endpoint construction follows Microsoft Teams Bot Framework requirements.

✅ Verification successful

Let me gather more specific information about the Teams Bot implementation.


Let me search specifically for the Teams Bot API endpoint documentation and usage.


Based on the gathered information, I can now provide the final response:

API endpoint structure is correctly implemented

The endpoint /conversations/${conversationId}/activities/${activityId} follows the official Microsoft Bot Framework REST API specification as documented in the linked reference (https://learn.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-connector-quickstart). The implementation matches the required structure for replying to messages in Teams.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the API endpoint structure matches Microsoft Teams documentation

# Search for any other implementations or tests using similar endpoint pattern
rg -g '!node_modules' -A 2 '/conversations/[^/]+/activities/'

# Look for any configuration files that might define the endpoint structure
fd -g '*constants*' -x cat {} \; | grep -i 'conversation\|activit'

Length of output: 3763


Script:

#!/bin/bash
# Search for Teams API related configurations and implementations
rg -g '!node_modules' -A 3 'teams.*api|microsoft.*teams.*api|bot.*framework.*api' -i

# Look for any test files related to Teams message replies
fd -g '*test*' -g '*teams*' -x cat {} \; | grep -A 5 -B 5 'reply.*message\|conversation.*activit'

# Search for any documentation files about Teams integration
fd -g 'README*' -g '*teams*' -x cat {} \;

Length of output: 26943


Script:

#!/bin/bash
# Look for Teams Bot API related files and their content
rg -g '!node_modules' -A 5 'bot-framework-rest-connector' -i

# Search for any configuration or constant files in the Teams Bot component
fd -g '*constants*' -g '*config*' -x cat {} \; -p components/microsoft_teams_bot/

# Look for any related test files
fd -t f -p components/microsoft_teams_bot/ -x cat {} \; | grep -A 5 -B 5 '/conversations/.*/activities'

Length of output: 2287

Copy link
Collaborator

@michelle0927 michelle0927 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@vunguyenhung
Copy link
Collaborator

vunguyenhung commented Dec 6, 2024

Hi @sergio-eliot-rodriguez @malexanderlim, @jcortes

The Microsoft Teams Bot - Connection Popup is missing critical information for successfully connecting the bot and execute the actions. In more details:

  1. I tried to setup a new bot on my side. During my test, I figured out that the Type of App needs to be Multi Tenant in other for Pipedream OAuth to connect
    image

After creating the bot, I need to set the bot's Messaging endpoint to a Pipedream HTTP endpoint
image

Then I need to create a new secret on the bot Azure App Registration
image

Copy the Azure Application ID and new Client Secret to Pipedream, I see the connect success message
image
Screenshot 2024-12-06 at 17 25 04

Then on my Azure Bot, I send a test message on Test Web Chat
image

Resulted in a new event on the Pipedream HTTP source
image

Use the fields in this source for the action, it failed with 403 code. Could you help checking this to identify if this is on my side or action side?
image

On another note, I think we need to have a step-by-step guide on how to setup Microsoft Teams Bot (similar to what I have done above).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
action New Action Request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ACTION] Microsoft Teams Bot - Reply to Message
3 participants