DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • How to Activate New User Accounts by Email
  • Spring Config Integration With a PCF Application: A Step-by-Step Guide
  • AOT Compilation Make Java More Power
  • Configuring Java Apps With Kubernetes ConfigMaps and Helm

Trending

  • Introduction to Retrieval Augmented Generation (RAG)
  • Useful System Table Queries in Relational Databases
  • Building a Real-Time Audio Transcription System With OpenAI’s Realtime API
  • Using Java Stream Gatherers To Improve Stateful Operations
  1. DZone
  2. Coding
  3. Frameworks
  4. Integration Between Java and Slack With Webhooks

Integration Between Java and Slack With Webhooks

I will explain how to create simple integration between Java and Slack with use of Slack Incoming Webhooks and Spring Framework.

By 
Bartłomiej Żyliński user avatar
Bartłomiej Żyliński
DZone Core CORE ·
Aug. 31, 20 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
13.2K Views

Join the DZone community and get the full member experience.

Join For Free

As you probably know, Slack is one of the most common company communicators nowadays. All possible plugins, apps, and bots, which can extend its functionalities, are a hot topic recently, especially as of now when more and more companies are forced to work remotely. Through the course of this article, I will try to show how to create a simple, yet useful, integration between Java and Slack. I will use links to Slack documentation and tutorials which provide detailed description of Slack features.

What are Slack Incoming Webhooks?

Here the answer is simple but meaningful. Webhooks are an easy (probably the easiest) way to post messages from custom apps to Slack users and channels. They use JSON as messages data format, and they also allow us to use the standard Slack formatting and layout blocks.

To use them, you have to create a Slack app. I did not manage to find a properly descriptive tutorial.

I recommend to open this link https://api.slack.com/apps and click the big green button Create an App. In a new modal, you will have to choose the name and workspace for the app. After creating the app, you have to enable Incoming Webhooks. On the bottom of the screen, with Webhooks enabling checkbox, you will see a button Add New Webhook to Workspace, which will allow you to get the Webhook of a particular channel. Now you have to copy the last part of a new Webhook. 

In the example below the part, which should be copied is marked in red:

https://hooks.slack.com/servic/T016M7S1PK4/B0187LJ9FFZ/Nw1hTMVJldSQQaXfpFYf2Y2e

If you have any troubles with configuring app Webhooks or simply want to know more about them, I recommend you to read this article. The article comes from official Slack documentation and concerns sending messages with Webhooks.

Before we start – a quick disclaimer.

I know that the code quality and design of provided examples can be considered questionable. Please remember that it is a more PoC  rather than something that is ready for production.

Let’s create our app step by step

Step 1

We will need a new spring boot project as a base. I chose Spring Boot as it provides plenty of configurations out of the box and has a number of modules which allow us to set up our app faster and add new features to it later on. It is also a very well integrated with IntelliJ. If you do not have IntelliJ installed I recommend to use Spring Initializr. We will need only one artifact, namely, Spring Web so project configuration should not be hard for anyone.

Step 2

After the previous step, we have a fully functioning Spring Boot app. Now, it is time to add something useful there. We start with creating a POJO named Message which will represent our message from the HTTP request. 

Then, we create a simple REST controller called MessageInterceptorController.

We will also create a service called MessageSender, which we will further inject into the controller. A code after this step should be more or less like this:

Java
 




xxxxxxxxxx
1
11


 
1
//imports
2
3
@RestController
4
public class MessageInterceptorController {
5
  
6
    private final MessageSender messageSender;
7
  
8
    public MessageInterceptorController(MessageSender messageSender) {
9
        this.messageSender = messageSender;
10
    }
11
}



Java
 




xxxxxxxxxx
1


 
1
//imports
2
3
@Service
4
public class MessageSender {
5
6
}



Java
 




xxxxxxxxxx
1


 
1
public class Message {
2
  
3
    private String text;
4
  
5
    public String getText() {
6
        return text;
7
    }
8
}


Step 3

Now, when we have the base of our middleware, we will add some functionalities. In the controller, we add a single endpoint with @PostMapping and path /messages/{userName} . The endpoint will get the value of variable userName with usage of @PathVariable and our message with help of @RequestBody. 

Both values will be further used to call newly created method sendMessage in MessageSender, which will be the most vital method of this app. After this step our code should be similar to the one from below. I did not paste the content of Message class because it remains unchanged from the previous step.

Java
 




xxxxxxxxxx
1
16


 
1
//imports
2
3
@RestController
4
public class MessageInterceptorController {
5
  
6
    private final MessageSender messageSender;
7
  
8
    public MessageInterceptorController(MessageSender messageSender) {
9
        this.messageSender = messageSender;
10
    }
11
  
12
    @PostMapping(path = "/messages/{userName}", consumes=MediaType.APPLICATION_JSON_VALUE)
13
    public void sendMessage(@PathVariable String userName, @RequestBody Message message) {
14
        messageSender.sendMessage(userName, message);
15
   }
16
}



Java
 




xxxxxxxxxx
1


 
1
//imports
2
3
@Service
4
public class MessageSender {
5
  
6
    public void sendMessage(String userName, Message message) {
7
    
8
    }
9
}



Step 4

In this step, we will add a Map, which will store the relation between a user name and the particular user channel Webhook, so the user name will be Map key and the channel Webhook will we Map value. We will also add a constant field which will store a common part of Webhooks URL. Your code after this step should be similar to the one below. Of course your user name and channel Webhook should be different then my.

