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

feat(api): Add slack integration #531

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

adityaRajGit
Copy link

@adityaRajGit adityaRajGit commented Nov 11, 2024

User description

Description

This PR adds slack integration.

Fixes #124

Dependencies

Installed slackapi/bolt-js package for slack integration

Future Improvements

NA

Mentions

@rajdip-b

Screenshots of relevant screens

NA

Developer's checklist

  • My PR follows the style guidelines of this project
  • I have performed a self-check on my work

If changes are made in the code:

  • I have followed the coding guidelines
  • My changes in code generate no new warnings
  • My changes are breaking another fix/feature of the project
  • I have added test cases to show that my feature works
  • I have added relevant screenshots in my PR
  • There are no UI/UX issues

Documentation Update

  • This PR requires an update to the documentation at docs.keyshade.xyz
  • I have made the necessary updates to the documentation, or no documentation changes are required.

PR Type

Enhancement, Tests


Description

  • Implemented a new Slack integration class to handle Slack events and interactions.
  • Added unit tests to ensure the Slack integration functions correctly, including checking permitted events and required metadata.
  • Updated the integration factory to include the new Slack integration.
  • Defined a new interface for Slack integration metadata.
  • Added the @slack/bolt package to the project dependencies for Slack API interactions.

Changes walkthrough 📝

Relevant files
Enhancement
slack.integration.ts
Implement Slack integration with event emission                   

