diff --git a/src/qTbot/src/private/requests/telegramsenddocument.cpp b/src/qTbot/src/private/requests/telegramsenddocument.cpp
index 25fd992..85e2135 100644
--- a/src/qTbot/src/private/requests/telegramsenddocument.cpp
+++ b/src/qTbot/src/private/requests/telegramsenddocument.cpp
@@ -12,35 +12,11 @@ TelegramSendDocument::TelegramSendDocument(const QVariant &chatId,
                                            const QString &text,
                                            const QString& fileName,
                                            const QByteArray &data):
-    TelegramSingleRquest("sendDocument") {
-
-    addArg("chat_id", chatId);
-    if (text.size())
-        addArg("caption", text);
-
-    addArg(QString("%0:%1").arg(REQUEST_UPLOAD_FILE_KEY, fileName), data);
-
-}
+    TelegramSendFile("sendDocument", chatId, text, fileName, TELEGRAM_DOCUMENT, data) {}
 
 TelegramSendDocument::TelegramSendDocument(const QVariant &chatId,
                                            const QString &text,
                                            const QFileInfo &file):
-    TelegramSingleRquest("sendDocument")
-{
-    addArg("chat_id", chatId);
+    TelegramSendFile("sendDocument", chatId, text, file) {}
 
-    if (text.size())
-        addArg("text", text);
-
-    QFile readFile(file.absoluteFilePath());
-    if (!readFile.open(QIODevice::ReadOnly)) {
-        qWarning() << "Fail to open file" << file.absoluteFilePath();
-    }
-
-    addArg(REQUEST_UPLOAD_FILE_KEY, file.completeBaseName().toLatin1() + ":" + readFile.readAll());
-}
-
-iRequest::RequestMethod TelegramSendDocument::method() const {
-    return Upload;
-}
 }
diff --git a/src/qTbot/src/private/requests/telegramsenddocument.h b/src/qTbot/src/private/requests/telegramsenddocument.h
index 4e62e7a..7bd389a 100644
--- a/src/qTbot/src/private/requests/telegramsenddocument.h
+++ b/src/qTbot/src/private/requests/telegramsenddocument.h
@@ -8,17 +8,15 @@
 #ifndef TELEGRAMSENDDOCUMENT_H
 #define TELEGRAMSENDDOCUMENT_H
 
-#include "telegramsinglerquest.h"
+#include "telegramsendfile.h"
 
-#include <QFile>
-#include <QFileInfo>
 
 namespace qTbot {
 
 /**
  * @brief The TelegramSendDocument class sents document into chat
  */
-class TelegramSendDocument: public TelegramSingleRquest
+class TelegramSendDocument: public TelegramSendFile
 {
 public:
     TelegramSendDocument(const QVariant &chatId,
@@ -30,10 +28,6 @@ public:
                          const QString &text,
                          const QFileInfo &file);
 
-
-    // iRequest interface
-public:
-    RequestMethod method() const override;
 };
 }
 #endif // TELEGRAMSENDDOCUMENT_H