Java
 




xxxxxxxxxx
1
14


 
1
//imports
2
3
@Service
4
public class MessageSender {
5
6
    private static final String HOOKS_URL = "https://hooks.slack.com/services/%s";
7
8
    private static final Map<String, String> USER_TO_CHANNEL_WEBHOOK =
9
            Map.of("Pask", "T016M7S1PK4/B0187LJ9FF/Nw1hTMVJldSQQaXfpFYf2Y2e");
10
11
    public void sendMessage(String userName, Message message) {
12
    
13
    }
14
}



Step 5

Here, we will implement sendMessage itself. Firstly, we will get the channel Webhook from our Map and create a full Webhook URL with it. Secondly we instantiate RestTemplate which will be our HTTP client. Thirdly we have to create JSON from our message. We will do it using ObjectMapper . The next thing to create HTTP Header for ContentType with value aplication/json . Then we create HttpEntity of type String and use it to call exchange method from RestTemplate which will send our request to the Slack.

Java
 




xxxxxxxxxx
1
26


 
1
//imports
2
3
@Service
4
public class MessageSender {
5
6
    private static final String HOOKS_URL = "https://hooks.slack.com/services/%s";
7
8
    private static final Map<String, String> USER_TO_CHANNEL_WEBHOOK =
9
            Map.of("Pask", "T016M7S1PK4/B0187LJ9FFZ/Nw1hTMVJldSQQaXfpFYf2Y2e");
10
11
    public void sendMessage(String userName, Message message) throws JsonProcessingException {
12
        String userChannelId = USER_TO_CHANNEL_WEBHOOK.get(userName);
13
        String userWebhookUrl = String.format(HOOKS_URL, userChannelId);
14
        RestTemplate restTemplate = new RestTemplate();
15
16
        HttpHeaders headers = new HttpHeaders();
17
        headers.setContentType(MediaType.APPLICATION_JSON);
18
      
19
        ObjectMapper objectMapper = new ObjectMapper();
20
        String messageJson = objectMapper.writeValueAsString(message);
21
      
22
        HttpEntity<String> entity = new HttpEntity<>(messageJson, headers);
23
      
24
        restTemplate.exchange(userWebhookUrl, HttpMethod.POST, entity, String.class);
25
    }
26
}



Java
 




xxxxxxxxxx
1
16


 
1
//imports
2
3
@RestController
4
public class MessageInterceptorController {
5
  
6
    private final MessageSender messageSender;
7
  
8
    public MessageInterceptorController(MessageSender messageSender) {
9
        this.messageSender = messageSender;
10
    }
11
  
12
    @PostMapping(path = "/messages/{userName}", consumes=MediaType.APPLICATION_JSON_VALUE)
13
    public void sendMessage(@PathVariable String userName, @RequestBody Message message) throws JsonProcessingException {
14
        messageSender.sendMessage(userName, message);
15
   }
16
}


Step 6

With the main functionality done, it is time for short refactor. We will focus on improving exception handling. We will also change our endpoint to return ResponseEntity object with the correct HTTP code depending on how the request will be processed.

Java
 




xxxxxxxxxx
1
11


 
1
//imports
2
3
@PostMapping(path = "/messages/{userName}", consumes = MediaType.APPLICATION_JSON_VALUE)
4
public ResponseEntity<String> sendMessage(@PathVariable String userName, @RequestBody Message message) {
5
        try {
6
            messageSender.sendMessage(userName, message);
7
            return ResponseEntity.ok().build();
8
        } catch (JsonProcessingException e) {
9
            return ResponseEntity.badRequest().build();
10
        }
11
    }



Et voila - integration done


Tests

For such simple tests, I recommend curl, but it can be also done with Postman, depending on which one you prefer. I will try to describe an example for both of them.

I will start with curl.

Here the only thing that you need is one line of script from below

Shell
 




xxxxxxxxxx
1


 
1
curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello Slack from Dzone with curl !"}' http://localhost:8080/messages/Pask



In Postman you have to choose POST as request method then copy this URL: http://localhost:8080/messages/Pask into proper field. You also have to specify the body content type with value JSON. To do so, you have to copy this string into the body tab located below URL field. As you can see i provided a screen-shot with the Postman configuration.

GET request in Postman


The last thing to do is to click the Send button. You should get a desired message on a selected Slack channel.

Notifier in Slack

Now our integration has been tested.


Ideas How To Make It Better

1. As for now the list of channels’ Webhooks is static and requires a new deployment to update. Here it is the first place to make our middleware better. For example we can use the properties file, a simple text file or even a database. H2 will be extremely useful here (remember to encode Webhooks).

2. Add an endpoint for sending a message to many users from one request

3. Put the common part of Webhook URL in Spring Boot application.properties file


Summing up

That is all for today. Thanks for your time. I hope that you find this example useful and it will give you some new ideas on how to make Slack integrations.

Webhook Slack (software) Java (programming language) Spring Framework Integration app Spring Boot

Opinions expressed by DZone contributors are their own.

Related

  • How to Activate New User Accounts by Email
  • Spring Config Integration With a PCF Application: A Step-by-Step Guide
  • AOT Compilation Make Java More Power
  • Configuring Java Apps With Kubernetes ConfigMaps and Helm

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!