Skip to Content
HomeBuild toolsCreate a tool with auth

Adding user authorization to your tools

Outcomes

Create a that sends a message on behalf of a via Slack.

You will Learn

  • How to add user authorization to your custom with Arcade.
  • How to use the ToolContext class to make authenticated requests to external APIs.
  • How to use the Slack to authorize your .

Prerequisites

Install Arcade and Slack SDK

Terminal
uv pip install arcade-ai slack_sdk

Define your authorized tool

Create a new Python file, e.g., slack_tools.py, and import the necessary modules:

Python
from typing import Annotated from arcade_tdk import ToolContext, tool from arcade_tdk.auth import Slack from arcade_tdk.errors import RetryableToolError from slack_sdk import WebClient

Now, define your using the @tool decorator and specify the required authorization, in this case, by using the built-in Slack :

Python
@tool( requires_auth=Slack( scopes=[ "chat:write", "im:write", "users.profile:read", "users:read", ], ) ) def send_dm_to_user( context: ToolContext, user_name: Annotated[str, "The Slack username of the person you want to message"], message: Annotated[str, "The message you want to send"], ) -> Annotated[str, "A confirmation message that the DM was sent"]: """Send a direct message to a user in Slack.""" slack_client = WebClient(token=context.authorization.token) # Retrieve the user ID based on username user_list_response = slack_client.users_list() user_id = None for user in user_list_response["members"]: if user["name"].lower() == user_name.lower(): user_id = user["id"] break if not user_id: raise RetryableToolError( "User not found", developer_message=f"User with username '{user_name}' not found." ) # Open a conversation and send the message im_response = slack_client.conversations_open(users=[user_id]) dm_channel_id = im_response["channel"]["id"] slack_client.chat_postMessage(channel=dm_channel_id, text=message) return "DM sent successfully"

Arcade offers a number of built-in auth providers, including Slack, Google, and GitHub. You can also require authorization with a custom , using the OAuth2 class, a subclass of the ToolAuthorization class:

Python
@tool( requires_auth=OAuth2( id="your-oauth-provider-id", scopes=["scope1", "scope2"], ) )

The OAuth2 class requires an id parameter to identify the in the . For built-in providers like Slack, you can skip the id. The Arcade Engine will find the right provider using your credentials. While you can specify an id for built-in providers, only do this for private that won’t be shared.

Use your authorized tool with Arcade

Now you can use your custom authorized with Arcade in your application.

Here’s an example of how to use your :

Python
from arcadepy import Arcade client = Arcade() # Automatically finds the `ARCADE_API_KEY` env variable user_id = "{arcade_user_id}" # Use the tool response = client.tools.execute( tool_name="Slack.SendDmToUser", input={ "user_name": "johndoe", "message": "Hello!", }, user_id=user_id, ) print(response.output.value)

Handle authorization

Since your requires authorization, the first time you use it, the (identified by user_id) needs to authorize access.

Arcade handles the authorization flow, prompting the to visit a URL to grant permissions.

Your application should guide the through this process.

How it works

By specifying the requires_auth parameter in the @tool decorator, you indicate that the needs authorization.

Arcade manages the OAuth flow, and provides the token in context.authorization.token when the is executed. Arcade also remembers the ’s authorization tokens, so they won’t have to go through the authorization process again until the auth expires or is revoked.

Next steps

Try adding more authorized , or explore how to handle different authorization providers and scopes.

Last updated on