Customizing Agentforce agents with Slack actions | Slack Developer Docs
https://docs.slack.dev/ai/customizing-agentforce-agents-with-custom-slack-actions/ • 229 KB fetched
Open original page
Customizing Agentforce agents with Slack actions | Slack Developer Docs
guide
Skip to main content
Guides Reference Samples Tools
Changelog Dev Program
MANAGE APPS
* Welcome!
* Quickstart
* Resources
*
* Slack platform concepts
* AI in Slack
* Overview
* Build agents on Slack
* Build with AI
* MCP
* Other integration methods
* Integrating AI into workflows
* Customizing Agentforce agents with Slack actions
* APIs
* App management
* App manifests
* Admin resources
* Authentication
* Block Kit
* Enterprise
* Enterprise Search for apps
* GovSlack
* Interactivity
* Messaging
* Slack Marketplace
* Surfaces
* Workflows
*
* Legacy
*
* 日本語版ページ
*
* AI in Slack
* Other integration methods
* Customizing Agentforce agents with Slack actions Copy as markdown
On this page
Customizing Agentforce agents with Slack actions
This guide will help you customize your Agentforce agent with custom Slack actions. Implementing custom Slack actions in your agent allows it to carry out certain tasks in Slack via the Slack Web API , such as sending a message to a channel or creating a canvas with content from the agent's response. To use standard Slack actions in your agent, refer to the Slack Agent Actions documentation.
Prerequisites
This guide assumes you have a connected Salesforce org and Slack org, as well as an Agentforce agent that can be modified. If you don't, use the Connect Salesforce and Slack guide and the Salesforce Create Agents guide to get set up.
Step 1: Set up your Slack app
In order to use the Slack Web API in custom actions in Agentforce, you first need to set up a way for your agents to get proper Slack credentials. You do this by creating a Slack app and using an Auth. Provider in the Salesforce Platform to manage the authentication flow between your Slack app and Salesforce users.
*
Start by logging into your Slack org and create a new app . In the Create an app modal, select From a manifest , then click Continue .
*
Highlight the contents of the placeholder JSON and replace it with this:
App manifest code
* JSON
* YAML {
"display_information" : {
"name" : "Agentforce Custom Actions"
} ,
"features" : {
"bot_user" : {
"display_name" : "Agentforce Custom Actions" ,
"always_online" : false
}
} ,
"oauth_config" : {
"scopes" : {
"bot" : [
"chat:write" ,
"chat:write.public" ,
"mpim:read" ,
"reactions:write" ,
"channels:history" ,
"canvases:write" ,
"channels:join" ,
"channels:read" ,
"team:read"
]
}
} ,
"settings" : {
"org_deploy_enabled" : true ,
"socket_mode_enabled" : false ,
"token_rotation_enabled" : false
}
}
display_information :
name : Agentforce Custom Actions
features :
bot_user :
display_name : Agentforce Custom Actions
always_online : false
oauth_config :
scopes :
bot :
- chat : write
- chat : write.public
- mpim : read
- reactions : write
- channels : history
- canvases : write
- channels : join
- channels : read
- team : read
settings :
org_deploy_enabled : true
socket_mode_enabled : false
token_rotation_enabled : false
*
Select a workspace in which to develop your app and click Next , then Create .
*
Select Install App in the sidebar. Click Install to Organization . Allow the app access to the org.
*
Select Basic Information in the sidebar. Copy down your Client ID and Client Secret; we'll use these later.
Step 2: Create an Auth Provider
To use your Slack app credentials in your agent, you need to first create an auth provider, allowing you to complete the authentication flow needed for the Salesforce Platform to get the proper credentials.
*
Log into your Salesforce org and open Setup from the gear icon in the upper right. Use the Quick Find to search for Auth. Providers , click on it, then click the New button above the list of existing providers to create a new provider. Enter the values for the fields listed below.
Field Value Provider Type Open ID Connect Name Slack URL Suffix Leave the value created by entering a Name Consumer Key Client ID of your Slack app Consumer Secret Client Secret of your Slack app Authorize Endpoint URL https://slack.com/oauth/v2/authorize Token Endpoint URL https://slack.com/api/oauth.v2.access
*
Click Save .
*
Scroll down the page and copy the Callback URL .
*
Navigate back to your Slack app settings and add the callback URL to your app in the OAuth & Permissions settings page.
* In the Redirect URLs section, click Add New Redirect URL .
* Enter the callback URL from the auth provider, then click Add .
* Click Save URLs .
Step 3: Create an External Credential
Once you have an auth provider, it’s time to set up an external credential. External credentials are the actual record of credentials for external services. This is what stores your tokens and connects them to a Principal for use in permission sets or user profiles.
*
Within your Salesforce org setup, search for and click on Named Credentials ; then within the settings click the External Credentials tab, then click the New button located above the list of external credentials. Enter the following values for the fields listed below:
Field Value Label Slack Name Slack Authentication Protocol OAuth 2.0 Authentication Flow Type Browser Flow Scope Leave blank Identity Provider Select Authentication Provider as the type and select the auth provider you created in the previous step
*
Save the external credential.
*
In the settings for the external credential you created, under Principals , click New . Enter the following values for the fields listed below:
Field Value Parameter Name Enter your Slack app name ( Agentforce Custom Actions ) Sequence Number 1 Identity Type Named Principal Scope chat:write , chat:write.public , mpim:read , reactions:write , channels:history , canvases:write , channels:join , channels:read , team:read
Note on Named Principal
We want to use a Named Principal when we want to share credentials (i.e. agent actions on the agent's behalf) and a User Principal when we want to keep credentials scoped to a user (i.e. agent takes actions on your behalf).
* Save your changes.
* Click the drop-down toggle in the Actions section for your new Principal.
* Click Authenticate to start the browser authentication flow with your Slack app. When the Slack authentication browser page opens, be sure to use the workspace picker in the header to switch to installation at the org level. Problems can occur authenticating if the browser is used to log in to any other Salesforce or Slack orgs, so it's safest to create a separate browser profile or use an incognito browser if you run into issues.
* Once you’ve switched the install destination to your org, click Allow .
* On the Salesforce auth page, click Confirm .
* You’re credentials are now configured for use!
* Now we can enable external credentials for the Einstein Agent User and System Administrator profiles.
* From Setup, in the Quick Find box, enter Profiles , then select it from the options.
* Find the Einstein Agent User profile and select it. In the Apps section, select External Credentials Principal Access .
* In the Enable External Credential Principal Access section, click Edit .
* Select the checkbox for the external credentials principal that you created.
* Save your changes.
* Repeat for the System Administrator profile.
Step 4: Create a Named Credential
Now that you have an external credential to allow proper access to your Slack app, you’ll need a Named Credential to finalize your API configuration with the proper base URL and any custom headers you may want to include. This is what will be used in Apex classes for interacting with the Slack Web API .
* Search again for Named Credentials in Salesforce Setup.
* From the Named Credentials tab, click New .
* For label enter Slack API .
* For name enter Slack_API .
* For the URL, enter https://slack.com/api .
* For external credentials, select Slack from the drop-down.
* Save your changes.
Step 5: Set up your Salesforce Platform developer environment
There are two methods of developing with Apex : using the Code Builder developer environment within the Salesforce Platform or using VSCode with the proper Salesforce extensions installed. This guide focuses on using VSCode as your developer environment.
* Install the Salesforce CLI.
* Navigate to this instruction page and install the CLI for your given environment.
* Confirm your installation by running sf --version in the terminal of your choice.
* Set up VSCode for Salesforce Platform development.
* Open VSCode and navigate to the extensions tab.
* Search for and install the following extensions:
* Salesforce Extension Pack —You can install the extended pack for Salesforce extensions which has all these packages included (and a few others that aren’t needed for this guide).
* Prettier
* ESLint
* XML
* Reload the window to activate the new extensions.
* Set up a Salesforce development project.
*
From the VSCode command palette ( Cmd/Ctrl + Shift + P ), search for SFDX:Create Project and select it from the list of options.
*
For the template type, leave Standard selected and press Enter .
*
Give your project a name like Custom Slack Actions and press Enter .
*
Choose a destination on your computer for the project and click Create Project . If you see an error about Apex not being able to find a Java runtime, then you’ll need to install OpenJDK version 21 (if not already installed) and set the path in your workspace settings. See Install JDK below.
Install JDK If you see an error about Apex not being able to find the Java runtime, follow these steps:
* Navigate to this install page and select the options for your specific OS and architecture. Then download the .dmg (for macOS) or .msi (for Windows) for the latest version for your set up.
* Install the .dmg or .msi , leaving all defaults as is.
* Open VSCode settings and search for java: home .
* For the Salesforcedx-vscode-apex › Java: Home property, enter /Library/Java/JavaVirtualMachines/zulu-21.jdk/Contents/Home for macOS or C:\Program-Files\Zulu\zulu-21\ for Windows.
* Reload the workspace ( Cmd/Ctrl + Shift + P , search for and select Developer: Reload Window ).
*
From the VSCode command palette, search for SFDX: Authorize an Org and select it from the list of options.
* Leave Project Default selected for login URL source and press Enter .
* Set an org alias like customActionsOrg or leave the default and press Enter .
* On the Salesforce login page, enter your Username and Password and click Log In .
* Allow access for the Salesforce CLI to act on your behalf by clicking Allow .
* You will get a notification in VSCode if authentication was successful.
Now that your credentials and developer environment are ready, we move on to the real fun—creating custom actions.
Step 6: Create custom Agentforce actions with Apex
Apex actions use the Invocable Method annotation syntax to define how the class can be used in platform features that support actions, like Flow and Agentforce. You'll use invocable methods that call out to the Slack API using the named credentials you created to authenticate. For this guide, you'll create two actions:
* GetSlackChannelAction (from the auth.teams.list and conversations.list methods) to look up channels by name and workspace.
* SendSlackMessageAction (from the chat.postMessage method) to allow the agent to send messages to a given channel.
Here is an example request with a named credential:
request.setEndpoint('callout:Slack_API/chat.postMessage');
Why do I need two actions to send a message?
Technically you don't. You could have one action take the channel name, the org, and the message content to complete the task. However, it's useful to think of actions as composable steps. Looking up a channel by it's name is useful in a lot of use cases so it makes sense to be it's own action! Then we can rely on the instructions in our topics to inform how the agent uses these actions together, in this case allowing users to provide channel names when sending messages, and the agent can use the get channel action to get the proper data needed to send the message in Slack.
* Create your first custom action Apex class.
* From the VSCode command palette, search for SFDX: Create Apex Class and select it from the list of options.
* Name your class GetSlackChannelAction and press Enter .
* Leave the default path for the destination and press Enter .
* Replace the contents of the file with the code shown here, then save the file.
View file code /**
* GetSlackChannelAction
*
* This class provides a Flow-invocable action to search for a Slack channel by name within a specific workspace
* in a Slack Enterprise org environment. It handles the pagination of results and provides detailed channel information.
*
* The process:
* 1. Takes a workspace name and channel name as input
* 2. Queries auth.teams.list to find the workspace ID from the name
* 3. Uses the workspace ID to search for the channel using conversations.list
* 4. Returns channel details if found
*/
public class GetSlackChannelAction {
/**
* Input class for the Flow action
* Requires both workspace name and channel name to perform the search
*/
public class ChannelSearchInput {
@InvocableVariable ( required = true description = ' Name of the channel to search for ' )
public String channel_name ;
@InvocableVariable ( required = true description = ' Name of the Slack workspace' )
public String workspace_name ;
}
/**
* Output class containing channel details or error information
* Returns basic channel information including ID, name, member count, and topic
*/
public class ChannelSearchOutput {
@InvocableVariable ( description = ' Channel ID ' )
public String channel_id ;
@InvocableVariable ( description = ' Channel Name ' )
public String channel_name ;
@InvocableVariable ( description = ' Number of members in the channel' )
public Integer num_members ;
@InvocableVariable ( description = ' Channel topic' )
public String topic ;
@InvocableVariable ( description = ' Error message if search failed' )
public String error_message ;
}
// ------------------------
// API Response Structures
// ------------------------
/**
* Response structure for auth.teams.list endpoint
* Used to find workspace/team ID from workspace name
*/
private class TeamsListResponse {
public Boolean ok ;
public List < Team > teams ;
public ResponseMetadata response_metadata ;
public String error ;
}
/**
* Structure representing a Slack workspace/team
*/
private class Team {
public String id ;
public String name ;
}
/**
* Response structure for conversations.list endpoint
* Contains list of channels and pagination metadata
*/
private class SlackResponse {
public Boolean ok ;
public List < Channel > channels ;
public ResponseMetadata response_metadata ;
public String error ;
}
/**
* Metadata structure containing pagination information
*/
private class ResponseMetadata {
public String next_cursor ;
}
/**
* Structure representing a Slack channel
* Contains only the fields we need for our output
*/
private class Channel {
public String id ;
public String name ;
public Integer num_members ;
public Topic topic ;
}
/**
* Structure representing a channel's topic
*/
private class Topic {
public String value ;
}
/**
* Main invocable method for the Flow action
* Processes a list of inputs (bulk processing support) and returns corresponding outputs
*/
@InvocableMethod ( label = ' Get Slack Channel '
description = ' Searches for a Slack channel by name in specified workspace and returns its details' )
public static List < ChannelSearchOutput > searchChannel ( List < ChannelSearchInput > inputs ) {
List < ChannelSearchOutput > outputs = new List < ChannelSearchOutput > ( ) ;
// Process each input in the list (supporting bulk operations)
for ( ChannelSearchInput input : inputs ) {
ChannelSearchOutput output = new ChannelSearchOutput ( ) ;
try {
// Step 1: Get the workspace ID from the workspace name
String teamId = getWorkspaceId ( input . workspace_name ) ;
if ( teamId == null ) {
output . error_message = ' Workspace "' + input.workspace_name + '" not found' ;
outputs . add ( output ) ;
continue ;
}
// Step 2: Search for the channel in the identified workspace
Channel foundChannel = searchAllChannels ( input . channel_name , teamId ) ;
// Step 3: Process results
if ( foundChannel != null ) {
// Channel found - populate output with channel details
output . channel_id = foundChannel . id ;
output . channel_name = foundChannel . name ;
output . num_members = foundChannel . num_members ;
if ( foundChannel . topic != null ) {
output . topic = foundChannel . topic . value ;
}
} else {
// Channel not found
output . error_message = ' Channel not found' ;
}
} catch ( Exception e ) {
// Handle any errors that occur during processing
output . error_message = ' Error : ' + e . getMessage ( ) ;
System . debug ( ' Error details : ' + e . getStackTraceString ( ) ) ;
}
outputs . add ( output ) ;
}
return outputs ;
}
/**
* Gets the workspace ID for a given workspace name using auth.teams.list
* This method handles the Enterprise org workspace lookup
*
* @param workspaceName The name of the workspace to find
* @return The workspace ID if found, null if not found
*/
private static String getWorkspaceId ( String workspaceName ) {
// Initialize HTTP request
Http http = new Http ( ) ;
HttpRequest request = new HttpRequest ( ) ;
request . setEndpoint ( 'callout : Slack_API / auth . teams . list' ) ;
request . setMethod ( 'GET' ) ;
// Make the API call
HttpResponse response = http . send ( request ) ;
// Check for successful response
if ( response . getStatusCode ( ) != 200 ) {
throw new CalloutException ( ' Teams list failed with status code : ' + response . getStatusCode ( ) ) ;
}
// Parse the response
TeamsListResponse tea
Links found on this page
- Skip to main content [direct]
- Guides [direct]
- Reference [direct]
- Samples [direct]
- Tools [direct]
- Changelog [direct]
- Dev Program [direct]
- MANAGE APPS [direct]
- Quickstart [direct]
- Resources [direct]
- Slack platform concepts [direct]
- AI in Slack [direct]
- Build agents on Slack [direct]
- Build with AI [direct]
- MCP [direct]
- Other integration methods [direct]
- Customizing Agentforce agents with Slack actions [direct]
- APIs [direct]
- App management [direct]
- App manifests [direct]
- Admin resources [direct]
- Authentication [direct]
- Block Kit [direct]
- Enterprise [direct]
- Enterprise Search for apps [direct]
- GovSlack [direct]
- Interactivity [direct]
- Messaging [direct]
- Slack Marketplace [direct]
- Surfaces [direct]
- Workflows [direct]
- Legacy [direct]
- 日本語版ページ [direct]
- Slack Web API [direct]
- Slack Agent Actions [direct]
- Connect Salesforce and Slack guide [direct]
- Create Agents [direct]
- a new app [direct]
- https://slack.com/oauth/v2/authorize [direct]
- https://slack.com/api/oauth.v2.access [direct]
- Apex [direct]
- instruction page [direct]
- install page [direct]
- annotation syntax [direct]
- auth.teams.list [direct]
- conversations.list [direct]
- chat.postMessage [direct]
- Slack Platform Connector [direct]
- here [direct]
- Slack CLI [direct]
- Bolt frameworks [direct]
- Block Kit Builder [direct]
- Code samples & tutorials [direct]
- LLM? Read llms.txt [direct]
- Learning paths [direct]
- Workshops [direct]
- Slack certifications [direct]
- Trailhead [direct]
- Resource library [direct]
- All learning resources [direct]
- Slack community [direct]
- Slack events [direct]
- Blog [direct]
- Slack marketplace [direct]
- Developer newsletter [direct]
- Status [direct]
- Privacy [direct]
- Terms [direct]
- Your Privacy Choices [direct]