apps/api/src/integration/plugins/slack/slack.integration.ts

  • Implemented Slack integration class.
  • Defined permitted events and required metadata parameters.
  • Added method to emit events to Slack.
  • +122/-0 
    integration.factory.ts
    Add Slack integration to factory                                                 

    apps/api/src/integration/plugins/factory/integration.factory.ts

    • Integrated Slack into the integration factory.
    +3/-1     
    integration.types.ts
    Define Slack integration metadata interface                           

    apps/api/src/integration/integration.types.ts

    • Added Slack integration metadata interface.
    +6/-0     
    Tests
    slack.integration.spec.ts
    Add unit tests for Slack integration                                         

    apps/api/src/integration/plugins/slack/slack.integration.spec.ts

  • Added unit tests for Slack integration.
  • Tested permitted events and metadata parameters.
  • +30/-0   
    Dependencies
    package.json
    Add Slack Bolt package dependency                                               

    apps/api/package.json

    • Added @slack/bolt package as a dependency.
    +1/-0     
    Additional files (token-limit)
    pnpm-lock.yaml
    ...                                                                                                           

    apps/api/pnpm-lock.yaml

    ...

    +3573/-1
    pnpm-lock.yaml
    ...                                                                                                           

    pnpm-lock.yaml

    ...

    +595/-145

    💡 PR-Agent usage: Comment /help "your question" on any pull request to receive relevant information

    Copy link
    Contributor

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 PR contains tests
    🔒 Security concerns

    Token Exposure:
    The implementation accepts sensitive Slack tokens (botToken and signingSecret) as metadata. While not directly exposed, ensure these are properly encrypted at rest and in transit. Also consider implementing token rotation mechanisms.

    ⚡ Recommended focus areas for review

    Singleton Pattern Issue
    The Slack app instance is stored as a class property and reused across events. This could cause issues if multiple workspaces use different tokens. Consider creating a new app instance for each event.

    Error Handling
    The error handling could be more specific. Currently it logs and rethrows all errors without distinguishing between different types of Slack API errors that may need different handling.

    Duplicate Events
    The getPermittedEvents() method contains duplicate entries for INTEGRATION_ADDED, INTEGRATION_UPDATED, and INTEGRATION_DELETED events.

    Copy link
    Contributor

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Score
    Possible issue
    Remove duplicate entries from a set of permitted values to maintain data integrity

    Remove duplicate event types from the permitted events set to avoid redundancy and
    potential confusion.

    apps/api/src/integration/plugins/slack/slack.integration.ts [17-48]

     return new Set([
         EventType.INTEGRATION_ADDED,
         // ... other events ...
    -    EventType.INTEGRATION_ADDED,
    -    EventType.INTEGRATION_UPDATED,
    -    EventType.INTEGRATION_DELETED
    +    EventType.ENVIRONMENT_ADDED
     ])
    Suggestion importance[1-10]: 8

    Why: The suggestion correctly identifies redundant event types (INTEGRATION_ADDED, INTEGRATION_UPDATED, INTEGRATION_DELETED) that are duplicated in the Set. Removing these duplicates is important for code clarity and preventing confusion.

    8
    Possible bug
    Validate required parameters early to fail fast and prevent runtime errors

    Validate metadata parameters before using them to prevent runtime errors from
    undefined or empty values.

    apps/api/src/integration/plugins/slack/slack.integration.ts [55-58]

     async emitEvent(
         data: IntegrationEventData,
         metadata: SlackIntegrationMetadata
     ) : Promise<void> {
    +    if (!metadata.botToken || !metadata.signingSecret || !metadata.channelId) {
    +        throw new Error('Required Slack metadata parameters are missing or empty');
    +    }
    • Apply this suggestion
    Suggestion importance[1-10]: 7

    Why: Early validation of required metadata parameters would prevent potential runtime errors and provide clearer error messages, improving the robustness of the integration.

    7
    Enhancement
    Implement retry mechanism for external API calls to improve reliability

    Add error retry logic for Slack API calls to handle temporary network issues or rate
    limits.

    apps/api/src/integration/plugins/slack/slack.integration.ts [110-114]

    -await this.app.client.chat.postMessage({
    -    channel: metadata.channelId,
    -    blocks: block,
    -    text:data.title
    -});
    +const maxRetries = 3;
    +for (let i = 0; i < maxRetries; i++) {
    +    try {
    +        await this.app.client.chat.postMessage({
    +            channel: metadata.channelId,
    +            blocks: block,
    +            text: data.title
    +        });
    +        break;
    +    } catch (error) {
    +        if (i === maxRetries - 1) throw error;
    +        await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, i)));
    +    }
    +}
    • Apply this suggestion
    Suggestion importance[1-10]: 6

    Why: Adding retry logic with exponential backoff for Slack API calls would improve reliability when dealing with temporary network issues or rate limits, though the current implementation already has basic error handling.

    6
    Performance
    Initialize resources during object construction rather than lazily to improve performance and reliability

    Initialize the Slack app once in the constructor instead of creating it on every
    event emission. This avoids unnecessary object creation and potential connection
    overhead.

    apps/api/src/integration/plugins/slack/slack.integration.ts [61-67]

    -if(!this.app)
    -{
    -  this.app = new App({
    -      token: metadata.botToken,
    -      signingSecret: metadata.signingSecret
    -  })
    +constructor(metadata?: SlackIntegrationMetadata) {
    +    super(IntegrationType.SLACK);
    +    if (metadata) {
    +        this.app = new App({
    +            token: metadata.botToken,
    +            signingSecret: metadata.signingSecret
    +        });
    +    }
     }
    • Apply this suggestion
    Suggestion importance[1-10]: 4

    Why: While initializing the Slack app in constructor could improve performance by avoiding repeated checks, the current lazy initialization is actually more flexible as it allows for metadata to be provided later. The suggestion would make the integration less adaptable.

    4

    💡 Need additional feedback ? start a PR chat

    Copy link
    Member

    @rajdip-b rajdip-b left a comment

    Choose a reason for hiding this comment

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

    LGTM, I'll need to test this once. Might need some time.

    @rajdip-b
    Copy link
    Member

    The lockfile is missing and so we are getting errors in the test. can you please include the updated lockfile? Run pnpm i and commit it

    @adityaRajGit
    Copy link
    Author

    adityaRajGit commented Nov 14, 2024

    The lockfile is missing and so we are getting errors in the test. can you please include the updated lockfile? Run pnpm i and commit it

    I have added the lock file. let me know if I can help.

    @rajdip-b
    Copy link
    Member

    I think it has some conflicts. You should merge the develop branch onto your branch, remove pnpm lock, run pnpm i, and push again.

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

    Successfully merging this pull request may close these issues.

    Integration: Add Slack
    2 participants