Kafka Connect Slack

December 27, 2018
Kotlin Kafka kafka-connect

I’ve created a new kafka-connect sink plugin that allows you to send messages from a topic into a Slack channel, or directly to a Slack user. The plugin is written in Kotlin.

Below we create a connector that reads from the paid-orders topic, which contains avro-formatted messages and posts in the #shipping-requests channel.

The payload contains nested values,

{
  "id": "08b04072-09fa-11e9-8d10-7200016da930",
  "quantity": 30,
  "item": {
    "name": "Duff Beer",
    "sku": "duf002"
  },
  "customer": {
    "firstname": "Homer",
    "lastname": "Simpson",
    "address": {
      "streetaddress": "742 Evergreen Terrace",
      "city": "Springfield"
    }
  }
}
kafka-avro-console-producer \
         --broker-list localhost:9092 --topic paid-orders \
         --property value.schema='{ "name": "order", "type": "record", "fields": [ { "name": "id", "type": "string" }, { "name": "quantity", "type": "int" }, { "name": "item", "type": { "type": "record", "name": "itemdetails", "fields": [ { "name": "name", "type": "string" }, { "name": "sku", "type": "string" } ] } }, { "name": "customer", "type": { "type": "record", "name": "customer", "fields": [ { "name": "firstname", "type": "string" }, { "name": "lastname", "type": "string" }, { "name": "address", "type": { "type": "record", "name": "AddressUSRecord", "fields": [ { "name": "streetaddress", "type": "string" }, { "name": "city", "type": "string" } ] } } ] } } ] }'

Configuring the connector

connector.class=net.mongey.kafka.connect.slack.SlackSinkConnector
topics=paid-orders
slack.token=<redacted>
slack.channel=shipping-requests
message.template=":ship: :ship: :ship:\n$${quantity} $${item.name} (${item.sku})\n Order ID: (${id})\n:house_with_garden: :house_with_garden: :house_with_garden: \n${customer.firstname} ${customer.lastname}\n ${customer.address.streetaddress}\n${customer.address.city}"

The config is simple.

  • topics is the topic you want to follow
  • slack.token is the slack token for the connector to use
  • slack.channel defines what channel to send the message into. (Optional)
  • slack.username defines the user to send the message to. (Optional)
  • message.template defines the template to use for the message.

message.template

Nested fields are accessible via level1.level2.leveln interpolation using ${fieldname}

:ship: :ship: :ship:
${quantity} ${item.name} (${item.sku})
Order ID: (${id})
:house_with_garden: :house_with_garden: :house_with_garden:
${customer.firstname} ${customer.lastname}
${customer.address.streetaddress}
${customer.address.city}

becomes

slack