How to send Slack notifications through your APEX apps - Part 2

A closer look at the Slack API

ยท

4 min read

Introduction

Continued from part 1 of this series on using incoming webhook to send Slack messages through an APEX application. This new post will focus on covering the missing features that incoming webhook cannot provide. To do this, we will use the Slack API to send messages securely.

Slack configuration

Go to https://api.slack.com/apps and edit the Slack application that was created in the first blog post.

Screenshot showing the Slack application named My APEX app

On the application management page, under Features on the left, click on OAuth & Permissions. Then scroll down to the Scopes section and add the ones shown in the screenshot below.

Screenshot showing the requiring scopes

Oracle APEX app

Create the REST Data Source

The idea here is to be able to select a channel to post our messages. To do this, you need to create a REST data source. In the first part of the wizard, enter Slack Conversations in the name field and slack.com/api/conversations.list in the Endpoint URL field.

Screenshot for first wizard step to create REST Data Source

In part 2 of the wizard, make sure you fill in the same values as the screenshot below.

Screenshot for second wizard step to create REST Data Source

In part 3, leave the default setting at No Pagination. In fact, Slack's API does support pagination, but it's a cursor-based pagination that I don't think is supported by the box. One option could be to create a Data Source REST plug-in, but that is not the purpose of this blog post.

Screenshot for part 3 wizard to create REST Data Source

In part 4 you need to set the authentication settings, for this example I used an authentication token. You can find it on the Slack app management page, in the OAuth & Permissions section. Click the Discover button when all the fields are correctly filled in.

Screenshot for part 4 wizard to create REST Data Source

The last step should show the discovery report confirming that the credentials are correct. Click the Create REST Data Source button.

Screenshot for part 5 wizard to create REST Data Source

Create the LOV

To select the channel, before posting the message, we need a pick list or better yet a drop down list. Let's create a LOV under Shared Components to do this.

In Part 1 of the LOV Creation Wizard, choose the From Scratch option and click Next.

Screenshot of the Create LOV wizard - Part 1

In Part 2 of the LOV Creation Wizard, choose a name, make sure you select the Dynamic option and click Next.

Screenshot of the Create LOV wizard - Part 2

In part 3 of the LOV creation wizard, choose the REST Data Source option, select the one we just created and click Next.

Screenshot of the Create LOV wizard - Part 3

In the LOV creation wizard, part 4, make sure your return column is ID, your display column is NAME and click Create.

Screenshot of the Create LOV wizard - Part 4

Creating the page

I'm essentially copying the page that was created in part 1 of this series and replacing the URL field with the string field. Just add a Popup LOV page element and choose our LOV under the Value List attributes.

Screenshot of the list of values attributes for the channel field

Then I updated the PL/SQL process

declare
    l_url_endpoint varchar2(100) := 'https://slack.com/api/chat.postMessage';
    l_response     clob;
    l_text         varchar2(500);
    l_obj          json_object_t;
begin
    l_text := replace(:P3_TEXT, '**'   , '*' );
    l_text := replace(l_text  , chr(10), '\n');
    l_text := replace(l_text  , chr(13), '\r');
    l_text := regexp_replace(l_text, '^```[a-z]{1,}', '```');

    apex_web_service.clear_request_headers;

    apex_web_service.set_request_headers(
        p_name_01        => 'Content-Type',
        p_value_01       => 'application/json'
    );

    l_obj := json_object_t('{}');
    l_obj.put('channel', :P3_SLACK_CHANNEL);
    l_obj.put('text'   , l_text           );
    l_obj.put('mrkdwn' , true             );

    l_response := apex_web_service.make_rest_request(
        p_url => l_url_endpoint,
        p_http_method => 'POST',
        p_body => l_obj.to_clob(),
        p_credential_static_id => 'Credentials_for_Slack'
    );

    if apex_web_service.g_status_code > 200 then
        apex_error.add_error (
            p_message          => 'Unexpected error',
            p_display_location => apex_error.c_inline_in_notification 
        );
    else
        l_obj := json_object_t(l_response);
        if l_obj.get_Boolean('ok') = false then
            apex_error.add_error (
                p_message          => 'Encountered the error: '|| l_obj.get_String('error'),
                p_display_location => apex_error.c_inline_in_notification 
            );
        end if;
    end if;
end;

Test it ๐Ÿš€

You should now be able to choose a channel and specifically post a message there. Let's try it

Screenshot showing the not_in_channel error

What, wait, it doesn't work the first time? Well, you need one more step to make it work, your bot needs to be added to the channels you want to notify. This is a one-time action, but it is necessary.

Right-click on your Slack application and click View Application Details.

Screenshot of a Slack app details

Click on Add this application to a channel, choose the channel and click on Add.

Screenshot showing how to add Slack app to a channel

Now you are ready to notify on the channel you want!

Conclusion

This blog post covers the missing part of the incoming webhook and allows you to send notifications to multiple channels without having to create a webhook for each. I hope it can be useful to someone.

I have updated the demo app on this Github repository. You will have to add your credentials to make it working.

Ressources

ย