diff --git a/src/qTbot/src/private/requests/telegramsendfile.cpp b/src/qTbot/src/private/requests/telegramsendfile.cpp
new file mode 100644
index 0000000..3b6af0e
--- /dev/null
+++ b/src/qTbot/src/private/requests/telegramsendfile.cpp
@@ -0,0 +1,85 @@
+//#
+//# Copyright (C) 2023-2023 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+#include "telegramsendfile.h"
+
+#include <QJsonDocument>
+
+namespace qTbot {
+
+
+qTbot::TelegramSendFile::TelegramSendFile(const QString &request,
+                                          const QVariant &chatId,
+                                          const QString &text,
+                                          const QString &fileName,
+                                          const QString &fileType,
+                                          const QByteArray &data,
+                                          unsigned long long replyToMessageId,
+                                          const QMap<QString, QSharedPointer<QJsonObject>>& extraObjects
+                                          ):
+    TelegramSingleRquest(request) {
+
+    addArg("chat_id", chatId);
+    if (text.size())
+        addArg("caption", text);
+
+    if (replyToMessageId > 0) {
+        addArg("reply_to_message_id", replyToMessageId);
+    }
+
+    for (auto it = extraObjects.begin(); it != extraObjects.end(); it = std::next(it)) {
+        addArg(it.key(), QJsonDocument(*it.value()).toJson(QJsonDocument::Compact));
+    }
+
+    addArg(QString("%0:%1:%2").arg(REQUEST_UPLOAD_FILE_KEY, fileName, fileType), data);
+}
+
+qTbot::TelegramSendFile::TelegramSendFile(const QString &request,
+                                          const QVariant &chatId,
+                                          const QString &text,
+                                          const QFileInfo &file,
+                                          unsigned long long replyToMessageId,
+                                          const QMap<QString, QSharedPointer<QJsonObject> > &extraObjects):
+    TelegramSingleRquest(request) {
+
+    addArg("chat_id", chatId);
+
+    if (text.size())
+        addArg("text", text);
+
+    if (replyToMessageId > 0) {
+        addArg("reply_to_message_id", replyToMessageId);
+    }
+
+    QFile readFile(file.absoluteFilePath());
+    if (!readFile.open(QIODevice::ReadOnly)) {
+        qWarning() << "Fail to open file" << file.absoluteFilePath();
+    }
+
+    for (auto it = extraObjects.begin(); it != extraObjects.end(); it = std::next(it)) {
+        addArg(it.key(), QJsonDocument(*it.value()).toJson(QJsonDocument::Compact));
+    }
+
+    auto&& sufix = file.suffix();
+    if (sufix.contains("png") || sufix.contains("jpg") || sufix.contains("jepg") || sufix.contains("gif")) {
+        addArg(QString("%0:%1:%2").arg(REQUEST_UPLOAD_FILE_KEY, file.fileName(), TELEGRAM_PHOTO),  readFile.readAll());
+
+    } else {
+        addArg(QString("%0:%1:%2").arg(REQUEST_UPLOAD_FILE_KEY, file.fileName(), TELEGRAM_DOCUMENT), readFile.readAll());
+
+    }
+
+    readFile.close();
+}
+
+iRequest::RequestMethod TelegramSendFile::method() const {
+    return iRequest::RequestMethod::Upload;
+}
+
+QString TelegramSendFile::type() const {
+    return REQUEST_UPLOAD_FILE_KEY;
+}
+}
diff --git a/src/qTbot/src/private/requests/telegramsendfile.h b/src/qTbot/src/private/requests/telegramsendfile.h
new file mode 100644
index 0000000..e0d0596
--- /dev/null
+++ b/src/qTbot/src/private/requests/telegramsendfile.h
@@ -0,0 +1,51 @@
+//#
+//# Copyright (C) 2023-2023 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+#ifndef TELEGRAMSENDFILE_H
+#define TELEGRAMSENDFILE_H
+
+#include "qfileinfo.h"
+#include "requests/telegramsinglerquest.h"
+
+#define TELEGRAM_PHOTO "photo"
+#define TELEGRAM_DOCUMENT "document"
+
+namespace qTbot {
+
+/**
+ * @brief The TelegramSendFile class Base clas for upload files to server
+ */
+class TelegramSendFile: public TelegramSingleRquest
+{
+public:
+
+    TelegramSendFile(const QString &request,
+                     const QVariant &chatId,
+                     const QString &text,
+                     const QString &fileName,
+                     const QString &fileType,
+                     const QByteArray& data,
+                     unsigned long long replyToMessageId = 0,
+                     const QMap<QString, QSharedPointer<QJsonObject> > &extraObjects = {});
+
+    TelegramSendFile(const QString &request,
+                     const QVariant &chatId,
+                     const QString &text,
+                     const QFileInfo &file,
+                     unsigned long long replyToMessageId = 0,
+                     const QMap<QString, QSharedPointer<QJsonObject> > &extraObjects = {});
+
+    RequestMethod method() const override;
+
+protected:
+    /**
+     * @brief type return type file. By Default it is REQUEST_UPLOAD_FILE_KEY
+     * @return
+     */
+    virtual QString type() const;
+};
+}
+#endif // TELEGRAMSENDFILE_H
diff --git a/src/qTbot/src/private/requests/telegramsendphoto.cpp b/src/qTbot/src/private/requests/telegramsendphoto.cpp
new file mode 100644
index 0000000..2033602
--- /dev/null
+++ b/src/qTbot/src/private/requests/telegramsendphoto.cpp
@@ -0,0 +1,34 @@
+//#
+//# Copyright (C) 2023-2023 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+
+#include "telegramsendphoto.h"
+
+namespace qTbot {
+
+
+TelegramSendPhoto::TelegramSendPhoto(const QVariant &chatId,
+                                     const QString &text,
+                                     const QString &fileName,
+                                     const QByteArray &data,
+                                     unsigned long long replyToMessageId,
+                                     const QMap<QString, QSharedPointer<QJsonObject>>& extraObjects
+                                     ):
+    TelegramSendFile("sendPhoto", chatId, text, fileName, TELEGRAM_PHOTO, data, replyToMessageId, extraObjects) {
+
+}
+
+TelegramSendPhoto::TelegramSendPhoto(const QVariant &chatId,
+                                     const QString &text,
+                                     const QFileInfo &file,
+                                     unsigned long long replyToMessageId,
+                                     const QMap<QString, QSharedPointer<QJsonObject> > &extraObjects):
+    TelegramSendFile("sendPhoto", chatId, text, file, replyToMessageId, extraObjects) {
+
+}
+
+}
diff --git a/src/qTbot/src/private/requests/telegramsendphoto.h b/src/qTbot/src/private/requests/telegramsendphoto.h
new file mode 100644
index 0000000..1f7eac7
--- /dev/null
+++ b/src/qTbot/src/private/requests/telegramsendphoto.h
@@ -0,0 +1,39 @@
+//#
+//# Copyright (C) 2023-2023 QuasarApp.
+//# Distributed under the GPLv3 software license, see the accompanying
+//# Everyone is permitted to copy and distribute verbatim copies
+//# of this license document, but changing it is not allowed.
+//#
+
+
+#ifndef TELEGRAMSENDPHOTO_H
+#define TELEGRAMSENDPHOTO_H
+
+#include "telegramsendfile.h"
+
+namespace qTbot {
+
+/**
+ * @brief The TelegramSendPhoto class using to sending photos on chat
+ */
+class TelegramSendPhoto: public TelegramSendFile
+{
+public:
+    TelegramSendPhoto(const QVariant &chatId,
+                      const QString &text,
+                      const QString &fileName,
+                      const QByteArray& data,
+                      unsigned long long replyToMessageId = 0,
+                      const QMap<QString, QSharedPointer<QJsonObject>>& extraObjects = {}
+                      );
+
+    TelegramSendPhoto(const QVariant &chatId,
+                      const QString &text,
+                      const QFileInfo &file,
+                      unsigned long long replyToMessageId = 0,
+                      const QMap<QString, QSharedPointer<QJsonObject>>& extraObjects = {}
+                      );
+
+};
+}
+#endif // TELEGRAMSENDPHOTO_H
diff --git a/src/qTbot/src/public/qTbot/irequest.cpp b/src/qTbot/src/public/qTbot/irequest.cpp
index f3bbffa..92972ae 100644
--- a/src/qTbot/src/public/qTbot/irequest.cpp
+++ b/src/qTbot/src/public/qTbot/irequest.cpp
@@ -66,13 +66,16 @@ QSharedPointer<QHttpMultiPart> iRequest::argsToMultipartFormData() const {
         if (it.key().contains(REQUEST_UPLOAD_FILE_KEY)) {
             auto metaData = it.key().split(":");
 
-            if (metaData.size() == 2) {
+            if (metaData.size() == 3) {
                 const auto fileName = metaData[1];
-                part.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"document\"; filename=\"" + fileName + "\"");
+                const auto fileType = metaData[2];
+
+                part.setHeader(QNetworkRequest::ContentDispositionHeader,
+                               "form-data; name=\"" + fileType + "\"; filename=\"" + fileName + "\"");
 
                 part.setBody(value.toByteArray());
             } else {
-                qWarning() << "the file arguments must be like _file_:fileName";
+                qWarning() << "the file arguments must be like _file_:fileName:fileType";
                 return nullptr;
             }
 
diff --git a/src/qTbot/src/public/qTbot/irequest.h b/src/qTbot/src/public/qTbot/irequest.h
index 1574732..33b10d0 100644
--- a/src/qTbot/src/public/qTbot/irequest.h
+++ b/src/qTbot/src/public/qTbot/irequest.h
@@ -17,6 +17,7 @@
 #include <QHttpMultiPart>
 
 #define REQUEST_UPLOAD_FILE_KEY "_file_"
+
 namespace qTbot {
 
 /**
diff --git a/src/qTbot/src/public/qTbot/itelegrambot.cpp b/src/qTbot/src/public/qTbot/itelegrambot.cpp
index 0d594eb..5545187 100644
--- a/src/qTbot/src/public/qTbot/itelegrambot.cpp
+++ b/src/qTbot/src/public/qTbot/itelegrambot.cpp
@@ -20,6 +20,7 @@
 #include <requests/telegramdeletemessage.h>
 #include <requests/telegrameditmessage.h>
 #include <requests/telegramsendlocation.h>
+#include <requests/telegramsendphoto.h>
 
 #include <QNetworkReply>
 #include <QSharedPointer>
@@ -106,10 +107,6 @@ bool ITelegramBot::sendSpecificMessageWithKeyboard(const QVariant &chatId,
     if (!chatId.isValid() || chatId.isNull())
         return false;
 
-    if (text.isEmpty()) {
-        return false;
-    }
-
     auto msg = QSharedPointer<TelegramSendMsg>::create(chatId,
                                                        text,
                                                        prepareKeyboard(autoResizeKeyboard, onTimeKeyboard, keyboard),
@@ -221,7 +218,7 @@ bool ITelegramBot::editSpecificMessageWithKeyboard(const QVariant &messageId,
                                                    const QString &text,
                                                    bool markdown,
                                                    bool disableWebPagePreview,
-                                                   const QList<QMap<QString, std::function<void (const QString &, const QVariant&)> > > &keyboard,
+                                                   const KeyboardOnMessage &keyboard,
                                                    const QString &callBackQueryId) {
 
     if (!chatId.isValid() || chatId.isNull())
@@ -386,6 +383,44 @@ bool ITelegramBot::sendFile(const QByteArray &file, const QString &fileName, con
     return sendFileWithDescription(file, fileName, chatId, "");
 }
 
+bool ITelegramBot::sendPhoto(const QFileInfo &photo,
+                             const QVariant &chatId,
+                             const QString &description,
+                             unsigned long long replyToMessageId,
+                             const KeyboardOnMessage &keyboard) {
+    if (!chatId.isValid() || chatId.isNull())
+        return false;
+
+    if (!photo.isReadable()) {
+        return false;
+    }
+
+    return sendFileWithPrivate(QSharedPointer<TelegramSendPhoto>::create(
+        chatId, description, photo, replyToMessageId, prepareInlineKeyBoard(keyboard)));
+}
+
+bool ITelegramBot::sendPhoto(const QByteArray &photo,
+                             const QString &fileName,
+                             const QVariant &chatId,
+                             const QString &description,
+                             unsigned long long replyToMessageId,
+                             const KeyboardOnMessage &keyboard) {
+
+    if (!chatId.isValid() || chatId.isNull())
+        return false;
+
+    if (!fileName.size()) {
+        return false;
+    }
+
+    if (!photo.size()) {
+        return false;
+    }
+
+    return sendFileWithPrivate(QSharedPointer<TelegramSendPhoto>::create(
+        chatId, description, fileName, photo, replyToMessageId, prepareInlineKeyBoard(keyboard)));
+}
+
 bool ITelegramBot::sendFileWithDescription(const QByteArray &file,
                                            const QString &fileName,
                                            const QVariant &chatId,
@@ -402,9 +437,7 @@ bool ITelegramBot::sendFileWithDescription(const QByteArray &file,
         return false;
     }
 
-    auto&& request = QSharedPointer<TelegramSendDocument>::create(chatId, description, fileName, file);
-
-    return bool(sendRequest(request));
+    return sendFileWithPrivate(QSharedPointer<TelegramSendDocument>::create(chatId, description, fileName, file));
 }
 
 bool ITelegramBot::sendFileWithDescription(const QFileInfo &file,
@@ -417,10 +450,7 @@ bool ITelegramBot::sendFileWithDescription(const QFileInfo &file,
         return false;
     }
 
-    auto&& request = QSharedPointer<TelegramSendDocument>::create(chatId, description, file);
-
-    return bool(sendRequest(request));
-
+    return sendFileWithPrivate(QSharedPointer<TelegramSendDocument>::create(chatId, description, file));
 }
 
 bool ITelegramBot::sendFileById(const QString &fileID, const QVariant &chatId) {
@@ -532,6 +562,10 @@ void ITelegramBot::handleFileHeader(const QWeakPointer<QNetworkReply> &sender,
     }
 }
 
+bool ITelegramBot::sendFileWithPrivate(const QSharedPointer<TelegramSendFile> &file) {
+    return bool(sendRequest(file));
+}
+
 QString ITelegramBot::findFileInlocatStorage(const QString &fileId) const {
     QDir defaultFileDir(defaultFileStorageLocation());
 
diff --git a/src/qTbot/src/public/qTbot/itelegrambot.h b/src/qTbot/src/public/qTbot/itelegrambot.h
index 2b6a808..6d739bd 100644
--- a/src/qTbot/src/public/qTbot/itelegrambot.h
+++ b/src/qTbot/src/public/qTbot/itelegrambot.h
@@ -21,6 +21,7 @@ namespace qTbot {
 class ITelegramMessage;
 class TelegramFile;
 class TelegramUpdateAnswer;
+class TelegramSendFile;
 
 typedef std::function<void(const QString& buttonKey, const QVariant& msgID)> ButtonCB;
 typedef QList<QMap<QString, ButtonCB >> KeyboardOnMessage;
@@ -120,9 +121,9 @@ public:
     bool sendSpecificMessageWithKeyboard(const QVariant &chatId,
                                          const QString& text,
                                          const QList<QList<QString> > &keyboard,
-                                         const QString &callBackQueryId,
+                                         const QString &callBackQueryId = "",
                                          bool onTimeKeyboard = false,
-                                         bool autoResizeKeyboard = false,
+                                         bool autoResizeKeyboard = true,
                                          unsigned long long replyToMessageId = 0,
                                          bool markdown = true,
                                          bool disableWebPagePreview = false);
@@ -186,7 +187,7 @@ public:
                                          const QString &text,
                                          bool markdown = true,
                                          bool disableWebPagePreview = false,
-                                         const QList<QMap<QString, std::function<void (const QString &, const QVariant &)> > > &keyboard = {},
+                                         const KeyboardOnMessage &keyboard = {},
                                          const QString &callBackQueryId = "");
 
     /**
@@ -230,6 +231,36 @@ public:
 
     bool sendFile( const QByteArray& file, const QString& fileName, const QVariant& chatId) override;
 
+    /**
+     * @brief sendPhoto This method will send image into chat with @a chatId
+     * @param photo this is photo path.
+     * @param chatId target chat
+     * @param replyToMessageId The unique identifier of the message to reply to, if any.
+     * @param keyboard A list of maps where each map represents a button with a callback function (optional).
+     * @return true if photo will snt successful
+     */
+    bool sendPhoto(const QFileInfo& photo,
+                   const QVariant& chatId,
+                   const QString &description,
+                   unsigned long long replyToMessageId = 0,
+                   const KeyboardOnMessage &keyboard = {});
+
+    /**
+     * @brief sendPhoto This method will send image into chat with @a chatId
+     * @param photo this is photo data.
+     * @param chatId target chat
+     * @param fileName This is dispalyed name of photo.
+     * @param replyToMessageId The unique identifier of the message to reply to, if any.
+     * @param keyboard A list of maps where each map represents a button with a callback function (optional).
+     * @return true if photo will snt successful
+     */
+    bool sendPhoto(const QByteArray& photo,
+                   const QString& fileName,
+                   const QVariant& chatId,
+                   const QString &description,
+                   unsigned long long replyToMessageId = 0,
+                   const KeyboardOnMessage &keyboard = {});
+
     /**
      * @brief sendFileWithDescription This method sents a byte array as a file into @a chatId with additional text @a description.
      * @param file This is a file source
@@ -238,7 +269,7 @@ public:
      * @param description additional text for message.
      * @return true if the message sents successful else false.
      */
-    bool sendFileWithDescription( const QByteArray& file,
+    bool sendFileWithDescription(const QByteArray& file,
                                  const QString& fileName,
                                  const QVariant& chatId,
                                  const QString& description);
@@ -375,6 +406,10 @@ private slots:
                           const QWeakPointer<iFile> &receiver);
 
 private:
+
+
+    bool sendFileWithPrivate(const QSharedPointer<TelegramSendFile>& file);
+
     QString findFileInlocatStorage(const QString& fileId) const;
     QMap<QString, QSharedPointer<QJsonObject>>
     prepareInlineKeyBoard(const QList<QMap<QString, std::function<void (const QString &, const QVariant &)> > > &keyboard);