Skip to content

Conversation

@Josh-XT
Copy link
Owner

@Josh-XT Josh-XT commented Jan 28, 2026

Summary

This PR adds comprehensive Slack and Microsoft Teams bot integrations following the existing Discord extension patterns.

Changes Made

New Files

Slack Integration

  • agixt/extensions/slack.py: Slack OAuth extension

    • SlackSSO class for OAuth 2.0 token management
    • sso() function for authorization code exchange
    • get_slack_user_ids() for user ID to email mapping
    • slack Extension class with 14 bot commands (send messages, list channels, etc.)
  • agixt/SlackBotManager.py: Multi-company Slack bot manager

    • CompanySlackBot class for handling Slack events via Socket Mode
    • SlackBotManager class for managing multiple bot instances per company
    • User impersonation via OAuth-linked accounts
    • Handles @mentions and direct messages

Microsoft Teams Integration

  • agixt/extensions/teams.py: Microsoft Teams OAuth extension

    • TeamsSSO class for Microsoft Identity Platform OAuth
    • sso() function for authorization code exchange
    • get_teams_user_ids() for user ID to email mapping
    • teams Extension class with 14 bot commands (list teams, send messages, etc.)
  • agixt/TeamsBotManager.py: Multi-company Teams bot manager

    • CompanyTeamsBot class using Microsoft Bot Framework
    • TeamsBotManager class for managing multiple bot instances
    • HTTP endpoint for Bot Framework webhook messages
    • User impersonation via OAuth-linked accounts

Modified Files

  • agixt/endpoints/Auth.py: Added bot invite endpoints
    • GET /v1/slack/bot-invite - Returns Slack workspace installation URL
    • GET /v1/teams/bot-invite - Returns Teams app installation information

Design Patterns

This implementation follows the exact patterns established in the Discord extension:

Component Discord Slack Teams
OAuth Extension extensions/discord.py extensions/slack.py extensions/teams.py
Bot Manager DiscordBotManager.py SlackBotManager.py TeamsBotManager.py
SSO Class DiscordSSO SlackSSO TeamsSSO
User Mapping get_discord_user_ids() get_slack_user_ids() get_teams_user_ids()
Bot Invite /v1/discord/bot-invite /v1/slack/bot-invite /v1/teams/bot-invite

Environment Variables Required

Slack

  • SLACK_CLIENT_ID - Slack OAuth client ID
  • SLACK_CLIENT_SECRET - Slack OAuth client secret
  • SLACK_BOT_TOKEN - Bot User OAuth Token
  • SLACK_APP_TOKEN - App-level token for Socket Mode
  • SLACK_SIGNING_SECRET - App signing secret (optional)

Microsoft Teams

  • TEAMS_CLIENT_ID - Azure AD application client ID
  • TEAMS_CLIENT_SECRET - Azure AD application client secret
  • TEAMS_APP_ID - Bot Framework App ID
  • TEAMS_APP_PASSWORD - Bot Framework App Password
  • TEAMS_BOT_PORT - HTTP port for Bot Framework endpoint (default: 3978)

How to Test

Slack

  1. Create a Slack app at https://api.slack.com/apps
  2. Enable Socket Mode and create an App-Level Token
  3. Add required bot scopes (app_mentions:read, chat:write, etc.)
  4. Set environment variables and start the bot manager
  5. Install the app to a workspace using the invite URL

Microsoft Teams

  1. Create an Azure AD app registration
  2. Register a bot in the Bot Framework portal
  3. Create a Teams app manifest with the bot configuration
  4. Set environment variables and start the bot manager
  5. Upload the app package to Teams admin center

Breaking Changes

None - this is a new feature addition.

Related

  • Reference: Based on existing Discord extension patterns
  • Files: DiscordBotManager.py, extensions/discord.py

This commit adds comprehensive Slack and Microsoft Teams bot integrations
following the existing Discord extension patterns:

New files:
- agixt/extensions/slack.py: Slack OAuth extension with:
  - SlackSSO class for OAuth token management
  - sso() function for authorization code exchange
  - get_slack_user_ids() for user mapping
  - slack Extension class with 14 bot commands

- agixt/SlackBotManager.py: Multi-company Slack bot manager with:
  - CompanySlackBot class for handling Slack events via Socket Mode
  - SlackBotManager class for managing multiple bot instances
  - User impersonation via OAuth-linked accounts
  - Message handling for @mentions and DMs

- agixt/extensions/teams.py: Microsoft Teams OAuth extension with:
  - TeamsSSO class for Microsoft identity platform
  - sso() function for authorization code exchange
  - get_teams_user_ids() for user mapping
  - teams Extension class with 14 bot commands

- agixt/TeamsBotManager.py: Multi-company Teams bot manager with:
  - CompanyTeamsBot class using Bot Framework
  - TeamsBotManager class for managing multiple bot instances
  - User impersonation via OAuth-linked accounts
  - HTTP endpoint for Bot Framework messages

Modified files:
- agixt/endpoints/Auth.py: Added bot invite endpoints:
  - GET /v1/slack/bot-invite for Slack workspace installation
  - GET /v1/teams/bot-invite for Teams app installation

Environment variables required:
- Slack: SLACK_CLIENT_ID, SLACK_CLIENT_SECRET, SLACK_BOT_TOKEN, SLACK_APP_TOKEN
- Teams: TEAMS_CLIENT_ID, TEAMS_CLIENT_SECRET, TEAMS_APP_ID, TEAMS_APP_PASSWORD

Reference: Based on existing Discord extension patterns (DiscordBotManager.py,
extensions/discord.py)
return web.Response(status=201)
except Exception as e:
logger.error(f"Error processing Teams activity: {e}")
return web.Response(status=500, text=str(e))

Check warning

Code scanning / CodeQL

Information exposure through an exception Medium

Stack trace information
flows to this location and may be exposed to an external user.

Copilot Autofix

AI 3 days ago

In general, to fix this kind of problem you keep detailed error information (including exception messages and stack traces) in server-side logs and return only a generic, non-sensitive error message to the client. This prevents potential attackers from learning about internal structure, file paths, or other sensitive details, while still preserving enough information for operators through logging.

For this specific case in agixt/TeamsBotManager.py, we should change the except block in _process_request so that:

  • The error is still logged using logger.error(...) as it already is.
  • The HTTP response body does not include str(e) but instead returns a generic message like "Internal server error" or similar.
  • We keep the HTTP status code as 500 to indicate failure without revealing details.

No new imports or helper methods are needed. The precise edit is around lines 372–374: replace web.Response(status=500, text=str(e)) with a web.Response that uses a constant, generic error string.

Suggested changeset 1
agixt/TeamsBotManager.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/agixt/TeamsBotManager.py b/agixt/TeamsBotManager.py
--- a/agixt/TeamsBotManager.py
+++ b/agixt/TeamsBotManager.py
@@ -371,7 +371,7 @@
             return web.Response(status=201)
         except Exception as e:
             logger.error(f"Error processing Teams activity: {e}")
-            return web.Response(status=500, text=str(e))
+            return web.Response(status=500, text="Internal server error")
 
     async def start(self, port: int = None):
         """Start the Teams bot HTTP endpoint."""
EOF
@@ -371,7 +371,7 @@
return web.Response(status=201)
except Exception as e:
logger.error(f"Error processing Teams activity: {e}")
return web.Response(status=500, text=str(e))
return web.Response(status=500, text="Internal server error")

async def start(self, port: int = None):
"""Start the Teams bot HTTP endpoint."""
Copilot is powered by AI and may make mistakes. Always verify output.
@Josh-XT Josh-XT closed this Jan 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants