diff --git a/pom.xml b/pom.xml
index 8b13f5c..4b0f055 100644
--- a/pom.xml
+++ b/pom.xml
@@ -89,6 +89,8 @@ SOFTWARE.
3.0.0
8.15
3.2.2
+ 0.55.0
+ 0.3.2
@@ -132,6 +134,16 @@ SOFTWARE.
spring-boot-configuration-processor
true
+
+ io.github.eo-cqrs
+ eokson
+ ${eokson.version}
+
+
+ org.cactoos
+ cactoos
+ ${cactoos.version}
+
org.projectlombok
lombok
diff --git a/src/main/java/io/blamer/hub/controller/ChatController.java b/src/main/java/io/blamer/hub/controller/ChatController.java
new file mode 100644
index 0000000..1f39a49
--- /dev/null
+++ b/src/main/java/io/blamer/hub/controller/ChatController.java
@@ -0,0 +1,46 @@
+package io.blamer.hub.controller;
+
+import io.blamer.hub.model.Chats;
+import io.blamer.hub.pg.PgChat;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Mono;
+
+/**
+ * Chat Controller.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+@RestController
+@RequestMapping("/api/chats")
+public class ChatController {
+
+ /**
+ * Chats.
+ */
+ private final Chats chats;
+
+ /**
+ * Ctor.
+ *
+ * @param chats Chats
+ */
+ public ChatController(@Qualifier("validated") final Chats chats) {
+ this.chats = chats;
+ }
+
+ /**
+ * Register new Chat ID.
+ *
+ * @param chat Chat ID
+ * @return Mono void publisher
+ */
+ @PostMapping
+ public Mono registerChatId(@RequestBody final Long chat) {
+ return this.chats.add(new PgChat(chat));
+ }
+}
diff --git a/src/main/java/io/blamer/hub/controller/HubAdvice.java b/src/main/java/io/blamer/hub/controller/HubAdvice.java
new file mode 100644
index 0000000..6d38239
--- /dev/null
+++ b/src/main/java/io/blamer/hub/controller/HubAdvice.java
@@ -0,0 +1,38 @@
+package io.blamer.hub.controller;
+
+import io.blamer.hub.rq.ChatAlreadyExists;
+import io.github.eocqrs.eokson.Jocument;
+import io.github.eocqrs.eokson.MutableJson;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+/**
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+@Slf4j
+@RestControllerAdvice
+public class HubAdvice {
+
+ /**
+ * Handle {@link ChatAlreadyExists}.
+ *
+ * @param ex ChatAlreadyExists
+ * @return ResponseEntity
+ */
+ @ExceptionHandler(ChatAlreadyExists.class)
+ public ResponseEntity handle(final ChatAlreadyExists ex) {
+ log.debug("Chat ID already exists", ex);
+ return new ResponseEntity<>(
+ new Jocument(
+ new MutableJson()
+ .with("code", HttpStatus.CONFLICT.value())
+ .with("message", ex.getMessage())
+ ).byteArray(),
+ HttpStatus.CONFLICT
+ );
+ }
+}
diff --git a/src/main/java/io/blamer/hub/controller/TokenController.java b/src/main/java/io/blamer/hub/controller/TokenController.java
new file mode 100644
index 0000000..e579e09
--- /dev/null
+++ b/src/main/java/io/blamer/hub/controller/TokenController.java
@@ -0,0 +1,48 @@
+package io.blamer.hub.controller;
+
+import io.blamer.hub.model.Tokens;
+import io.blamer.hub.rq.RequestToken;
+import io.blamer.hub.rq.TokenToAdd;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import reactor.core.publisher.Mono;
+
+/**
+ * Token controller.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+@RestController
+@RequestMapping("/api/tokens")
+public class TokenController {
+
+ /**
+ * Tokens.
+ */
+ private final Tokens tokens;
+
+ /**
+ * Ctor.
+ *
+ * @param tkns Tokens
+ */
+ public TokenController(final Tokens tkns) {
+ this.tokens = tkns;
+ }
+
+ /**
+ * Registers new Token with Chat ID.
+ *
+ * @param request RequestToken
+ * @return Mono void publisher
+ * @throws Exception if something went wrong
+ */
+ @PostMapping
+ Mono registerToken(@RequestBody final RequestToken request)
+ throws Exception {
+ return this.tokens.add(new TokenToAdd(request).value());
+ }
+}
diff --git a/src/main/java/io/blamer/hub/controller/package-info.java b/src/main/java/io/blamer/hub/controller/package-info.java
new file mode 100644
index 0000000..8b216b8
--- /dev/null
+++ b/src/main/java/io/blamer/hub/controller/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Endpoints.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+package io.blamer.hub.controller;
diff --git a/src/main/java/io/blamer/hub/model/Chat.java b/src/main/java/io/blamer/hub/model/Chat.java
new file mode 100644
index 0000000..7d65713
--- /dev/null
+++ b/src/main/java/io/blamer/hub/model/Chat.java
@@ -0,0 +1,17 @@
+package io.blamer.hub.model;
+
+/**
+ * Chat.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+public interface Chat {
+
+ /**
+ * Chat ID.
+ *
+ * @return Chat ID
+ */
+ long id();
+}
diff --git a/src/main/java/io/blamer/hub/model/Chats.java b/src/main/java/io/blamer/hub/model/Chats.java
new file mode 100644
index 0000000..974aeeb
--- /dev/null
+++ b/src/main/java/io/blamer/hub/model/Chats.java
@@ -0,0 +1,20 @@
+package io.blamer.hub.model;
+
+import reactor.core.publisher.Mono;
+
+/**
+ * Chats.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+public interface Chats {
+
+ /**
+ * Add new Chat.
+ *
+ * @param chat Chat
+ * @return Mono void publisher
+ */
+ Mono add(Chat chat);
+}
diff --git a/src/main/java/io/blamer/hub/model/Token.java b/src/main/java/io/blamer/hub/model/Token.java
new file mode 100644
index 0000000..07507fd
--- /dev/null
+++ b/src/main/java/io/blamer/hub/model/Token.java
@@ -0,0 +1,38 @@
+package io.blamer.hub.model;
+
+/**
+ * Token.
+ *
+ * @author Aliaksei Bialiauski ()
+ * @since 0.0.0
+ */
+public interface Token {
+
+ /**
+ * Id.
+ *
+ * @return Token id
+ */
+ Long id();
+
+ /**
+ * Value.
+ *
+ * @return Token value
+ */
+ String value();
+
+ /**
+ * Alias.
+ *
+ * @return Token alias
+ */
+ String alias();
+
+ /**
+ * Chat.
+ *
+ * @return Token chat
+ */
+ Chat chat();
+}
diff --git a/src/main/java/io/blamer/hub/model/Tokens.java b/src/main/java/io/blamer/hub/model/Tokens.java
new file mode 100644
index 0000000..4ce7853
--- /dev/null
+++ b/src/main/java/io/blamer/hub/model/Tokens.java
@@ -0,0 +1,20 @@
+package io.blamer.hub.model;
+
+import reactor.core.publisher.Mono;
+
+/**
+ * Tokens.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+public interface Tokens {
+
+ /**
+ * Register new token.
+ *
+ * @param token Token
+ * @return Mono void publisher
+ */
+ Mono add(Token token);
+}
diff --git a/src/main/java/io/blamer/hub/model/package-info.java b/src/main/java/io/blamer/hub/model/package-info.java
new file mode 100644
index 0000000..aeaeb78
--- /dev/null
+++ b/src/main/java/io/blamer/hub/model/package-info.java
@@ -0,0 +1,31 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2023 Blamer.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * Model.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+package io.blamer.hub.model;
diff --git a/src/main/java/io/blamer/hub/pg/PgChat.java b/src/main/java/io/blamer/hub/pg/PgChat.java
new file mode 100644
index 0000000..a51b6f0
--- /dev/null
+++ b/src/main/java/io/blamer/hub/pg/PgChat.java
@@ -0,0 +1,24 @@
+package io.blamer.hub.pg;
+
+import io.blamer.hub.model.Chat;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * Chat in PostgreSQL.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+@RequiredArgsConstructor
+public class PgChat implements Chat {
+
+ /**
+ * Chat ID.
+ */
+ private final long id;
+
+ @Override
+ public long id() {
+ return this.id;
+ }
+}
diff --git a/src/main/java/io/blamer/hub/pg/PgChats.java b/src/main/java/io/blamer/hub/pg/PgChats.java
new file mode 100644
index 0000000..d98d619
--- /dev/null
+++ b/src/main/java/io/blamer/hub/pg/PgChats.java
@@ -0,0 +1,41 @@
+package io.blamer.hub.pg;
+
+import io.blamer.hub.model.Chat;
+import io.blamer.hub.model.Chats;
+import org.springframework.r2dbc.core.DatabaseClient;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Mono;
+
+/**
+ * Chats in PostgreSQL.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+@Component
+public class PgChats implements Chats {
+
+ /**
+ * Database Client.
+ */
+ private final DatabaseClient db;
+
+ /**
+ * Ctor.
+ *
+ * @param dbc Database Client.
+ */
+ public PgChats(final DatabaseClient dbc) {
+ this.db = dbc;
+ }
+
+ @Override
+ public Mono add(final Chat chat) {
+ return this.db.sql(
+ "INSERT INTO chat (id) VALUES (:id)"
+ ).bind("id", chat.id())
+ .fetch()
+ .first()
+ .then();
+ }
+}
diff --git a/src/main/java/io/blamer/hub/pg/PgToken.java b/src/main/java/io/blamer/hub/pg/PgToken.java
new file mode 100644
index 0000000..f53832a
--- /dev/null
+++ b/src/main/java/io/blamer/hub/pg/PgToken.java
@@ -0,0 +1,76 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2023 Blamer.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.blamer.hub.pg;
+
+import io.blamer.hub.model.Chat;
+import io.blamer.hub.model.Token;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * Token in PostgreSQL.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+@RequiredArgsConstructor
+public class PgToken implements Token {
+
+ /**
+ * Token ID.
+ */
+ private final Long id;
+ /**
+ * Token value.
+ */
+ private final String value;
+ /**
+ * Token alias.
+ */
+ private final String alias;
+ /**
+ * Chat ID.
+ */
+ private final long chat;
+
+ @Override
+ public Long id() {
+ return this.id;
+ }
+
+ @Override
+ public String value() {
+ return this.value;
+ }
+
+ @Override
+ public String alias() {
+ return this.alias;
+ }
+
+ @Override
+ public Chat chat() {
+ return new PgChat(this.chat);
+ }
+}
diff --git a/src/main/java/io/blamer/hub/pg/PgTokens.java b/src/main/java/io/blamer/hub/pg/PgTokens.java
new file mode 100644
index 0000000..f87532d
--- /dev/null
+++ b/src/main/java/io/blamer/hub/pg/PgTokens.java
@@ -0,0 +1,69 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2023 Blamer.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.blamer.hub.pg;
+
+import io.blamer.hub.model.Token;
+import io.blamer.hub.model.Tokens;
+import org.springframework.r2dbc.core.DatabaseClient;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Mono;
+
+/**
+ * Tokens in PostgreSQL.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+@Component
+public class PgTokens implements Tokens {
+
+ /**
+ * Database Client.
+ */
+ private final DatabaseClient db;
+
+ /**
+ * Ctor.
+ *
+ * @param dbc DatabaseClient
+ */
+ public PgTokens(final DatabaseClient dbc) {
+ this.db = dbc;
+ }
+
+ @Override
+ public Mono add(final Token token) {
+ return this.db.sql(
+ "INSERT INTO token (token, alias, chat)"
+ + "VALUES (:token, :alias, :chat)"
+ )
+ .bind("token", token.value())
+ .bind("alias", token.alias())
+ .bind("chat", token.chat().id())
+ .fetch()
+ .first()
+ .then();
+ }
+}
diff --git a/src/main/java/io/blamer/hub/pg/Validated.java b/src/main/java/io/blamer/hub/pg/Validated.java
new file mode 100644
index 0000000..9da1354
--- /dev/null
+++ b/src/main/java/io/blamer/hub/pg/Validated.java
@@ -0,0 +1,63 @@
+package io.blamer.hub.pg;
+
+import io.blamer.hub.model.Chat;
+import io.blamer.hub.model.Chats;
+import io.blamer.hub.rq.ChatAlreadyExists;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.r2dbc.core.DatabaseClient;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Mono;
+
+import java.util.function.Function;
+
+/**
+ * Validated Chats.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+@Component
+public class Validated implements Chats {
+
+ /**
+ * Chats.
+ */
+ private final Chats chats;
+ /**
+ * Database Client.
+ */
+ private final DatabaseClient db;
+
+ /**
+ * Ctor.
+ *
+ * @param chts Chats
+ * @param dbc Database Client
+ */
+ public Validated(
+ @Qualifier("pgChats") final Chats chts,
+ final DatabaseClient dbc
+ ) {
+ this.chats = chts;
+ this.db = dbc;
+ }
+
+ @Override
+ public Mono add(final Chat chat) {
+ return this.db.sql("SELECT c.id AS id FROM chat c WHERE c.id = :chat")
+ .bind("chat", chat.id())
+ .fetch()
+ .one()
+ .flatMap(rows ->
+ Mono.just((Long) rows.get("id")))
+ .flatMap(
+ (Function>) id ->
+ Mono.error(
+ new ChatAlreadyExists(
+ "Chat ID %s already exists"
+ .formatted(id)
+ )
+ )
+ ).switchIfEmpty(this.chats.add(chat));
+ }
+}
diff --git a/src/main/java/io/blamer/hub/pg/package-info.java b/src/main/java/io/blamer/hub/pg/package-info.java
new file mode 100644
index 0000000..00c7c7c
--- /dev/null
+++ b/src/main/java/io/blamer/hub/pg/package-info.java
@@ -0,0 +1,31 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2023 Blamer.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * PostgreSQL.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+package io.blamer.hub.pg;
diff --git a/src/main/java/io/blamer/hub/rq/ChatAlreadyExists.java b/src/main/java/io/blamer/hub/rq/ChatAlreadyExists.java
new file mode 100644
index 0000000..c33674b
--- /dev/null
+++ b/src/main/java/io/blamer/hub/rq/ChatAlreadyExists.java
@@ -0,0 +1,44 @@
+package io.blamer.hub.rq;
+
+/**
+ * Chat already exists.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+public class ChatAlreadyExists extends RuntimeException {
+
+ /**
+ * Ctor.
+ */
+ public ChatAlreadyExists() {
+ }
+
+ /**
+ * Ctor.
+ *
+ * @param message Message
+ */
+ public ChatAlreadyExists(final String message) {
+ super(message);
+ }
+
+ /**
+ * Ctor.
+ *
+ * @param message Message
+ * @param cause Exception
+ */
+ public ChatAlreadyExists(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Ctor.
+ *
+ * @param cause Exception
+ */
+ public ChatAlreadyExists(final Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/src/main/java/io/blamer/hub/rq/ChatToAdd.java b/src/main/java/io/blamer/hub/rq/ChatToAdd.java
new file mode 100644
index 0000000..e0ac7ee
--- /dev/null
+++ b/src/main/java/io/blamer/hub/rq/ChatToAdd.java
@@ -0,0 +1,57 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2023 Blamer.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.blamer.hub.rq;
+
+import io.blamer.hub.model.Chat;
+import io.blamer.hub.pg.PgChat;
+import org.cactoos.Scalar;
+
+/**
+ * Chat to add.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+public final class ChatToAdd implements Scalar {
+
+ /**
+ * Chat ID.
+ */
+ private final long chat;
+
+ /**
+ * Ctor.
+ *
+ * @param cht Chat ID
+ */
+ public ChatToAdd(final long cht) {
+ this.chat = cht;
+ }
+
+ @Override
+ public Chat value() throws Exception {
+ return new PgChat(this.chat);
+ }
+}
diff --git a/src/main/java/io/blamer/hub/rq/RequestToken.java b/src/main/java/io/blamer/hub/rq/RequestToken.java
new file mode 100644
index 0000000..d5cf968
--- /dev/null
+++ b/src/main/java/io/blamer/hub/rq/RequestToken.java
@@ -0,0 +1,50 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2023 Blamer.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.blamer.hub.rq;
+
+import lombok.Data;
+
+/**
+ * Request token.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+@Data
+public class RequestToken {
+
+ /**
+ * Token alias.
+ */
+ private final String alias;
+ /**
+ * Token value.
+ */
+ private final String value;
+ /**
+ * Chat ID.
+ */
+ private final long chat;
+}
diff --git a/src/main/java/io/blamer/hub/rq/TokenToAdd.java b/src/main/java/io/blamer/hub/rq/TokenToAdd.java
new file mode 100644
index 0000000..d0a1afa
--- /dev/null
+++ b/src/main/java/io/blamer/hub/rq/TokenToAdd.java
@@ -0,0 +1,55 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2023 Blamer.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package io.blamer.hub.rq;
+
+import io.blamer.hub.model.Token;
+import io.blamer.hub.pg.PgToken;
+import lombok.RequiredArgsConstructor;
+import org.cactoos.Scalar;
+
+/**
+ * Token to add.
+ *
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+@RequiredArgsConstructor
+public class TokenToAdd implements Scalar {
+
+ /**
+ * Request.
+ */
+ private final RequestToken request;
+
+ @Override
+ public Token value() throws Exception {
+ return new PgToken(
+ null,
+ this.request.getValue(),
+ this.request.getAlias(),
+ this.request.getChat()
+ );
+ }
+}
diff --git a/src/main/java/io/blamer/hub/rq/package-info.java b/src/main/java/io/blamer/hub/rq/package-info.java
new file mode 100644
index 0000000..e821201
--- /dev/null
+++ b/src/main/java/io/blamer/hub/rq/package-info.java
@@ -0,0 +1,29 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2023 Blamer.io
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * @author Aliaksei Bialiauski (abialiauski.dev@gmail.com)
+ * @since 0.0.0
+ */
+package io.blamer.hub.rq;