Introducing SDriver: a Delphi wrapper for Slack API

I am very happy to introduce you to SDriver, a new open source project I am working on since a while (formerly named SlackDriver but I noticed that name would have infringed Slack Brand Guidelines and I changed to SDriver).

It is an simple Delphi wrapper for (some of) Slack APIs.

SDriver logo

What is Slack

Slack (slack.com) is a popular communication platform that can be used to improve collaboration in teams. It provides services like instant messaging and document sharing across a group of people in public or private way.

You can freely setup your own organization (team) and create some channels (eventually assigning members to specific channels) for discussion. The official help center provides you a fair documentation of their features.

The Slack logo

Out of the box, Slack provides you a web app client (with a subdomain dedicated to your organization, mine is https://andreamagni.slack.com ) as well as native apps for the most common platforms out there (Windows, Mac OSX, Linux, Android, iOS…).

Having a way to programmatically send messages into a channel or to a specific member obviously is a very nice add on for every integrated system, just to name an advantage think about the fact the (human) members can receive realtime notifications when somebody (human or not) send a message into a channel or to the member himself.

Each member has a stateful view of the messages so one can always know those messages has been already read and those that has not (avoiding to force people to always look at the message queue).

Last but not least, Slack provides a long list of integrations with other systems and tools. Just to name one I really love, Trello has a very good integration with Slack (and viceversa).

Incoming Webhooks

Incoming webhooks are a way to interact with the Slack environment from the outside. For example, you may want to send a message into a channel or to some specific members so they get notified or have a chance to take action to respond at some event.

Using SDriver you can send messages to a Slack WebHook from your application server, your mobile app, a desktop software or some command line utility you may want to build for example to use it in a script or batch file.

Incoming WebHooks Slack app

Once you have setup the webhook in the Slack settings of your organization, a URL will be available to send data to the Slack system. This is the key configuration item you need to use SDriver to send messages from your software.

Delphi VCL app sending a message to Slack channel

Slack app on my Android phone

Message attachments

Sending a simple text message is already fine but what if you want to provide a more structured content to Slack? Message attachments are the answer to the question and SDriver provides you to define them within your message.

For example, once a order is placed on an e-commerce website, a message can be sent to a Slack group of users to notify them a new order is ready to be processed. As attachments the system can provides some details of the order (for example, the list of items ordered and their specific quantity and options), some informations about the customer (recent orders, support tickets, contact info and so on) or some internal informations (for example current availability of ordered items).

Message-Attachments on Android app

Message attachments on website

Have a look a the handy Message builder provided by Slack!

Custom slash commands

If incoming webhooks are a way to send data to Slack from the outside, you may want to cause some action from Slack to the outside world. If you are familiar with most popular messaging systems for sure you already have seen commands into chats (like “/kick <user>” and similar). Think about having a way to let a team member write a command in a channel or in his own private chat and have an effect outside of the Slack environment (like receiving an http POST on some URL of yours). That’s it!

You may want to build a Delphi REST server using any technology/library available, I will provide an example using MARS-Curiosity very soon.

A real world example

I am going to use SDriver in a real world project of one of my customers where there are several software instances running an e-commerce website, some system integration with third party software processes and a client server backend. All made with Delphi (using different technologies) so a very nice chance to test integration with Slack to ease internal communication for the company.

What’s next

In the next few weeks I plan to:

  • improve the Incoming Webhooks demo
  • add a demo to show Message Attachments
  • add a simple server implementation of a Slash command
  • wrap Message buttons
  • investigate some more API available to wrap

Stay tuned 😉

Andrea

2 thoughts on “Introducing SDriver: a Delphi wrapper for Slack API

  1. Harry says:

    Hi Andrea,

    Nice implementation you have there!
    Quetsion: not everybody has upgraded their Delphi version 6 times in 5 years, so not everybody had Berlin 10.1 🙂
    Any plans to port your package to older versions, say from XE7 upwards?

    With regards,
    Harry

  2. chalermsak says:

    Hi Andrea,

    This is procedure for file upload to slack bot.
    Added:
    – Token
    – File Name

    procedure TExecutor.InternalFileUpload(
    const AURL: string; const AMessage: IMessage;
    const AOnSuccess: TOnSuccessProc; const AOnError: TOnErrorProc);
    var
    FRequest: TNetHTTPRequestAndClient;
    LStream: TBytesStream;
    LFileStream: TMultipartFormData;
    LResponse: IHTTPResponse;
    LSuccess: Boolean;
    begin
    FRequest := TNetHTTPRequestAndClient.Create(nil);
    try
    LFileStream := TMultipartFormData.Create();
    try
    LFileStream.AddFile(‘file’, AMessage.FileName);
    LFileStream.AddField(‘channels’,AMessage.Channel);
    LFileStream.AddField(‘pretty’,’1′);
    LFileStream.AddField(‘token’, AMessage.Token);
    LFileStream.AddField(‘title’, AMessage.Text);
    LResponse := FRequest.Post(AURL, LFileStream);
    LSuccess := Assigned(LResponse) and (LResponse.StatusCode = 200);
    if LSuccess then
    begin
    if Assigned(AOnSuccess) then
    AOnSuccess(AMessage);
    end
    else begin
    if Assigned(AOnError) then
    begin
    if Assigned(LResponse) then
    AOnError(AMessage, LResponse.StatusCode, LResponse.StatusText, LResponse.ContentAsString())
    else
    AOnError(AMessage, -1, ‘Response not available’, ”);
    end;
    end;

    finally
    LFileStream.Free;
    end;
    finally
    FRequest.Free;
    end;
    end;

Leave a Reply

Your email address will not be published. Required fields are marked *