Connecting to OAuth Apps

Handle the user connection flow for apps like Google, GitHub, Slack

This guide details the programmatic steps required to connect your users (Entities) to external applications that use OAuth 2.0 for authorization (e.g., Google Workspace, GitHub, Slack, Salesforce).

This flow involves redirecting the user to the external service’s login and consent screen in their browser.

Prerequisites:

  • An Integration for the OAuth app must be configured in Composio, providing you with an integration_id. Ensure it’s set up correctly for OAuth (using Composio’s shared app or your own credentials).
  • A unique entity_id representing the user within your application.

OAuth Connection Flow

The process involves initiating the connection, redirecting the user for authorization, and then waiting for Composio to confirm the connection is active.

Step 1: Initiate the Connection

Use the initiate_connection (Python) or initiateConnection (TypeScript) method on the user’s Entity object. Provide the integration_id for the OAuth app you configured.

1from composio_openai import ComposioToolSet, App
2
3# Assumes toolset is initialized
4toolset = ComposioToolSet()
5user_id = "your_user_unique_id"
6# Get this from your Composio Integration setup
7google_integration_id = "int_google_xxxxxxxx..."
8
9entity = toolset.get_entity(id=user_id)
10
11try:
12 print(f"Initiating OAuth connection for entity {entity.id}...")
13 connection_request = toolset.initiate_connection(
14 integration_id=google_integration_id,
15 entity_id=user_id,
16 # Optionally add: redirect_url="https://yourapp.com/final-destination"
17 # if you want user sent somewhere specific *after* Composio finishes.
18 # Optional add: app=App.APP_NAME
19 )
20
21 # Check if a redirect URL was provided (expected for OAuth)
22 if connection_request.redirectUrl:
23 print(f"Received redirect URL: {connection_request.redirectUrl}")
24 else:
25 print("Error: Expected a redirectUrl for OAuth flow but didn't receive one.")
26 # Handle error: Maybe the integration is misconfigured?
27
28 # Store connection_request.connectedAccountId if needed for Step 3 polling
29 # connection_id_in_progress = connection_request.connectedAccountId
30
31except Exception as e:
32 print(f"Error initiating connection: {e}")

The key output here is the redirectUrl.

Step 2: Redirect the User

Your application must now direct the user’s browser to the redirectUrl obtained in Step 1.

  • How: This typically involves sending an HTTP 302 Redirect response from your backend, or using window.location.href = redirectUrl; in your frontend JavaScript.

The user will see the external service’s login page (if not already logged in) followed by an authorization screen asking them to grant the permissions (scopes) defined in your Composio Integration.

Step 3: Wait for Connection Activation

After the user authorizes the app, the external service redirects back (typically to Composio’s callback URL). Composio exchanges the authorization code for access/refresh tokens and securely stores them, marking the Connection as ACTIVE.

Your application needs to wait for this confirmation. Use the wait_until_active (Python) / waitUntilActive (TypeScript) method on the connection_request object obtained in Step 1.

1# Assuming 'connection_request' from Step 1
2
3print("Waiting for user authorization and connection activation...")
4try:
5 # Poll Composio until the status is ACTIVE
6 active_connection = connection_request.wait_until_active(
7 client=toolset.client, # Pass the Composio client instance
8 timeout=180 # Wait up to 3 minutes (adjust as needed)
9 )
10 print(f"Success! Connection is ACTIVE. ID: {active_connection.id}")
11 # Store active_connection.id associated with your user (entity_id)
12 # Now ready for Step 4.
13except Exception as e: # Catches TimeoutError, etc.
14 print(f"Connection did not become active within timeout or failed: {e}")
15 # Implement retry logic or inform the user

Step 4: Use the Connection

Once wait_until_active completes successfully, the Connection is ready. You can now use the entity_id or the obtained active_connection.id to execute actions on behalf of this user for the connected app.