This is an automated email from the ASF dual-hosted git repository.

oalsafi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new 9777663  CAMEL-16255 Use of the slack-api-model to create rich content 
(#5121)
9777663 is described below

commit 9777663454178f86b03ccad6b6f1d3134e767376
Author: Anthony Defraine <r...@kinae.eu>
AuthorDate: Wed Mar 3 16:35:31 2021 +0100

    CAMEL-16255 Use of the slack-api-model to create rich content (#5121)
    
    * CAMEL-16255 Use of the slack-api-model to create rich content
    
    * Use slack-api-client to create rich content and keep backward 
compatibility with the legacy webhookUrl
    
    * Use constant for the conversations.list limit
    Missing CustomSlackHttpClient for the SlackConsumer
    
    * Remove since tag in documentation
---
 .../apache/camel/catalog/docs/slack-component.adoc |  54 +++++-
 components/camel-slack/pom.xml                     |  16 ++
 .../component/slack/SlackComponentConfigurer.java  |   3 +
 .../component/slack/SlackEndpointConfigurer.java   |  12 ++
 .../component/slack/SlackEndpointUriFactory.java   |   4 +-
 .../org/apache/camel/component/slack/slack.json    |   5 +-
 .../camel-slack/src/main/docs/slack-component.adoc |  52 +++++-
 .../component/slack/CustomSlackHttpClient.java     |  46 +++++
 .../camel/component/slack/SlackComponent.java      |  14 ++
 .../slack/SlackComponentVerifierExtension.java     |  84 +++------
 .../camel/component/slack/SlackConstants.java      |   1 +
 .../camel/component/slack/SlackConsumer.java       | 179 +++++++-----------
 .../camel/component/slack/SlackEndpoint.java       |  35 +++-
 .../camel/component/slack/SlackProducer.java       | 203 ++++++++++-----------
 .../camel/component/slack/utils/SlackUtils.java    |  53 ------
 .../camel/component/slack/SlackProducerTest.java   |  27 ++-
 .../dsl/SlackComponentBuilderFactory.java          |  15 ++
 .../endpoint/dsl/SlackEndpointBuilderFactory.java  | 131 +++++++++++--
 .../modules/ROOT/pages/slack-component.adoc        |  54 +++++-
 parent/pom.xml                                     |   1 +
 20 files changed, 615 insertions(+), 374 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/slack-component.adoc
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/slack-component.adoc
index f37ef4d..5363145 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/slack-component.adoc
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/slack-component.adoc
@@ -44,7 +44,7 @@ To send a direct message to a slackuser.
 
 [source,java]
 -------------------------
-slack:@username[?options]
+slack:@userID[?options]
 -------------------------
 
 == Options
@@ -52,7 +52,7 @@ slack:@username[?options]
 
 
 // component options: START
-The Slack component supports 4 options, which are listed below.
+The Slack component supports 5 options, which are listed below.
 
 
 
@@ -62,6 +62,7 @@ The Slack component supports 4 options, which are listed 
below.
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions occurred while the 
consumer is trying to pickup incoming messages, or the likes, will now be 
processed as a message and handled by the routing Error Handler. By default the 
consumer will use the org.apache.camel.spi.ExceptionHandler to deal with 
exceptions, that will be logged at WARN or ERROR level and ignored. | false | 
boolean
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy 
(on the first message). By starting lazy you can use this to allow CamelContext 
and routes to startup in situations where a producer may otherwise fail during 
starting and cause the route to fail being started. By deferring this startup 
to be lazy then the startup failure can be handled during routing messages via 
Camel's routing error handlers. Beware that when the first message is processed 
then creating and [...]
 | *autowiredEnabled* (advanced) | Whether autowiring is enabled. This is used 
for automatic autowiring options (the option must be marked as autowired) by 
looking up in the registry to find if there is a single instance of matching 
type, which then gets configured on the component. This can be used for 
automatic configuring JDBC data sources, JMS connection factories, AWS Clients, 
etc. | true | boolean
+| *token* (token) | The token to use |  | String
 | *webhookUrl* (webhook) | The incoming webhook URL |  | String
 |===
 // component options: END
@@ -88,17 +89,19 @@ with the following path and query parameters:
 |===
 
 
-=== Query Parameters (27 parameters):
+=== Query Parameters (29 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
+| *token* (common) | The token to use |  | String
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions occurred while the 
consumer is trying to pickup incoming messages, or the likes, will now be 
processed as a message and handled by the routing Error Handler. By default the 
consumer will use the org.apache.camel.spi.ExceptionHandler to deal with 
exceptions, that will be logged at WARN or ERROR level and ignored. | false | 
boolean
+| *conversationType* (consumer) | Type of conversation. There are 4 enums and 
the value can be one of: PUBLIC_CHANNEL, PRIVATE_CHANNEL, MPIM, IM | 
PUBLIC_CHANNEL | ConversationType
 | *maxResults* (consumer) | The Max Result for the poll | 10 | String
+| *naturalOrder* (consumer) | Create exchanges in natural order (oldest to 
newest) or not | false | boolean
 | *sendEmptyMessageWhenIdle* (consumer) | If the polling consumer did not poll 
any files, you can enable this option to send an empty message (no body) 
instead. | false | boolean
 | *serverUrl* (consumer) | The Server URL of the Slack instance | 
https://slack.com | String
-| *token* (consumer) | The token to use |  | String
 | *exceptionHandler* (consumer) | To let the consumer use a custom 
ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this 
option is not in use. By default the consumer will deal with exceptions, that 
will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer 
creates an exchange. There are 3 enums and the value can be one of: InOnly, 
InOut, InOptionalOut |  | ExchangePattern
 | *pollStrategy* (consumer) | A pluggable 
org.apache.camel.PollingConsumerPollingStrategy allowing you to provide your 
custom implementation to control error handling usually occurred during the 
poll operation before an Exchange have been created and being routed in Camel. 
|  | PollingConsumerPollStrategy
@@ -129,13 +132,14 @@ with the following path and query parameters:
 == SlackComponent
 
 The SlackComponent with XML must be configured as a Spring or Blueprint
-bean that contains the incoming webhook url for the integration as a
+bean that contains the incoming webhook url or the app token for the 
integration as a
 parameter.
 
 [source,xml]
 
-----------------------------------------------------------------------------------------------------------------------
 <bean id="slack" class="org.apache.camel.component.slack.SlackComponent">
     <property name="webhookUrl" 
value="https://hooks.slack.com/services/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"/>
+    <property name="token" 
value="xoxb-12345678901-1234567890123-xxxxxxxxxxxxxxxxxxxxxxxx"/>
 </bean>
 
-----------------------------------------------------------------------------------------------------------------------
 
@@ -164,6 +168,35 @@ A CamelContext with Blueprint could be as:
 </blueprint>
 
---------------------------------------------------------------------------------------------------------------------------
 
+== Producer
+
+*Since Camel 3.9.0* +
+ You can now use a token to send a message instead of WebhookUrl
+
+[source,java]
+---------------------------------------------------------------------------------------------------------------------------
+from("direct:test")
+    .to("slack:#random?token=RAW(<YOUR_TOKEN>)");
+---------------------------------------------------------------------------------------------------------------------------
+
+ You can now use the Slack API model to create blocks. You can read more about 
it here https://api.slack.com/block-kit
+
+[source,java]
+---------------------------------------------------------------------------------------------------------------------------
+    public void testSlackAPIModelMessage() {
+        Message message = new Message();
+        message.setBlocks(Collections.singletonList(SectionBlock
+                .builder()
+                .text(MarkdownTextObject
+                        .builder()
+                        .text("*Hello from Camel!*")
+                        .build())
+                .build()));
+
+        template.sendBody(test, message);
+    }
+---------------------------------------------------------------------------------------------------------------------------
+
 == Consumer
 
 You can use also a consumer for messages in channel
@@ -180,6 +213,15 @@ You'll need to create a Slack app and use it on your 
workspace.
 
 Use the 'Bot User OAuth Access Token' as token for the consumer endpoint.
 
-IMPORTANT: Add the `channels:history` and `channels:read` user token scope to 
your app to grant it permission to view messages in the user's public channels.
+IMPORTANT: Add the corresponding history (`channels:history` or 
`groups:history` or `mpim:history` or `im:history`) and
+read (`channels:read` or `groups:read` or `mpim:read` or `im:read`) user token 
scope to your app to grant it permission to
+view messages in the corresponding channel. You will need to use the 
conversationType option to set it up too (`PUBLIC_CHANNEL`, `PRIVATE_CHANNEL`, 
`MPIM`, `IM`)
+
+*Since Camel 3.9.0* +
+ The naturalOrder option allows consuming messages from the oldest to the 
newest.
+Originally you would get the newest first and consume backward (message 3 => 
message 2 => message 1)
+
+IMPORTANT: You can use the conversationType option to read history and 
messages from a channel that is not only public
+(`PUBLIC_CHANNEL`,`PRIVATE_CHANNEL`, `MPIM`, `IM`)
 
 include::camel-spring-boot::page$slack-starter.adoc[]
diff --git a/components/camel-slack/pom.xml b/components/camel-slack/pom.xml
index ff00ff7..7393360 100644
--- a/components/camel-slack/pom.xml
+++ b/components/camel-slack/pom.xml
@@ -47,6 +47,22 @@
         </dependency>
 
         <dependency>
+            <groupId>com.slack.api</groupId>
+            <artifactId>slack-api-client</artifactId>
+            <version>${slack-api-model-version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.code.gson</groupId>
+                    <artifactId>gson</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>${gson-version}</version>
+        </dependency>
+        <dependency>
             <groupId>com.googlecode.json-simple</groupId>
             <artifactId>json-simple</artifactId>
             <version>${json-simple-version}</version>
diff --git 
a/components/camel-slack/src/generated/java/org/apache/camel/component/slack/SlackComponentConfigurer.java
 
b/components/camel-slack/src/generated/java/org/apache/camel/component/slack/SlackComponentConfigurer.java
index 84b6429..3889b64 100644
--- 
a/components/camel-slack/src/generated/java/org/apache/camel/component/slack/SlackComponentConfigurer.java
+++ 
b/components/camel-slack/src/generated/java/org/apache/camel/component/slack/SlackComponentConfigurer.java
@@ -27,6 +27,7 @@ public class SlackComponentConfigurer extends 
PropertyConfigurerSupport implemen
         case "bridgeErrorHandler": 
target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); 
return true;
         case "lazystartproducer":
         case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
+        case "token": target.setToken(property(camelContext, 
java.lang.String.class, value)); return true;
         case "webhookurl":
         case "webhookUrl": target.setWebhookUrl(property(camelContext, 
java.lang.String.class, value)); return true;
         default: return false;
@@ -42,6 +43,7 @@ public class SlackComponentConfigurer extends 
PropertyConfigurerSupport implemen
         case "bridgeErrorHandler": return boolean.class;
         case "lazystartproducer":
         case "lazyStartProducer": return boolean.class;
+        case "token": return java.lang.String.class;
         case "webhookurl":
         case "webhookUrl": return java.lang.String.class;
         default: return null;
@@ -58,6 +60,7 @@ public class SlackComponentConfigurer extends 
PropertyConfigurerSupport implemen
         case "bridgeErrorHandler": return target.isBridgeErrorHandler();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
+        case "token": return target.getToken();
         case "webhookurl":
         case "webhookUrl": return target.getWebhookUrl();
         default: return null;
diff --git 
a/components/camel-slack/src/generated/java/org/apache/camel/component/slack/SlackEndpointConfigurer.java
 
b/components/camel-slack/src/generated/java/org/apache/camel/component/slack/SlackEndpointConfigurer.java
index e61ba22..64b78d4 100644
--- 
a/components/camel-slack/src/generated/java/org/apache/camel/component/slack/SlackEndpointConfigurer.java
+++ 
b/components/camel-slack/src/generated/java/org/apache/camel/component/slack/SlackEndpointConfigurer.java
@@ -29,6 +29,8 @@ public class SlackEndpointConfigurer extends 
PropertyConfigurerSupport implement
         case "backoffMultiplier": 
target.setBackoffMultiplier(property(camelContext, int.class, value)); return 
true;
         case "bridgeerrorhandler":
         case "bridgeErrorHandler": 
target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); 
return true;
+        case "conversationtype":
+        case "conversationType": 
target.setConversationType(property(camelContext, 
com.slack.api.model.ConversationType.class, value)); return true;
         case "delay": target.setDelay(property(camelContext, long.class, 
value)); return true;
         case "exceptionhandler":
         case "exceptionHandler": 
target.setExceptionHandler(property(camelContext, 
org.apache.camel.spi.ExceptionHandler.class, value)); return true;
@@ -45,6 +47,8 @@ public class SlackEndpointConfigurer extends 
PropertyConfigurerSupport implement
         case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
         case "maxresults":
         case "maxResults": target.setMaxResults(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "naturalorder":
+        case "naturalOrder": target.setNaturalOrder(property(camelContext, 
boolean.class, value)); return true;
         case "pollstrategy":
         case "pollStrategy": target.setPollStrategy(property(camelContext, 
org.apache.camel.spi.PollingConsumerPollStrategy.class, value)); return true;
         case "repeatcount":
@@ -85,6 +89,8 @@ public class SlackEndpointConfigurer extends 
PropertyConfigurerSupport implement
         case "backoffMultiplier": return int.class;
         case "bridgeerrorhandler":
         case "bridgeErrorHandler": return boolean.class;
+        case "conversationtype":
+        case "conversationType": return 
com.slack.api.model.ConversationType.class;
         case "delay": return long.class;
         case "exceptionhandler":
         case "exceptionHandler": return 
org.apache.camel.spi.ExceptionHandler.class;
@@ -101,6 +107,8 @@ public class SlackEndpointConfigurer extends 
PropertyConfigurerSupport implement
         case "lazyStartProducer": return boolean.class;
         case "maxresults":
         case "maxResults": return java.lang.String.class;
+        case "naturalorder":
+        case "naturalOrder": return boolean.class;
         case "pollstrategy":
         case "pollStrategy": return 
org.apache.camel.spi.PollingConsumerPollStrategy.class;
         case "repeatcount":
@@ -142,6 +150,8 @@ public class SlackEndpointConfigurer extends 
PropertyConfigurerSupport implement
         case "backoffMultiplier": return target.getBackoffMultiplier();
         case "bridgeerrorhandler":
         case "bridgeErrorHandler": return target.isBridgeErrorHandler();
+        case "conversationtype":
+        case "conversationType": return target.getConversationType();
         case "delay": return target.getDelay();
         case "exceptionhandler":
         case "exceptionHandler": return target.getExceptionHandler();
@@ -158,6 +168,8 @@ public class SlackEndpointConfigurer extends 
PropertyConfigurerSupport implement
         case "lazyStartProducer": return target.isLazyStartProducer();
         case "maxresults":
         case "maxResults": return target.getMaxResults();
+        case "naturalorder":
+        case "naturalOrder": return target.isNaturalOrder();
         case "pollstrategy":
         case "pollStrategy": return target.getPollStrategy();
         case "repeatcount":
diff --git 
a/components/camel-slack/src/generated/java/org/apache/camel/component/slack/SlackEndpointUriFactory.java
 
b/components/camel-slack/src/generated/java/org/apache/camel/component/slack/SlackEndpointUriFactory.java
index 207be9e..88b2c77 100644
--- 
a/components/camel-slack/src/generated/java/org/apache/camel/component/slack/SlackEndpointUriFactory.java
+++ 
b/components/camel-slack/src/generated/java/org/apache/camel/component/slack/SlackEndpointUriFactory.java
@@ -20,8 +20,9 @@ public class SlackEndpointUriFactory extends 
org.apache.camel.support.component.
     private static final Set<String> PROPERTY_NAMES;
     private static final Set<String> SECRET_PROPERTY_NAMES;
     static {
-        Set<String> props = new HashSet<>(28);
+        Set<String> props = new HashSet<>(30);
         props.add("backoffMultiplier");
+        props.add("naturalOrder");
         props.add("channel");
         props.add("initialDelay");
         props.add("scheduler");
@@ -43,6 +44,7 @@ public class SlackEndpointUriFactory extends 
org.apache.camel.support.component.
         props.add("webhookUrl");
         props.add("backoffIdleThreshold");
         props.add("token");
+        props.add("conversationType");
         props.add("lazyStartProducer");
         props.add("delay");
         props.add("pollStrategy");
diff --git 
a/components/camel-slack/src/generated/resources/org/apache/camel/component/slack/slack.json
 
b/components/camel-slack/src/generated/resources/org/apache/camel/component/slack/slack.json
index 7c4befa..c288126 100644
--- 
a/components/camel-slack/src/generated/resources/org/apache/camel/component/slack/slack.json
+++ 
b/components/camel-slack/src/generated/resources/org/apache/camel/component/slack/slack.json
@@ -25,15 +25,18 @@
     "bridgeErrorHandler": { "kind": "property", "displayName": "Bridge Error 
Handler", "group": "consumer", "label": "consumer", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Allows for bridging the 
consumer to the Camel routing Error Handler, which mean any exceptions occurred 
while the consumer is trying to pickup incoming messages, or the likes, will 
now be processed as a me [...]
     "lazyStartProducer": { "kind": "property", "displayName": "Lazy Start 
Producer", "group": "producer", "label": "producer", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Whether the producer 
should be started lazy (on the first message). By starting lazy you can use 
this to allow CamelContext and routes to startup in situations where a producer 
may otherwise fail during star [...]
     "autowiredEnabled": { "kind": "property", "displayName": "Autowired 
Enabled", "group": "advanced", "label": "advanced", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": true, "description": "Whether autowiring is 
enabled. This is used for automatic autowiring options (the option must be 
marked as autowired) by looking up in the registry to find if there is a single 
instance of matching type, which t [...]
+    "token": { "kind": "property", "displayName": "Token", "group": "token", 
"label": "token", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The token to use" },
     "webhookUrl": { "kind": "property", "displayName": "Webhook Url", "group": 
"webhook", "label": "webhook", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "The incoming webhook URL" }
   },
   "properties": {
     "channel": { "kind": "path", "displayName": "Channel", "group": "common", 
"label": "", "required": true, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "description": "The channel name (syntax #name) or 
slackuser (syntax userName) to send a message directly to an user." },
+    "token": { "kind": "parameter", "displayName": "Token", "group": "common", 
"label": "", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": true, 
"description": "The token to use" },
     "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error 
Handler", "group": "consumer", "label": "consumer", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": false, "description": "Allows for bridging the 
consumer to the Camel routing Error Handler, which mean any exceptions occurred 
while the consumer is trying to pickup incoming messages, or the likes, will 
now be processed as a m [...]
+    "conversationType": { "kind": "parameter", "displayName": "Conversation 
Type", "group": "consumer", "label": "consumer", "required": false, "type": 
"object", "javaType": "com.slack.api.model.ConversationType", "enum": [ 
"PUBLIC_CHANNEL", "PRIVATE_CHANNEL", "MPIM", "IM" ], "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "PUBLIC_CHANNEL", 
"description": "Type of conversation" },
     "maxResults": { "kind": "parameter", "displayName": "Max Results", 
"group": "consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "10", "description": "The Max Result for the 
poll" },
+    "naturalOrder": { "kind": "parameter", "displayName": "Natural Order", 
"group": "consumer", "label": "consumer", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": false, "description": "Create exchanges in natural order 
(oldest to newest) or not" },
     "sendEmptyMessageWhenIdle": { "kind": "parameter", "displayName": "Send 
Empty Message When Idle", "group": "consumer", "label": "consumer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": "If 
the polling consumer did not poll any files, you can enable this option to send 
an empty message (no body) instead." },
     "serverUrl": { "kind": "parameter", "displayName": "Server Url", "group": 
"consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": false, "defaultValue": "https:\/\/slack.com", "description": "The 
Server URL of the Slack instance" },
-    "token": { "kind": "parameter", "displayName": "Token", "group": 
"consumer", "label": "consumer", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The token to use" },
     "exceptionHandler": { "kind": "parameter", "displayName": "Exception 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By default the 
con [...]
     "exchangePattern": { "kind": "parameter", "displayName": "Exchange 
Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", 
"InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, 
"description": "Sets the exchange pattern when the consumer creates an 
exchange." },
     "pollStrategy": { "kind": "parameter", "displayName": "Poll Strategy", 
"group": "consumer (advanced)", "label": "consumer,advanced", "required": 
false, "type": "object", "javaType": 
"org.apache.camel.spi.PollingConsumerPollStrategy", "deprecated": false, 
"autowired": false, "secret": false, "description": "A pluggable 
org.apache.camel.PollingConsumerPollingStrategy allowing you to provide your 
custom implementation to control error handling usually occurred during the 
poll operation  [...]
diff --git a/components/camel-slack/src/main/docs/slack-component.adoc 
b/components/camel-slack/src/main/docs/slack-component.adoc
index f37ef4d..be1060a 100644
--- a/components/camel-slack/src/main/docs/slack-component.adoc
+++ b/components/camel-slack/src/main/docs/slack-component.adoc
@@ -44,7 +44,7 @@ To send a direct message to a slackuser.
 
 [source,java]
 -------------------------
-slack:@username[?options]
+slack:@userID[?options]
 -------------------------
 
 == Options
@@ -52,7 +52,7 @@ slack:@username[?options]
 
 
 // component options: START
-The Slack component supports 4 options, which are listed below.
+The Slack component supports 5 options, which are listed below.
 
 
 
@@ -62,6 +62,7 @@ The Slack component supports 4 options, which are listed 
below.
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions occurred while the 
consumer is trying to pickup incoming messages, or the likes, will now be 
processed as a message and handled by the routing Error Handler. By default the 
consumer will use the org.apache.camel.spi.ExceptionHandler to deal with 
exceptions, that will be logged at WARN or ERROR level and ignored. | false | 
boolean
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy 
(on the first message). By starting lazy you can use this to allow CamelContext 
and routes to startup in situations where a producer may otherwise fail during 
starting and cause the route to fail being started. By deferring this startup 
to be lazy then the startup failure can be handled during routing messages via 
Camel's routing error handlers. Beware that when the first message is processed 
then creating and [...]
 | *autowiredEnabled* (advanced) | Whether autowiring is enabled. This is used 
for automatic autowiring options (the option must be marked as autowired) by 
looking up in the registry to find if there is a single instance of matching 
type, which then gets configured on the component. This can be used for 
automatic configuring JDBC data sources, JMS connection factories, AWS Clients, 
etc. | true | boolean
+| *token* (token) | The token to use |  | String
 | *webhookUrl* (webhook) | The incoming webhook URL |  | String
 |===
 // component options: END
@@ -88,17 +89,19 @@ with the following path and query parameters:
 |===
 
 
-=== Query Parameters (27 parameters):
+=== Query Parameters (29 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
+| *token* (common) | The token to use |  | String
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions occurred while the 
consumer is trying to pickup incoming messages, or the likes, will now be 
processed as a message and handled by the routing Error Handler. By default the 
consumer will use the org.apache.camel.spi.ExceptionHandler to deal with 
exceptions, that will be logged at WARN or ERROR level and ignored. | false | 
boolean
+| *conversationType* (consumer) | Type of conversation. There are 4 enums and 
the value can be one of: PUBLIC_CHANNEL, PRIVATE_CHANNEL, MPIM, IM | 
PUBLIC_CHANNEL | ConversationType
 | *maxResults* (consumer) | The Max Result for the poll | 10 | String
+| *naturalOrder* (consumer) | Create exchanges in natural order (oldest to 
newest) or not | false | boolean
 | *sendEmptyMessageWhenIdle* (consumer) | If the polling consumer did not poll 
any files, you can enable this option to send an empty message (no body) 
instead. | false | boolean
 | *serverUrl* (consumer) | The Server URL of the Slack instance | 
https://slack.com | String
-| *token* (consumer) | The token to use |  | String
 | *exceptionHandler* (consumer) | To let the consumer use a custom 
ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this 
option is not in use. By default the consumer will deal with exceptions, that 
will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer 
creates an exchange. There are 3 enums and the value can be one of: InOnly, 
InOut, InOptionalOut |  | ExchangePattern
 | *pollStrategy* (consumer) | A pluggable 
org.apache.camel.PollingConsumerPollingStrategy allowing you to provide your 
custom implementation to control error handling usually occurred during the 
poll operation before an Exchange have been created and being routed in Camel. 
|  | PollingConsumerPollStrategy
@@ -129,13 +132,14 @@ with the following path and query parameters:
 == SlackComponent
 
 The SlackComponent with XML must be configured as a Spring or Blueprint
-bean that contains the incoming webhook url for the integration as a
+bean that contains the incoming webhook url or the app token for the 
integration as a
 parameter.
 
 [source,xml]
 
-----------------------------------------------------------------------------------------------------------------------
 <bean id="slack" class="org.apache.camel.component.slack.SlackComponent">
     <property name="webhookUrl" 
value="https://hooks.slack.com/services/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"/>
+    <property name="token" 
value="xoxb-12345678901-1234567890123-xxxxxxxxxxxxxxxxxxxxxxxx"/>
 </bean>
 
-----------------------------------------------------------------------------------------------------------------------
 
@@ -164,6 +168,34 @@ A CamelContext with Blueprint could be as:
 </blueprint>
 
---------------------------------------------------------------------------------------------------------------------------
 
+== Producer
+
+You can now use a token to send a message instead of WebhookUrl
+
+[source,java]
+---------------------------------------------------------------------------------------------------------------------------
+from("direct:test")
+    .to("slack:#random?token=RAW(<YOUR_TOKEN>)");
+---------------------------------------------------------------------------------------------------------------------------
+
+You can now use the Slack API model to create blocks. You can read more about 
it here https://api.slack.com/block-kit
+
+[source,java]
+---------------------------------------------------------------------------------------------------------------------------
+    public void testSlackAPIModelMessage() {
+        Message message = new Message();
+        message.setBlocks(Collections.singletonList(SectionBlock
+                .builder()
+                .text(MarkdownTextObject
+                        .builder()
+                        .text("*Hello from Camel!*")
+                        .build())
+                .build()));
+
+        template.sendBody(test, message);
+    }
+---------------------------------------------------------------------------------------------------------------------------
+
 == Consumer
 
 You can use also a consumer for messages in channel
@@ -180,6 +212,14 @@ You'll need to create a Slack app and use it on your 
workspace.
 
 Use the 'Bot User OAuth Access Token' as token for the consumer endpoint.
 
-IMPORTANT: Add the `channels:history` and `channels:read` user token scope to 
your app to grant it permission to view messages in the user's public channels.
+IMPORTANT: Add the corresponding history (`channels:history` or 
`groups:history` or `mpim:history` or `im:history`) and
+read (`channels:read` or `groups:read` or `mpim:read` or `im:read`) user token 
scope to your app to grant it permission to
+view messages in the corresponding channel. You will need to use the 
conversationType option to set it up too (`PUBLIC_CHANNEL`, `PRIVATE_CHANNEL`, 
`MPIM`, `IM`)
+
+The naturalOrder option allows consuming messages from the oldest to the 
newest.
+Originally you would get the newest first and consume backward (message 3 => 
message 2 => message 1)
+
+IMPORTANT: You can use the conversationType option to read history and 
messages from a channel that is not only public
+(`PUBLIC_CHANNEL`,`PRIVATE_CHANNEL`, `MPIM`, `IM`)
 
 include::camel-spring-boot::page$slack-starter.adoc[]
diff --git 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/CustomSlackHttpClient.java
 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/CustomSlackHttpClient.java
new file mode 100644
index 0000000..10c6718
--- /dev/null
+++ 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/CustomSlackHttpClient.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.slack;
+
+import java.io.IOException;
+
+import com.slack.api.SlackConfig;
+import com.slack.api.util.http.SlackHttpClient;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+
+/**
+ * Slack-api-client use the OkHttpClient v4.x.x We need to override the 
SlackHttpClient to force the function
+ * postJsonBody to work with the v3.x.x
+ */
+public class CustomSlackHttpClient extends SlackHttpClient {
+
+    private static final MediaType MEDIA_TYPE_APPLICATION_JSON = 
MediaType.parse("application/json; charset=utf-8");
+
+    private final SlackConfig config = SlackConfig.DEFAULT;
+    private final OkHttpClient okHttpClient = buildOkHttpClient(config);
+
+    @Override
+    public Response postJsonBody(String url, Object obj) throws IOException {
+        RequestBody body = RequestBody.create((String) obj, 
MEDIA_TYPE_APPLICATION_JSON);
+        Request request = new Request.Builder().url(url).post(body).build();
+        return okHttpClient.newCall(request).execute();
+    }
+}
diff --git 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackComponent.java
 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackComponent.java
index 4264e02..eac4ef4 100644
--- 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackComponent.java
+++ 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackComponent.java
@@ -30,6 +30,9 @@ public class SlackComponent extends DefaultComponent {
     @Metadata(label = "webhook")
     private String webhookUrl;
 
+    @Metadata(label = "token")
+    private String token;
+
     public SlackComponent() {
         this(null);
     }
@@ -56,4 +59,15 @@ public class SlackComponent extends DefaultComponent {
     public void setWebhookUrl(String webhookUrl) {
         this.webhookUrl = webhookUrl;
     }
+
+    public String getToken() {
+        return token;
+    }
+
+    /**
+     * The token to use
+     */
+    public void setToken(String token) {
+        this.token = token;
+    }
 }
diff --git 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackComponentVerifierExtension.java
 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackComponentVerifierExtension.java
index 338e803..6d612fb 100644
--- 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackComponentVerifierExtension.java
+++ 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackComponentVerifierExtension.java
@@ -16,30 +16,24 @@
  */
 package org.apache.camel.component.slack;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
+import java.util.Collections;
 import java.util.Map;
 
+import com.google.gson.Gson;
+import com.slack.api.Slack;
+import com.slack.api.methods.response.conversations.ConversationsListResponse;
+import com.slack.api.model.ConversationType;
+import com.slack.api.webhook.WebhookResponse;
 import 
org.apache.camel.component.extension.verifier.DefaultComponentVerifierExtension;
 import org.apache.camel.component.extension.verifier.ResultBuilder;
 import org.apache.camel.component.extension.verifier.ResultErrorBuilder;
 import org.apache.camel.component.slack.helper.SlackMessage;
 import org.apache.camel.util.ObjectHelper;
-import org.apache.camel.util.json.JsonObject;
-import org.apache.camel.util.json.Jsoner;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.message.BasicNameValuePair;
-
-import static org.apache.camel.component.slack.utils.SlackUtils.readResponse;
 
 public class SlackComponentVerifierExtension extends 
DefaultComponentVerifierExtension {
 
+    private static final Gson GSON = new Gson();
+
     public SlackComponentVerifierExtension() {
         this("slack");
     }
@@ -57,12 +51,12 @@ public class SlackComponentVerifierExtension extends 
DefaultComponentVerifierExt
 
         if (ObjectHelper.isEmpty(parameters.get("token")) && 
ObjectHelper.isEmpty(parameters.get("webhookUrl"))) {
             
builder.error(ResultErrorBuilder.withCodeAndDescription(VerificationError.StandardCode.GENERIC,
-                    "You must specify a webhookUrl (for producer) or a token 
(for consumer)").parameterKey("webhookUrl")
-                    .parameterKey("token").build());
+                    "You must specify a webhookUrl (for producer) or a token 
(for producer and consumer)")
+                    .parameterKey("webhookUrl").parameterKey("token").build());
         }
         if (ObjectHelper.isNotEmpty(parameters.get("token")) && 
ObjectHelper.isNotEmpty(parameters.get("webhookUrl"))) {
             
builder.error(ResultErrorBuilder.withCodeAndDescription(VerificationError.StandardCode.GENERIC,
-                    "You must specify a webhookUrl (for producer) or a token 
(for consumer). You can't specify both.")
+                    "You must specify a webhookUrl (for producer) or a token 
(for producer and consumer). You can't specify both.")
                     .parameterKey("webhookUrl").parameterKey("token").build());
         }
         return builder.build();
@@ -78,35 +72,24 @@ public class SlackComponentVerifierExtension extends 
DefaultComponentVerifierExt
     }
 
     private void verifyCredentials(ResultBuilder builder, Map<String, Object> 
parameters) {
-
         String webhookUrl = (String) parameters.get("webhookUrl");
 
         if (ObjectHelper.isNotEmpty(webhookUrl)) {
 
             try {
-                HttpClient client = 
HttpClientBuilder.create().useSystemProperties().build();
-                HttpPost httpPost = new HttpPost(webhookUrl);
-
                 // Build Helper object
                 SlackMessage slackMessage;
                 slackMessage = new SlackMessage();
                 slackMessage.setText("Test connection");
 
-                // Set the post body
-                String json = asJson(slackMessage);
-                StringEntity body = new StringEntity(json);
-
-                // Do the post
-                httpPost.setEntity(body);
-
-                HttpResponse response = client.execute(httpPost);
+                WebhookResponse response
+                        = Slack.getInstance(new 
CustomSlackHttpClient()).send(webhookUrl, GSON.toJson(slackMessage));
 
                 // 2xx is OK, anything else we regard as failure
-                if (response.getStatusLine().getStatusCode() < 200 || 
response.getStatusLine().getStatusCode() > 299) {
-                    builder
-                            .error(ResultErrorBuilder
-                                    
.withCodeAndDescription(VerificationError.StandardCode.AUTHENTICATION, "Invalid 
webhookUrl")
-                                    .parameterKey("webhookUrl").build());
+                if (response.getCode() < 200 || response.getCode() > 299) {
+                    builder.error(ResultErrorBuilder
+                            
.withCodeAndDescription(VerificationError.StandardCode.AUTHENTICATION, "Invalid 
webhookUrl")
+                            .parameterKey("webhookUrl").build());
                 }
             } catch (Exception e) {
                 builder.error(ResultErrorBuilder
@@ -118,23 +101,12 @@ public class SlackComponentVerifierExtension extends 
DefaultComponentVerifierExt
             String token = (String) parameters.get("token");
 
             try {
-                HttpClient client = 
HttpClientBuilder.create().useSystemProperties().build();
-                HttpPost httpPost = new HttpPost(parameters.get("serverUrl") + 
"/api/conversations.list");
-
-                List<BasicNameValuePair> params = new ArrayList<>();
-                params.add(new BasicNameValuePair("token", token));
-                httpPost.setEntity(new UrlEncodedFormEntity(params));
+                ConversationsListResponse response = Slack.getInstance(new 
CustomSlackHttpClient()).methods(token)
+                        .conversationsList(req -> req
+                                
.types(Collections.singletonList(ConversationType.PUBLIC_CHANNEL))
+                                .limit(1));
 
-                HttpResponse response = client.execute(httpPost);
-
-                String jsonString = 
readResponse(response.getEntity().getContent());
-                if (response.getStatusLine().getStatusCode() < 200 || 
response.getStatusLine().getStatusCode() > 299) {
-                    builder.error(ResultErrorBuilder
-                            
.withCodeAndDescription(VerificationError.StandardCode.AUTHENTICATION, "Invalid 
token")
-                            .parameterKey("token").build());
-                }
-                JsonObject obj = (JsonObject) Jsoner.deserialize(jsonString);
-                if (obj.get("ok") != null && obj.get("ok").equals(false)) {
+                if (!response.isOk()) {
                     builder.error(ResultErrorBuilder
                             
.withCodeAndDescription(VerificationError.StandardCode.AUTHENTICATION, "Invalid 
token")
                             .parameterKey("token").build());
@@ -144,18 +116,6 @@ public class SlackComponentVerifierExtension extends 
DefaultComponentVerifierExt
                         
.withCodeAndDescription(VerificationError.StandardCode.AUTHENTICATION, "Invalid 
token")
                         .parameterKey("token").build());
             }
-
         }
     }
-
-    protected String asJson(SlackMessage message) {
-        Map<String, Object> jsonMap = new HashMap<>();
-
-        // Put the values in a map
-        jsonMap.put(SlackConstants.SLACK_TEXT_FIELD, message.getText());
-
-        // Generate a JSONObject
-        return new JsonObject(jsonMap).toJson();
-    }
-
 }
diff --git 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackConstants.java
 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackConstants.java
index 2609b3e..e1755a9 100644
--- 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackConstants.java
+++ 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackConstants.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.component.slack;
 
+@Deprecated
 public final class SlackConstants {
 
     public static final String SLACK_USERNAME_FIELD = "username";
diff --git 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackConsumer.java
 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackConsumer.java
index fde7f10..4296483 100644
--- 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackConsumer.java
+++ 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackConsumer.java
@@ -17,102 +17,91 @@
 package org.apache.camel.component.slack;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Queue;
 
+import com.slack.api.Slack;
+import com.slack.api.methods.SlackApiException;
+import 
com.slack.api.methods.response.conversations.ConversationsHistoryResponse;
+import com.slack.api.methods.response.conversations.ConversationsListResponse;
+import com.slack.api.model.Conversation;
+import com.slack.api.model.Message;
 import org.apache.camel.Exchange;
-import org.apache.camel.Message;
 import org.apache.camel.Processor;
 import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.component.slack.helper.SlackMessage;
 import org.apache.camel.support.ScheduledBatchPollingConsumer;
 import org.apache.camel.util.CastUtils;
 import org.apache.camel.util.ObjectHelper;
-import org.apache.camel.util.json.DeserializationException;
-import org.apache.camel.util.json.JsonArray;
-import org.apache.camel.util.json.JsonObject;
-import org.apache.camel.util.json.Jsoner;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.message.BasicNameValuePair;
-
-import static org.apache.camel.component.slack.utils.SlackUtils.readResponse;
 
 public class SlackConsumer extends ScheduledBatchPollingConsumer {
 
-    private SlackEndpoint slackEndpoint;
+    private static final int CONVERSATIONS_LIST_LIMIT = 200;
+    private final SlackEndpoint slackEndpoint;
+    private Slack slack;
     private String timestamp;
     private String channelId;
-    private CloseableHttpClient client;
 
-    public SlackConsumer(SlackEndpoint endpoint, Processor processor) throws 
IOException, DeserializationException {
+    public SlackConsumer(SlackEndpoint endpoint, Processor processor) {
         super(endpoint, processor);
         this.slackEndpoint = endpoint;
     }
 
     @Override
     protected void doStart() throws Exception {
-        this.client = HttpClientBuilder.create().useSystemProperties().build();
+        this.slack = Slack.getInstance(new CustomSlackHttpClient());
+        this.channelId = getChannelId(slackEndpoint.getChannel(), null);
         super.doStart();
-        this.channelId = getChannelId(slackEndpoint.getChannel());
     }
 
     @Override
     protected void doStop() throws Exception {
         super.doStop();
-        if (client != null) {
-            client.close();
+        if (slack != null) {
+            slack.close();
         }
     }
 
     @Override
     protected int poll() throws Exception {
-        Queue<Exchange> exchanges;
-
-        HttpPost httpPost = new HttpPost(slackEndpoint.getServerUrl() + 
"/api/conversations.history");
-        List<BasicNameValuePair> params = new ArrayList<>();
-        params.add(new BasicNameValuePair(SlackConstants.SLACK_CHANNEL_FIELD, 
channelId));
-        if (ObjectHelper.isNotEmpty(timestamp)) {
-            params.add(new BasicNameValuePair("oldest", timestamp));
+        // Maximum limit is 1000. Slack recommends no more than 200 results at 
a time.
+        // https://api.slack.com/methods/conversations.history
+        // We set the limit to 1 the first call to set the timestamp of the 
last message of the history
+        ConversationsHistoryResponse response = 
slack.methods(slackEndpoint.getToken()).conversationsHistory(req -> req
+                .channel(channelId)
+                .oldest(timestamp)
+                .limit(timestamp != null ? 
Integer.parseInt(slackEndpoint.getMaxResults()) : 1));
+
+        if (!response.isOk()) {
+            throw new RuntimeCamelException("API request conversations.history 
to Slack failed: " + response);
         }
-        params.add(new BasicNameValuePair("count", 
slackEndpoint.getMaxResults()));
-        params.add(new BasicNameValuePair("token", slackEndpoint.getToken()));
-        httpPost.setEntity(new UrlEncodedFormEntity(params));
-
-        HttpResponse response = client.execute(httpPost);
-
-        String jsonString = readResponse(response);
-
-        JsonObject c = (JsonObject) Jsoner.deserialize(jsonString);
 
-        checkSlackReply(c);
-
-        JsonArray list = c.getCollection("messages");
-        exchanges = createExchanges(list);
+        Queue<Exchange> exchanges = createExchanges(response.getMessages());
         return processBatch(CastUtils.cast(exchanges));
     }
 
-    private Queue<Exchange> createExchanges(List<Object> list) {
+    private Queue<Exchange> createExchanges(final List<Message> list) {
         Queue<Exchange> answer = new LinkedList<>();
         if (ObjectHelper.isNotEmpty(list)) {
-            Iterator it = list.iterator();
-            int i = 0;
-            while (it.hasNext()) {
-                Object object = it.next();
-                JsonObject singleMess = (JsonObject) object;
-                if (i == 0) {
-                    timestamp = (String) singleMess.get("ts");
+            if (slackEndpoint.isNaturalOrder()) {
+                for (int i = list.size() - 1; i >= 0; i--) {
+                    Message message = list.get(i);
+                    if (i == 0) {
+                        timestamp = message.getTs();
+                    }
+                    Exchange exchange = createExchange(message);
+                    answer.add(exchange);
+                }
+            } else {
+                for (int i = 0; i < list.size(); i++) {
+                    Message message = list.get(i);
+                    if (i == 0) {
+                        timestamp = message.getTs();
+                    }
+                    Exchange exchange = createExchange(message);
+                    answer.add(exchange);
                 }
-                i++;
-                Exchange exchange = createExchange(singleMess);
-                answer.add(exchange);
             }
         }
         return answer;
@@ -141,68 +130,36 @@ public class SlackConsumer extends 
ScheduledBatchPollingConsumer {
         return total;
     }
 
-    private String getChannelId(String channel) throws IOException, 
DeserializationException {
-        HttpPost httpPost = new HttpPost(slackEndpoint.getServerUrl() + 
"/api/conversations.list");
-
-        List<BasicNameValuePair> params = new ArrayList<>();
-        params.add(new BasicNameValuePair("token", slackEndpoint.getToken()));
-        httpPost.setEntity(new UrlEncodedFormEntity(params));
-
-        HttpResponse response = client.execute(httpPost);
-
-        String jsonString = readResponse(response);
-        JsonObject c = (JsonObject) Jsoner.deserialize(jsonString);
-
-        checkSlackReply(c);
-
-        Collection<JsonObject> channels = c.getCollection("channels");
-        if (channels == null) {
-            throw new RuntimeCamelException("The response was successful but 
no channel list was provided");
-        }
-
-        for (JsonObject singleChannel : channels) {
-            if (singleChannel.get("name") != null) {
-                if (singleChannel.get("name").equals(channel)) {
-                    if (singleChannel.get("id") != null) {
-                        return (String) singleChannel.get("id");
-                    }
-                }
+    private String getChannelId(final String channel, final String cursor) {
+        try {
+            // Maximum limit is 1000. Slack recommends no more than 200 
results at a time.
+            // https://api.slack.com/methods/conversations.list
+            ConversationsListResponse response = 
slack.methods(slackEndpoint.getToken()).conversationsList(req -> req
+                    
.types(Collections.singletonList(slackEndpoint.getConversationType()))
+                    .cursor(cursor)
+                    .limit(CONVERSATIONS_LIST_LIMIT));
+
+            if (!response.isOk()) {
+                throw new RuntimeCamelException("API request 
conversations.list to Slack failed: " + response);
             }
-        }
-
-        return jsonString;
-    }
-
-    private void checkSlackReply(JsonObject c) {
-        boolean okStatus = c.getBoolean("ok");
 
-        if (!okStatus) {
-            String errorMessage = c.getString("error");
-
-            if (errorMessage == null || errorMessage.isEmpty()) {
-                errorMessage = "the slack server did not provide error 
details";
-            }
-
-            throw new RuntimeCamelException(String.format("API request to 
Slack failed: %s", errorMessage));
+            return response.getChannels().stream()
+                    .filter(it -> it.getName().equals(channel))
+                    .map(Conversation::getId)
+                    .findFirst().orElseGet(() -> {
+                        if 
(ObjectHelper.isNotEmpty(response.getResponseMetadata().getNextCursor())) {
+                            throw new 
RuntimeCamelException(String.format("Channel %s not found", channel));
+                        }
+                        return getChannelId(channel, 
response.getResponseMetadata().getNextCursor());
+                    });
+        } catch (IOException | SlackApiException e) {
+            throw new RuntimeCamelException("API request conversations.list to 
Slack failed", e);
         }
     }
 
-    public Exchange createExchange(JsonObject object) {
+    private Exchange createExchange(Message object) {
         Exchange exchange = createExchange(true);
-        SlackMessage slackMessage = new SlackMessage();
-        String text = object.getString(SlackConstants.SLACK_TEXT_FIELD);
-        String user = object.getString("user");
-        slackMessage.setText(text);
-        slackMessage.setUser(user);
-        if (ObjectHelper.isNotEmpty(object.get("icons"))) {
-            JsonObject icons = object.getMap("icons");
-            if (ObjectHelper.isNotEmpty(icons.get("emoji"))) {
-                slackMessage.setIconEmoji(icons.getString("emoji"));
-            }
-        }
-        Message message = exchange.getIn();
-        message.setBody(slackMessage);
+        exchange.getIn().setBody(object);
         return exchange;
     }
-
 }
diff --git 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackEndpoint.java
 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackEndpoint.java
index 9893b21..814d03d 100644
--- 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackEndpoint.java
+++ 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackEndpoint.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.component.slack;
 
+import com.slack.api.model.ConversationType;
 import org.apache.camel.Category;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
@@ -49,12 +50,18 @@ public class SlackEndpoint extends ScheduledPollEndpoint {
     @UriParam(label = "producer")
     @Deprecated
     private String iconEmoji;
-    @UriParam(label = "consumer", secret = true)
+    @UriParam(secret = true)
     private String token;
     @UriParam(label = "consumer", defaultValue = "10")
     private String maxResults = "10";
     @UriParam(label = "consumer", defaultValue = "https://slack.com";)
     private String serverUrl = "https://slack.com";;
+    @UriParam(label = "consumer", defaultValue = "false", javaType = "boolean",
+              description = "Create exchanges in natural order (oldest to 
newest) or not")
+    private boolean naturalOrder;
+    @UriParam(label = "consumer", enums = 
"PUBLIC_CHANNEL,PRIVATE_CHANNEL,MPIM,IM", defaultValue = "PUBLIC_CHANNEL",
+              description = "Type of conversation")
+    private ConversationType conversationType = 
ConversationType.PUBLIC_CHANNEL;
 
     /**
      * Constructor for SlackEndpoint
@@ -66,11 +73,16 @@ public class SlackEndpoint extends ScheduledPollEndpoint {
     public SlackEndpoint(String uri, String channelName, SlackComponent 
component) {
         super(uri, component);
         this.webhookUrl = component.getWebhookUrl();
+        this.token = component.getToken();
         this.channel = channelName;
     }
 
     @Override
     public Producer createProducer() throws Exception {
+        if (ObjectHelper.isEmpty(token) && ObjectHelper.isEmpty(webhookUrl)) {
+            throw new RuntimeCamelException(
+                    "Missing required endpoint configuration: token or 
webhookUrl must be defined for Slack producer");
+        }
         SlackProducer producer = new SlackProducer(this);
         return producer;
     }
@@ -178,4 +190,25 @@ public class SlackEndpoint extends ScheduledPollEndpoint {
         this.serverUrl = serverUrl;
     }
 
+    /**
+     * Is consuming message in natural order
+     */
+    public void setNaturalOrder(boolean naturalOrder) {
+        this.naturalOrder = naturalOrder;
+    }
+
+    public boolean isNaturalOrder() {
+        return naturalOrder;
+    }
+
+    /**
+     * The type of the conversation
+     */
+    public void setConversationType(ConversationType conversationType) {
+        this.conversationType = conversationType;
+    }
+
+    public ConversationType getConversationType() {
+        return conversationType;
+    }
 }
diff --git 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackProducer.java
 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackProducer.java
index d1321a8..20b8d7a 100644
--- 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackProducer.java
+++ 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/SlackProducer.java
@@ -16,28 +16,26 @@
  */
 package org.apache.camel.component.slack;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+import java.io.IOException;
+
+import com.google.gson.Gson;
+import com.slack.api.Slack;
+import com.slack.api.methods.SlackApiException;
+import com.slack.api.methods.response.chat.ChatPostMessageResponse;
+import com.slack.api.model.Message;
+import com.slack.api.webhook.WebhookResponse;
 import org.apache.camel.AsyncCallback;
 import org.apache.camel.CamelExchangeException;
 import org.apache.camel.Exchange;
 import org.apache.camel.component.slack.helper.SlackMessage;
 import org.apache.camel.support.DefaultAsyncProducer;
-import org.apache.camel.support.ExchangeHelper;
-import org.apache.camel.util.json.JsonObject;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.util.EntityUtils;
 
 public class SlackProducer extends DefaultAsyncProducer {
 
+    private static final Gson GSON = new Gson();
+
     private final SlackEndpoint slackEndpoint;
-    private CloseableHttpClient client;
+    private Slack slack;
 
     public SlackProducer(SlackEndpoint endpoint) {
         super(endpoint);
@@ -46,133 +44,116 @@ public class SlackProducer extends DefaultAsyncProducer {
 
     @Override
     protected void doStart() throws Exception {
-        this.client = HttpClientBuilder.create().useSystemProperties().build();
+        this.slack = Slack.getInstance(new CustomSlackHttpClient());
         super.doStart();
     }
 
     @Override
     protected void doStop() throws Exception {
         super.doStop();
-
-        if (client != null) {
-            client.close();
-            client = null;
+        if (slack != null) {
+            slack.close();
         }
     }
 
     @Override
     public boolean process(Exchange exchange, AsyncCallback callback) {
-
-        // Create Post object
-        HttpPost httpPost = new HttpPost(slackEndpoint.getWebhookUrl());
-
-        // Build Helper object
-        SlackMessage slackMessage;
-        Object payload = exchange.getIn().getBody();
-        if (payload instanceof SlackMessage) {
-            slackMessage = (SlackMessage) payload;
+        if (slackEndpoint.getToken() != null) {
+            return sendMessageByToken(exchange, callback);
         } else {
-            slackMessage = new SlackMessage();
-            slackMessage.setText(exchange.getIn().getBody(String.class));
+            return sendMessageByWebhookURL(exchange, callback);
         }
-        slackMessage.setChannel(slackEndpoint.getChannel());
-        slackMessage.setUsername(slackEndpoint.getUsername());
-        slackMessage.setIconUrl(slackEndpoint.getIconUrl());
-        slackMessage.setIconEmoji(slackEndpoint.getIconEmoji());
-
-        // use charset from exchange or fallback to the default charset
-        String charset = ExchangeHelper.getCharsetName(exchange, true);
-
-        // Set the post body
-        String json = asJson(slackMessage);
-        StringEntity body = new StringEntity(json, charset);
+    }
 
-        // Do the post
-        httpPost.setEntity(body);
+    private boolean sendMessageByToken(Exchange exchange, AsyncCallback 
callback) {
+        ChatPostMessageResponse response;
+        Object payload = exchange.getIn().getBody();
 
         try {
-            client.execute(httpPost, response -> {
-                try {
-                    // 2xx is OK, anything else we regard as failure
-                    if (response.getStatusLine().getStatusCode() < 200 || 
response.getStatusLine().getStatusCode() > 299) {
-                        exchange.setException(
-                                new CamelExchangeException("Error POSTing to 
Slack API: " + response.toString(), exchange));
-                    }
-                    EntityUtils.consumeQuietly(response.getEntity());
-                } finally {
-                    callback.done(false);
-                }
-                return null;
-            });
+            if (payload instanceof SlackMessage) {
+                response = sendLegacySlackMessage((SlackMessage) payload);
+            } else if (payload instanceof Message) {
+                response = sendMessage((Message) payload);
+            } else {
+                SlackMessage slackMessage = new SlackMessage();
+                slackMessage.setText(exchange.getIn().getBody(String.class));
+                response = sendLegacySlackMessage(slackMessage);
+            }
         } catch (Exception e) {
             exchange.setException(e);
-            callback.done(true);
             return true;
+        } finally {
+            callback.done(true);
+        }
+
+        if (!response.isOk()) {
+            exchange.setException(new CamelExchangeException("Error POSTing to 
Slack API: " + response.toString(), exchange));
         }
 
         return false;
     }
 
-    /**
-     * Returns a JSON string to be posted to the Slack API
-     *
-     * @return JSON string
-     */
-    public String asJson(SlackMessage message) {
-        Map<String, Object> jsonMap = new HashMap<>();
-
-        // Put the values in a map
-        jsonMap.put(SlackConstants.SLACK_TEXT_FIELD, message.getText());
-        jsonMap.put(SlackConstants.SLACK_CHANNEL_FIELD, message.getChannel());
-        jsonMap.put(SlackConstants.SLACK_USERNAME_FIELD, 
message.getUsername());
-        jsonMap.put(SlackConstants.SLACK_ICON_URL_FIELD, message.getIconUrl());
-        jsonMap.put(SlackConstants.SLACK_ICON_EMOJI_FIELD, 
message.getIconEmoji());
-
-        List<SlackMessage.Attachment> attachments = message.getAttachments();
-        if (attachments != null && !attachments.isEmpty()) {
-            buildAttachmentJson(jsonMap, attachments);
+    private ChatPostMessageResponse sendLegacySlackMessage(SlackMessage 
slackMessage) throws IOException, SlackApiException {
+        return slack.methods(slackEndpoint.getToken()).chatPostMessage(req -> 
req
+                .channel(slackEndpoint.getChannel())
+                .username(slackEndpoint.getUsername())
+                .iconUrl(slackEndpoint.getIconUrl())
+                .iconEmoji(slackEndpoint.getIconEmoji())
+                .text(slackMessage.getText()));
+    }
+
+    private ChatPostMessageResponse sendMessage(Message message) throws 
IOException, SlackApiException {
+        return slack.methods(slackEndpoint.getToken()).chatPostMessage(req -> 
req
+                .channel(slackEndpoint.getChannel())
+                .username(slackEndpoint.getUsername())
+                .iconUrl(slackEndpoint.getIconUrl())
+                .iconEmoji(slackEndpoint.getIconEmoji())
+                .text(message.getText())
+                .blocks(message.getBlocks())
+                .attachments(message.getAttachments()));
+    }
+
+    private boolean sendMessageByWebhookURL(Exchange exchange, AsyncCallback 
callback) {
+        String json;
+        Object payload = exchange.getIn().getBody();
+        if (payload instanceof SlackMessage) {
+            json = GSON.toJson(addEndPointOptions((SlackMessage) payload));
+        } else if (payload instanceof Message) {
+            json = GSON.toJson(addEndPointOptions((Message) payload));
+        } else {
+            SlackMessage slackMessage = new SlackMessage();
+            slackMessage.setText(exchange.getIn().getBody(String.class));
+            json = GSON.toJson(addEndPointOptions(slackMessage));
+        }
+
+        WebhookResponse response;
+        try {
+            response = slack.send(slackEndpoint.getWebhookUrl(), json);
+        } catch (IOException e) {
+            exchange.setException(e);
+            return true;
+        } finally {
+            callback.done(true);
+        }
+
+        if (response.getCode() < 200 || response.getCode() > 299) {
+            exchange.setException(new CamelExchangeException("Error POSTing to 
Slack API: " + response.toString(), exchange));
         }
 
-        // Return the string based on the JSON Object
-        return new JsonObject(jsonMap).toJson();
+        return false;
     }
 
-    private void buildAttachmentJson(Map<String, Object> jsonMap, 
List<SlackMessage.Attachment> attachments) {
-        List<Map<String, Object>> attachmentsJson = new 
ArrayList<>(attachments.size());
-        attachments.forEach(attachment -> {
-            Map<String, Object> attachmentJson = new HashMap<>();
-            attachmentJson.put(SlackConstants.SLACK_ATTACHMENT_FALLBACK_FIELD, 
attachment.getFallback());
-            attachmentJson.put(SlackConstants.SLACK_ATTACHMENT_COLOR_FIELD, 
attachment.getColor());
-            attachmentJson.put(SlackConstants.SLACK_ATTACHMENT_PRETEXT_FIELD, 
attachment.getPretext());
-            
attachmentJson.put(SlackConstants.SLACK_ATTACHMENT_AUTHOR_NAME_FIELD, 
attachment.getAuthorName());
-            
attachmentJson.put(SlackConstants.SLACK_ATTACHMENT_AUTHOR_LINK_FIELD, 
attachment.getAuthorLink());
-            
attachmentJson.put(SlackConstants.SLACK_ATTACHMENT_AUTHOR_ICON_FIELD, 
attachment.getAuthorIcon());
-            attachmentJson.put(SlackConstants.SLACK_ATTACHMENT_TITLE_FIELD, 
attachment.getTitle());
-            
attachmentJson.put(SlackConstants.SLACK_ATTACHMENT_TITLE_LINK_FIELD, 
attachment.getTitleLink());
-            attachmentJson.put(SlackConstants.SLACK_ATTACHMENT_TEXT_FIELD, 
attachment.getText());
-            
attachmentJson.put(SlackConstants.SLACK_ATTACHMENT_IMAGE_URL_FIELD, 
attachment.getImageUrl());
-            attachmentJson.put(SlackConstants.SLACK_ATTACHMENT_FOOTER_FIELD, 
attachment.getFooter());
-            
attachmentJson.put(SlackConstants.SLACK_ATTACHMENT_FOOTER_ICON_FIELD, 
attachment.getFooterIcon());
-            attachmentJson.put(SlackConstants.SLACK_ATTACHMENT_TS_FIELD, 
attachment.getTs());
-
-            List<SlackMessage.Attachment.Field> fields = 
attachment.getFields();
-            if (fields != null && !fields.isEmpty()) {
-                buildAttachmentFieldJson(attachmentJson, fields);
-            }
-            attachmentsJson.add(attachmentJson);
-        });
-        jsonMap.put(SlackConstants.SLACK_ATTACHMENTS_FIELD, attachmentsJson);
+    private Message addEndPointOptions(Message slackMessage) {
+        slackMessage.setChannel(slackEndpoint.getChannel());
+        slackMessage.setUsername(slackEndpoint.getUsername());
+        return slackMessage;
     }
 
-    private void buildAttachmentFieldJson(Map<String, Object> attachmentJson, 
List<SlackMessage.Attachment.Field> fields) {
-        List<Map<String, Object>> fieldsJson = new ArrayList<>(fields.size());
-        fields.forEach(field -> {
-            Map<String, Object> fieldJson = new HashMap<>();
-            fieldJson.put("title", field.getTitle());
-            fieldJson.put("value", field.getValue());
-            fieldJson.put("short", field.isShortValue());
-            fieldsJson.add(fieldJson);
-        });
-        attachmentJson.put("fields", fieldsJson);
+    private SlackMessage addEndPointOptions(SlackMessage slackMessage) {
+        slackMessage.setChannel(slackEndpoint.getChannel());
+        slackMessage.setUsername(slackEndpoint.getUsername());
+        slackMessage.setIconUrl(slackEndpoint.getIconUrl());
+        slackMessage.setIconEmoji(slackEndpoint.getIconEmoji());
+        return slackMessage;
     }
 }
diff --git 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/utils/SlackUtils.java
 
b/components/camel-slack/src/main/java/org/apache/camel/component/slack/utils/SlackUtils.java
deleted file mode 100644
index 0515cdb..0000000
--- 
a/components/camel-slack/src/main/java/org/apache/camel/component/slack/utils/SlackUtils.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.slack.utils;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.http.HttpResponse;
-
-public final class SlackUtils {
-
-    private SlackUtils() {
-    }
-
-    public static String readResponse(HttpResponse response) throws 
IOException {
-        ByteArrayOutputStream result = new ByteArrayOutputStream();
-        try (InputStream s = response.getEntity().getContent()) {
-            byte[] buffer = new byte[1024];
-            int length;
-            while ((length = s.read(buffer)) != -1) {
-                result.write(buffer, 0, length);
-            }
-        }
-        return result.toString(StandardCharsets.UTF_8.name());
-    }
-
-    public static String readResponse(InputStream s) throws IOException, 
UnsupportedEncodingException {
-        ByteArrayOutputStream result = new ByteArrayOutputStream();
-        byte[] buffer = new byte[1024];
-        int length;
-        while ((length = s.read(buffer)) != -1) {
-            result.write(buffer, 0, length);
-        }
-        return result.toString(StandardCharsets.UTF_8.name());
-    }
-}
diff --git 
a/components/camel-slack/src/test/java/org/apache/camel/component/slack/SlackProducerTest.java
 
b/components/camel-slack/src/test/java/org/apache/camel/component/slack/SlackProducerTest.java
index 93c7080..406490b 100644
--- 
a/components/camel-slack/src/test/java/org/apache/camel/component/slack/SlackProducerTest.java
+++ 
b/components/camel-slack/src/test/java/org/apache/camel/component/slack/SlackProducerTest.java
@@ -16,6 +16,11 @@
  */
 package org.apache.camel.component.slack;
 
+import java.util.Collections;
+
+import com.slack.api.model.Message;
+import com.slack.api.model.block.SectionBlock;
+import com.slack.api.model.block.composition.MarkdownTextObject;
 import org.apache.camel.EndpointInject;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.direct.DirectEndpoint;
@@ -43,6 +48,24 @@ public class SlackProducerTest extends CamelTestSupport {
         assertMockEndpointsSatisfied();
     }
 
+    @Test
+    public void testSlackAPIModelMessage() throws Exception {
+        errors.expectedMessageCount(0);
+
+        Message message = new Message();
+        message.setBlocks(Collections.singletonList(SectionBlock
+                .builder()
+                .text(MarkdownTextObject
+                        .builder()
+                        .text("*Hello from Camel!*")
+                        .build())
+                .build()));
+
+        template.sendBody(test, message);
+
+        assertMockEndpointsSatisfied();
+    }
+
     @Override
     protected RouteBuilder createRouteBuilder() {
         return new RouteBuilder() {
@@ -54,10 +77,10 @@ public class SlackProducerTest extends CamelTestSupport {
 
                 onException(Exception.class).handled(true).to(errors);
 
-                final String slacUser = System.getProperty("SLACK_USER", 
"CamelTest");
+                final String slackUser = System.getProperty("SLACK_USER", 
"CamelTest");
                 from("undertow:http://localhost:"; + UNDERTOW_PORT + 
"/slack/webhook").setBody(constant("{\"ok\": true}"));
 
-                
from(test).to(String.format("slack:#general?iconEmoji=:camel:&username=%s", 
slacUser));
+                
from(test).to(String.format("slack:#general?iconEmoji=:camel:&username=%s", 
slackUser));
             }
         };
     }
diff --git 
a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SlackComponentBuilderFactory.java
 
b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SlackComponentBuilderFactory.java
index ed9ad93..b38560d 100644
--- 
a/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SlackComponentBuilderFactory.java
+++ 
b/core/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/SlackComponentBuilderFactory.java
@@ -115,6 +115,20 @@ public interface SlackComponentBuilderFactory {
             return this;
         }
         /**
+         * The token to use.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: token
+         * 
+         * @param token the value to set
+         * @return the dsl builder
+         */
+        default SlackComponentBuilder token(java.lang.String token) {
+            doSetProperty("token", token);
+            return this;
+        }
+        /**
          * The incoming webhook URL.
          * 
          * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
@@ -148,6 +162,7 @@ public interface SlackComponentBuilderFactory {
             case "bridgeErrorHandler": ((SlackComponent) 
component).setBridgeErrorHandler((boolean) value); return true;
             case "lazyStartProducer": ((SlackComponent) 
component).setLazyStartProducer((boolean) value); return true;
             case "autowiredEnabled": ((SlackComponent) 
component).setAutowiredEnabled((boolean) value); return true;
+            case "token": ((SlackComponent) 
component).setToken((java.lang.String) value); return true;
             case "webhookUrl": ((SlackComponent) 
component).setWebhookUrl((java.lang.String) value); return true;
             default: return false;
             }
diff --git 
a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SlackEndpointBuilderFactory.java
 
b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SlackEndpointBuilderFactory.java
index 84e7983..d062915 100644
--- 
a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SlackEndpointBuilderFactory.java
+++ 
b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SlackEndpointBuilderFactory.java
@@ -47,6 +47,20 @@ public interface SlackEndpointBuilderFactory {
             return (AdvancedSlackEndpointConsumerBuilder) this;
         }
         /**
+         * The token to use.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: common
+         * 
+         * @param token the value to set
+         * @return the dsl builder
+         */
+        default SlackEndpointConsumerBuilder token(String token) {
+            doSetProperty("token", token);
+            return this;
+        }
+        /**
          * Allows for bridging the consumer to the Camel routing Error Handler,
          * which mean any exceptions occurred while the consumer is trying to
          * pickup incoming messages, or the likes, will now be processed as a
@@ -92,6 +106,40 @@ public interface SlackEndpointBuilderFactory {
             return this;
         }
         /**
+         * Type of conversation.
+         * 
+         * The option is a:
+         * &lt;code&gt;com.slack.api.model.ConversationType&lt;/code&gt; type.
+         * 
+         * Default: PUBLIC_CHANNEL
+         * Group: consumer
+         * 
+         * @param conversationType the value to set
+         * @return the dsl builder
+         */
+        default SlackEndpointConsumerBuilder conversationType(
+                ConversationType conversationType) {
+            doSetProperty("conversationType", conversationType);
+            return this;
+        }
+        /**
+         * Type of conversation.
+         * 
+         * The option will be converted to a
+         * &lt;code&gt;com.slack.api.model.ConversationType&lt;/code&gt; type.
+         * 
+         * Default: PUBLIC_CHANNEL
+         * Group: consumer
+         * 
+         * @param conversationType the value to set
+         * @return the dsl builder
+         */
+        default SlackEndpointConsumerBuilder conversationType(
+                String conversationType) {
+            doSetProperty("conversationType", conversationType);
+            return this;
+        }
+        /**
          * The Max Result for the poll.
          * 
          * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
@@ -107,6 +155,37 @@ public interface SlackEndpointBuilderFactory {
             return this;
         }
         /**
+         * Create exchanges in natural order (oldest to newest) or not.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: consumer
+         * 
+         * @param naturalOrder the value to set
+         * @return the dsl builder
+         */
+        default SlackEndpointConsumerBuilder naturalOrder(boolean 
naturalOrder) {
+            doSetProperty("naturalOrder", naturalOrder);
+            return this;
+        }
+        /**
+         * Create exchanges in natural order (oldest to newest) or not.
+         * 
+         * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
+         * type.
+         * 
+         * Default: false
+         * Group: consumer
+         * 
+         * @param naturalOrder the value to set
+         * @return the dsl builder
+         */
+        default SlackEndpointConsumerBuilder naturalOrder(String naturalOrder) 
{
+            doSetProperty("naturalOrder", naturalOrder);
+            return this;
+        }
+        /**
          * If the polling consumer did not poll any files, you can enable this
          * option to send an empty message (no body) instead.
          * 
@@ -157,20 +236,6 @@ public interface SlackEndpointBuilderFactory {
             return this;
         }
         /**
-         * The token to use.
-         * 
-         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
-         * 
-         * Group: consumer
-         * 
-         * @param token the value to set
-         * @return the dsl builder
-         */
-        default SlackEndpointConsumerBuilder token(String token) {
-            doSetProperty("token", token);
-            return this;
-        }
-        /**
          * The number of subsequent error polls (failed due some error) that
          * should happen before the backoffMultipler should kick-in.
          * 
@@ -776,6 +841,20 @@ public interface SlackEndpointBuilderFactory {
             return (AdvancedSlackEndpointProducerBuilder) this;
         }
         /**
+         * The token to use.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: common
+         * 
+         * @param token the value to set
+         * @return the dsl builder
+         */
+        default SlackEndpointProducerBuilder token(String token) {
+            doSetProperty("token", token);
+            return this;
+        }
+        /**
          * Use a Slack emoji as an avatar.
          * 
          * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
@@ -908,6 +987,20 @@ public interface SlackEndpointBuilderFactory {
         default AdvancedSlackEndpointBuilder advanced() {
             return (AdvancedSlackEndpointBuilder) this;
         }
+        /**
+         * The token to use.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: common
+         * 
+         * @param token the value to set
+         * @return the dsl builder
+         */
+        default SlackEndpointBuilder token(String token) {
+            doSetProperty("token", token);
+            return this;
+        }
     }
 
     /**
@@ -922,6 +1015,16 @@ public interface SlackEndpointBuilderFactory {
         }
     }
 
+    /**
+     * Proxy enum for <code>com.slack.api.model.ConversationType</code> enum.
+     */
+    enum ConversationType {
+        PUBLIC_CHANNEL,
+        PRIVATE_CHANNEL,
+        MPIM,
+        IM;
+    }
+
     public interface SlackBuilders {
         /**
          * Slack (camel-slack)
diff --git a/docs/components/modules/ROOT/pages/slack-component.adoc 
b/docs/components/modules/ROOT/pages/slack-component.adoc
index 6c0cc29..b88ad4d 100644
--- a/docs/components/modules/ROOT/pages/slack-component.adoc
+++ b/docs/components/modules/ROOT/pages/slack-component.adoc
@@ -46,7 +46,7 @@ To send a direct message to a slackuser.
 
 [source,java]
 -------------------------
-slack:@username[?options]
+slack:@userID[?options]
 -------------------------
 
 == Options
@@ -54,7 +54,7 @@ slack:@username[?options]
 
 
 // component options: START
-The Slack component supports 4 options, which are listed below.
+The Slack component supports 5 options, which are listed below.
 
 
 
@@ -64,6 +64,7 @@ The Slack component supports 4 options, which are listed 
below.
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions occurred while the 
consumer is trying to pickup incoming messages, or the likes, will now be 
processed as a message and handled by the routing Error Handler. By default the 
consumer will use the org.apache.camel.spi.ExceptionHandler to deal with 
exceptions, that will be logged at WARN or ERROR level and ignored. | false | 
boolean
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy 
(on the first message). By starting lazy you can use this to allow CamelContext 
and routes to startup in situations where a producer may otherwise fail during 
starting and cause the route to fail being started. By deferring this startup 
to be lazy then the startup failure can be handled during routing messages via 
Camel's routing error handlers. Beware that when the first message is processed 
then creating and [...]
 | *autowiredEnabled* (advanced) | Whether autowiring is enabled. This is used 
for automatic autowiring options (the option must be marked as autowired) by 
looking up in the registry to find if there is a single instance of matching 
type, which then gets configured on the component. This can be used for 
automatic configuring JDBC data sources, JMS connection factories, AWS Clients, 
etc. | true | boolean
+| *token* (token) | The token to use |  | String
 | *webhookUrl* (webhook) | The incoming webhook URL |  | String
 |===
 // component options: END
@@ -90,17 +91,19 @@ with the following path and query parameters:
 |===
 
 
-=== Query Parameters (27 parameters):
+=== Query Parameters (29 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
+| *token* (common) | The token to use |  | String
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the 
Camel routing Error Handler, which mean any exceptions occurred while the 
consumer is trying to pickup incoming messages, or the likes, will now be 
processed as a message and handled by the routing Error Handler. By default the 
consumer will use the org.apache.camel.spi.ExceptionHandler to deal with 
exceptions, that will be logged at WARN or ERROR level and ignored. | false | 
boolean
+| *conversationType* (consumer) | Type of conversation. There are 4 enums and 
the value can be one of: PUBLIC_CHANNEL, PRIVATE_CHANNEL, MPIM, IM | 
PUBLIC_CHANNEL | ConversationType
 | *maxResults* (consumer) | The Max Result for the poll | 10 | String
+| *naturalOrder* (consumer) | Create exchanges in natural order (oldest to 
newest) or not | false | boolean
 | *sendEmptyMessageWhenIdle* (consumer) | If the polling consumer did not poll 
any files, you can enable this option to send an empty message (no body) 
instead. | false | boolean
 | *serverUrl* (consumer) | The Server URL of the Slack instance | 
https://slack.com | String
-| *token* (consumer) | The token to use |  | String
 | *exceptionHandler* (consumer) | To let the consumer use a custom 
ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this 
option is not in use. By default the consumer will deal with exceptions, that 
will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
 | *exchangePattern* (consumer) | Sets the exchange pattern when the consumer 
creates an exchange. There are 3 enums and the value can be one of: InOnly, 
InOut, InOptionalOut |  | ExchangePattern
 | *pollStrategy* (consumer) | A pluggable 
org.apache.camel.PollingConsumerPollingStrategy allowing you to provide your 
custom implementation to control error handling usually occurred during the 
poll operation before an Exchange have been created and being routed in Camel. 
|  | PollingConsumerPollStrategy
@@ -131,13 +134,14 @@ with the following path and query parameters:
 == SlackComponent
 
 The SlackComponent with XML must be configured as a Spring or Blueprint
-bean that contains the incoming webhook url for the integration as a
+bean that contains the incoming webhook url or the app token for the 
integration as a
 parameter.
 
 [source,xml]
 
-----------------------------------------------------------------------------------------------------------------------
 <bean id="slack" class="org.apache.camel.component.slack.SlackComponent">
     <property name="webhookUrl" 
value="https://hooks.slack.com/services/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"/>
+    <property name="token" 
value="xoxb-12345678901-1234567890123-xxxxxxxxxxxxxxxxxxxxxxxx"/>
 </bean>
 
-----------------------------------------------------------------------------------------------------------------------
 
@@ -166,6 +170,35 @@ A CamelContext with Blueprint could be as:
 </blueprint>
 
---------------------------------------------------------------------------------------------------------------------------
 
+== Producer
+
+*Since Camel 3.9.0* +
+ You can now use a token to send a message instead of WebhookUrl
+
+[source,java]
+---------------------------------------------------------------------------------------------------------------------------
+from("direct:test")
+    .to("slack:#random?token=RAW(<YOUR_TOKEN>)");
+---------------------------------------------------------------------------------------------------------------------------
+
+ You can now use the Slack API model to create blocks. You can read more about 
it here https://api.slack.com/block-kit
+
+[source,java]
+---------------------------------------------------------------------------------------------------------------------------
+    public void testSlackAPIModelMessage() {
+        Message message = new Message();
+        message.setBlocks(Collections.singletonList(SectionBlock
+                .builder()
+                .text(MarkdownTextObject
+                        .builder()
+                        .text("*Hello from Camel!*")
+                        .build())
+                .build()));
+
+        template.sendBody(test, message);
+    }
+---------------------------------------------------------------------------------------------------------------------------
+
 == Consumer
 
 You can use also a consumer for messages in channel
@@ -182,6 +215,15 @@ You'll need to create a Slack app and use it on your 
workspace.
 
 Use the 'Bot User OAuth Access Token' as token for the consumer endpoint.
 
-IMPORTANT: Add the `channels:history` and `channels:read` user token scope to 
your app to grant it permission to view messages in the user's public channels.
+IMPORTANT: Add the corresponding history (`channels:history` or 
`groups:history` or `mpim:history` or `im:history`) and
+read (`channels:read` or `groups:read` or `mpim:read` or `im:read`) user token 
scope to your app to grant it permission to
+view messages in the corresponding channel. You will need to use the 
conversationType option to set it up too (`PUBLIC_CHANNEL`, `PRIVATE_CHANNEL`, 
`MPIM`, `IM`)
+
+*Since Camel 3.9.0* +
+ The naturalOrder option allows consuming messages from the oldest to the 
newest.
+Originally you would get the newest first and consume backward (message 3 => 
message 2 => message 1)
+
+IMPORTANT: You can use the conversationType option to read history and 
messages from a channel that is not only public
+(`PUBLIC_CHANNEL`,`PRIVATE_CHANNEL`, `MPIM`, `IM`)
 
 include::camel-spring-boot::page$slack-starter.adoc[]
diff --git a/parent/pom.xml b/parent/pom.xml
index 84f8384..85928f0 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -493,6 +493,7 @@
         <shrinkwrap-resolver-version>3.1.3</shrinkwrap-resolver-version>
         <shrinkwrap-version>1.2.6</shrinkwrap-version>
         <sip-api-version>1.1</sip-api-version>
+        <slack-api-model-version>1.6.1</slack-api-model-version>
         <slf4j-api-version>1.7.30</slf4j-api-version>
         <slf4j-version>1.7.30</slf4j-version>
         <smack-version>4.3.5</smack-version>

Reply via email to