diff --git a/CHANGELOG.md b/CHANGELOG.md
index e9a314e6..ab2c37d5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,13 +8,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added
 
-- Add `filter_boost_added` and `filter_reply_to_story` filters to `MessageFilterExt` trait
-- Add `filter_mention_command` filter to `HandlerExt` trait ([issue #494](https://github.com/teloxide/teloxide/issues/494))
-- Add `filter_business_connection`, `filter_business_message`, `filter_edited_business_message`, and `filter_deleted_business_messages` filters to update filters ([PR 1146](https://github.com/teloxide/teloxide/pull/1146))
+- `filter_boost_added` and `filter_reply_to_story` filters to the `MessageFilterExt` trait ([PR 1131](https://github.com/teloxide/teloxide/pull/1131))
+- `filter_mention_command` filter to the `HandlerExt` trait ([issue 494](https://github.com/teloxide/teloxide/issues/494))
+- `filter_business_connection`, `filter_business_message`, `filter_edited_business_message`, and `filter_deleted_business_messages` filters to the `UpdateFilterExt` trait ([PR 1146](https://github.com/teloxide/teloxide/pull/1146))
+- Syntax sugar for making requests ([issue 1143](https://github.com/teloxide/teloxide/issues/1143)):
+  - `bot.forward`, `bot.edit_live_location`, `bot.stop_live_location`, `bot.set_reaction`, `bot.pin`, `bot.unpin`, `bot.edit_text`, `bot.edit_caption`, `bot.edit_media`, `bot.edit_reply_markup`, `bot.stop_poll_message`, `bot.delete` and `bot.copy` methods to the new `crate::sugar::bot::BotMessagesExt` trait
+  - `req.reply_to` method to the new `crate::sugar::request::RequestReplyExt` trait
+  - `req.disable_link_preview` method to the new `crate::sugar::request::RequestLinkPreviewExt` trait
 
 ### Changed
 
-- Environment bumps: ([#1147][pr1147])
+- Environment bumps: ([PR 1147](https://github.com/teloxide/teloxide/pull/1147))
   - MSRV (Minimal Supported Rust Version) was bumped from `1.70.0` to `1.80.0`
   - Some dependencies was bumped: `sqlx` to `0.8.1`, `tower` to `0.5.0`, `reqwest` to `0.12.7`
   - `tokio` version was explicitly specified as `1.39`
@@ -23,8 +27,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 - Now Vec<MessageId> in requests serializes into [number] instead of [ {message_id: number} ], `forward_messages`, `copy_messages` and `delete_messages` now work properly
 
-[pr1147]: https://github.com/teloxide/teloxide/pull/1147
-
 ## 0.13.0 - 2024-08-16
 
 ### Added
diff --git a/crates/teloxide-core/src/types/message.rs b/crates/teloxide-core/src/types/message.rs
index 2b2ce6e2..2da52dcf 100644
--- a/crates/teloxide-core/src/types/message.rs
+++ b/crates/teloxide-core/src/types/message.rs
@@ -1816,6 +1816,13 @@ impl Message {
     }
 }
 
+/// Implemented for syntax sugar, see issue <https://github.com/teloxide/teloxide/issues/1143>
+impl From<Message> for MessageId {
+    fn from(message: Message) -> MessageId {
+        message.id
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use chrono::DateTime;
diff --git a/crates/teloxide/examples/buttons.rs b/crates/teloxide/examples/buttons.rs
index daa538c2..9f188915 100644
--- a/crates/teloxide/examples/buttons.rs
+++ b/crates/teloxide/examples/buttons.rs
@@ -2,6 +2,7 @@ use std::error::Error;
 use teloxide::{
     payloads::SendMessageSetters,
     prelude::*,
+    sugar::bot::BotMessagesExt,
     types::{
         InlineKeyboardButton, InlineKeyboardMarkup, InlineQueryResultArticle, InputMessageContent,
         InputMessageContentText, Me,
@@ -107,17 +108,17 @@ async fn inline_query_handler(
 /// **IMPORTANT**: do not send privacy-sensitive data this way!!!
 /// Anyone can read data stored in the callback button.
 async fn callback_handler(bot: Bot, q: CallbackQuery) -> Result<(), Box<dyn Error + Send + Sync>> {
-    if let Some(version) = q.data {
+    if let Some(ref version) = q.data {
         let text = format!("You chose: {version}");
 
         // Tell telegram that we've seen this query, to remove 🕑 icons from the
         // clients. You could also use `answer_callback_query`'s optional
         // parameters to tweak what happens on the client side.
-        bot.answer_callback_query(q.id).await?;
+        bot.answer_callback_query(&q.id).await?;
 
         // Edit text of the message to which the buttons were attached
-        if let Some(message) = q.message {
-            bot.edit_message_text(message.chat().id, message.id(), text).await?;
+        if let Some(message) = q.regular_message() {
+            bot.edit_text(message, text).await?;
         } else if let Some(id) = q.inline_message_id {
             bot.edit_message_text_inline(id, text).await?;
         }
diff --git a/crates/teloxide/examples/dispatching_features.rs b/crates/teloxide/examples/dispatching_features.rs
index bcc65a2e..8b327b55 100644
--- a/crates/teloxide/examples/dispatching_features.rs
+++ b/crates/teloxide/examples/dispatching_features.rs
@@ -4,9 +4,7 @@
 use rand::Rng;
 
 use teloxide::{
-    dispatching::HandlerExt,
-    prelude::*,
-    types::{Dice, ReplyParameters},
+    dispatching::HandlerExt, prelude::*, sugar::request::RequestReplyExt, types::Dice,
     utils::command::BotCommands,
 };
 
@@ -84,7 +82,7 @@ async fn main() {
             // filter only messages with dices.
             Message::filter_dice().endpoint(|bot: Bot, msg: Message, dice: Dice| async move {
                 bot.send_message(msg.chat.id, format!("Dice value: {}", dice.value))
-                    .reply_parameters(ReplyParameters::new(msg.id))
+                    .reply_to(msg)
                     .await?;
                 Ok(())
             }),
diff --git a/crates/teloxide/src/lib.rs b/crates/teloxide/src/lib.rs
index bcb901f1..edab596d 100644
--- a/crates/teloxide/src/lib.rs
+++ b/crates/teloxide/src/lib.rs
@@ -140,6 +140,7 @@ pub mod prelude;
 #[cfg(feature = "ctrlc_handler")]
 pub mod repls;
 pub mod stop;
+pub mod sugar;
 pub mod update_listeners;
 pub mod utils;
 
diff --git a/crates/teloxide/src/sugar.rs b/crates/teloxide/src/sugar.rs
new file mode 100644
index 00000000..0e8bb856
--- /dev/null
+++ b/crates/teloxide/src/sugar.rs
@@ -0,0 +1,4 @@
+//! Some syntax sugar support for TBA functionality.
+
+pub mod bot;
+pub mod request;
diff --git a/crates/teloxide/src/sugar/bot.rs b/crates/teloxide/src/sugar/bot.rs
new file mode 100644
index 00000000..c1e4f0cd
--- /dev/null
+++ b/crates/teloxide/src/sugar/bot.rs
@@ -0,0 +1,191 @@
+//! Additions to [`Bot`].
+//!
+//! [`Bot`]: crate::Bot
+use crate::{prelude::*, types::*};
+use teloxide_core::{
+    payloads::*,
+    requests::{JsonRequest, MultipartRequest},
+};
+
+/// Syntax sugar for [`Message`] manipulations.
+///
+/// [`Message`]: crate::types::Message
+pub trait BotMessagesExt {
+    /// This function is the same as [`Bot::forward_message`],
+    /// but can take in [`Message`] to forward it.
+    ///
+    /// [`Bot::forward_message`]: crate::Bot::forward_message
+    /// [`Message`]: crate::types::Message
+    fn forward<C>(&self, to_chat_id: C, message: &Message) -> JsonRequest<ForwardMessage>
+    where
+        C: Into<Recipient>;
+
+    /// This function is the same as [`Bot::edit_message_live_location`],
+    /// but can take in [`Message`] to edit it.
+    ///
+    /// [`Bot::edit_message_live_location`]: crate::Bot::edit_message_live_location
+    /// [`Message`]: crate::types::Message
+    fn edit_live_location(
+        &self,
+        message: &Message,
+        latitude: f64,
+        longitude: f64,
+    ) -> JsonRequest<EditMessageLiveLocation>;
+
+    /// This function is the same as [`Bot::stop_message_live_location`],
+    /// but can take in [`Message`] to stop the live location in it.
+    ///
+    /// [`Bot::stop_message_live_location`]: crate::Bot::stop_message_live_location
+    /// [`Message`]: crate::types::Message
+    fn stop_live_location(&self, message: &Message) -> JsonRequest<StopMessageLiveLocation>;
+
+    /// This function is the same as [`Bot::set_message_reaction`],
+    /// but can take in [`Message`] to set a reaction on it.
+    ///
+    /// [`Bot::set_message_reaction`]: crate::Bot::set_message_reaction
+    /// [`Message`]: crate::types::Message
+    fn set_reaction(&self, message: &Message) -> JsonRequest<SetMessageReaction>;
+
+    /// This function is the same as [`Bot::pin_chat_message`],
+    /// but can take in [`Message`] to pin it.
+    ///
+    /// [`Bot::pin_chat_message`]: crate::Bot::pin_chat_message
+    /// [`Message`]: crate::types::Message
+    fn pin(&self, message: &Message) -> JsonRequest<PinChatMessage>;
+
+    /// This function is the same as [`Bot::unpin_chat_message`],
+    /// but can take in [`Message`] to unpin it.
+    ///
+    /// [`Bot::unpin_chat_message`]: crate::Bot::unpin_chat_message
+    /// [`Message`]: crate::types::Message
+    fn unpin(&self, message: &Message) -> JsonRequest<UnpinChatMessage>;
+
+    /// This function is the same as [`Bot::edit_message_text`],
+    /// but can take in [`Message`] to edit it.
+    ///
+    /// [`Bot::edit_message_text`]: crate::Bot::edit_message_text
+    /// [`Message`]: crate::types::Message
+    fn edit_text<T>(&self, message: &Message, text: T) -> JsonRequest<EditMessageText>
+    where
+        T: Into<String>;
+
+    /// This function is the same as [`Bot::edit_message_caption`],
+    /// but can take in [`Message`] to edit it.
+    ///
+    /// [`Bot::edit_message_caption`]: crate::Bot::edit_message_caption
+    /// [`Message`]: crate::types::Message
+    fn edit_caption(&self, message: &Message) -> JsonRequest<EditMessageCaption>;
+
+    /// This function is the same as [`Bot::edit_message_media`],
+    /// but can take in [`Message`] to edit it.
+    ///
+    /// [`Bot::edit_message_media`]: crate::Bot::edit_message_media
+    /// [`Message`]: crate::types::Message
+    fn edit_media(
+        &self,
+        message: &Message,
+        media: InputMedia,
+    ) -> MultipartRequest<EditMessageMedia>;
+
+    /// This function is the same as [`Bot::edit_message_reply_markup`],
+    /// but can take in [`Message`] to edit it.
+    ///
+    /// [`Bot::edit_message_reply_markup`]: crate::Bot::edit_message_reply_markup
+    /// [`Message`]: crate::types::Message
+    fn edit_reply_markup(&self, message: &Message) -> JsonRequest<EditMessageReplyMarkup>;
+
+    /// This function is the same as [`Bot::stop_poll`],
+    /// but can take in [`Message`] to stop the poll in it.
+    ///
+    /// [`Bot::stop_poll`]: crate::Bot::stop_poll
+    /// [`Message`]: crate::types::Message
+    fn stop_poll_message(&self, message: &Message) -> JsonRequest<StopPoll>;
+
+    /// This function is the same as [`Bot::delete_message`],
+    /// but can take in [`Message`] to delete it.
+    ///
+    /// [`Bot::delete_message`]: crate::Bot::delete_message
+    /// [`Message`]: crate::types::Message
+    fn delete(&self, message: &Message) -> JsonRequest<DeleteMessage>;
+
+    /// This function is the same as [`Bot::copy_message`],
+    /// but can take in [`Message`] to copy it.
+    ///
+    /// [`Bot::copy_messages`]: crate::Bot::copy_message
+    /// [`Message`]: crate::types::Message
+    fn copy<C>(&self, to_chat_id: C, message: &Message) -> JsonRequest<CopyMessage>
+    where
+        C: Into<Recipient>;
+}
+
+impl BotMessagesExt for Bot {
+    fn forward<C>(&self, to_chat_id: C, message: &Message) -> JsonRequest<ForwardMessage>
+    where
+        C: Into<Recipient>,
+    {
+        self.forward_message(to_chat_id, message.chat.id, message.id)
+    }
+
+    fn edit_live_location(
+        &self,
+        message: &Message,
+        latitude: f64,
+        longitude: f64,
+    ) -> JsonRequest<EditMessageLiveLocation> {
+        self.edit_message_live_location(message.chat.id, message.id, latitude, longitude)
+    }
+
+    fn stop_live_location(&self, message: &Message) -> JsonRequest<StopMessageLiveLocation> {
+        self.stop_message_live_location(message.chat.id, message.id)
+    }
+
+    fn set_reaction(&self, message: &Message) -> JsonRequest<SetMessageReaction> {
+        self.set_message_reaction(message.chat.id, message.id)
+    }
+
+    fn pin(&self, message: &Message) -> JsonRequest<PinChatMessage> {
+        self.pin_chat_message(message.chat.id, message.id)
+    }
+
+    fn unpin(&self, message: &Message) -> JsonRequest<UnpinChatMessage> {
+        self.unpin_chat_message(message.chat.id).message_id(message.id)
+    }
+
+    fn edit_text<T>(&self, message: &Message, text: T) -> JsonRequest<EditMessageText>
+    where
+        T: Into<String>,
+    {
+        self.edit_message_text(message.chat.id, message.id, text)
+    }
+
+    fn edit_caption(&self, message: &Message) -> JsonRequest<EditMessageCaption> {
+        self.edit_message_caption(message.chat.id, message.id)
+    }
+
+    fn edit_media(
+        &self,
+        message: &Message,
+        media: InputMedia,
+    ) -> MultipartRequest<EditMessageMedia> {
+        self.edit_message_media(message.chat.id, message.id, media)
+    }
+
+    fn edit_reply_markup(&self, message: &Message) -> JsonRequest<EditMessageReplyMarkup> {
+        self.edit_message_reply_markup(message.chat.id, message.id)
+    }
+
+    fn stop_poll_message(&self, message: &Message) -> JsonRequest<StopPoll> {
+        self.stop_poll(message.chat.id, message.id)
+    }
+
+    fn delete(&self, message: &Message) -> JsonRequest<DeleteMessage> {
+        self.delete_message(message.chat.id, message.id)
+    }
+
+    fn copy<C>(&self, to_chat_id: C, message: &Message) -> JsonRequest<CopyMessage>
+    where
+        C: Into<Recipient>,
+    {
+        self.copy_message(to_chat_id, message.chat.id, message.id)
+    }
+}
diff --git a/crates/teloxide/src/sugar/request.rs b/crates/teloxide/src/sugar/request.rs
new file mode 100644
index 00000000..59ca41b0
--- /dev/null
+++ b/crates/teloxide/src/sugar/request.rs
@@ -0,0 +1,155 @@
+//! Additions to [`JsonRequest`] and [`MultipartRequest`].
+//!
+//! [`JsonRequest`]: teloxide_core::requests::JsonRequest
+//! [`MultipartRequest`]: teloxide_core::requests::MultipartRequest
+
+use teloxide_core::{
+    payloads::*,
+    requests::{JsonRequest, MultipartRequest},
+    types::*,
+};
+
+macro_rules! impl_request_reply_ext {
+    ($($t:ty),*) => {
+        $(
+            impl RequestReplyExt for $t {
+                fn reply_to<M>(self, message_id: M) -> Self
+                where
+                    M: Into<MessageId>,
+                    Self: Sized,
+                {
+                    self.reply_parameters(ReplyParameters::new(message_id.into()))
+                }
+            }
+        )*
+    };
+}
+
+macro_rules! impl_request_link_preview_ext {
+    ($($t:ty),*) => {
+        $(
+            impl RequestLinkPreviewExt for $t {
+                fn disable_link_preview(self, is_disabled: bool) -> Self
+                where
+                    Self: Sized
+                {
+                    let link_preview_options = LinkPreviewOptions {
+                        is_disabled,
+                        url: None,
+                        prefer_small_media: false,
+                        prefer_large_media: false,
+                        show_above_text: false,
+                    };
+                    self.link_preview_options(link_preview_options)
+                }
+            }
+        )*
+    };
+}
+
+/// `.reply_to(msg)` syntax sugar for requests.
+pub trait RequestReplyExt {
+    /// Replaces `.reply_parameters(ReplyParameters::new(msg.id))`
+    /// with `.reply_to(msg.id)` or `.reply_to(msg)`
+    fn reply_to<M>(self, message_id: M) -> Self
+    where
+        M: Into<MessageId>,
+        Self: Sized;
+}
+
+/// `.disable_link_preview(is_disabled)` syntax sugar for requests.
+pub trait RequestLinkPreviewExt {
+    /// Replaces
+    /// `.link_preview_options(LinkPreviewOptions {
+    ///     is_disabled: true,
+    ///     url: None,
+    ///     prefer_small_media: false,
+    ///     prefer_large_media: false,
+    ///     show_above_text: false
+    /// };)`
+    ///
+    /// with `.disable_link_preview(true)`.
+    fn disable_link_preview(self, is_disabled: bool) -> Self
+    where
+        Self: Sized;
+}
+
+impl_request_reply_ext! {
+    JsonRequest<SendDice>,
+    JsonRequest<SendInvoice>,
+    JsonRequest<SendPoll>,
+    JsonRequest<SendContact>,
+    JsonRequest<SendGame>,
+    JsonRequest<SendVenue>,
+    JsonRequest<SendLocation>,
+    JsonRequest<CopyMessage>,
+    JsonRequest<SendMessage>,
+    MultipartRequest<SendSticker>,
+    MultipartRequest<SendMediaGroup>,
+    MultipartRequest<SendAnimation>,
+    MultipartRequest<SendVideoNote>,
+    MultipartRequest<SendVideo>,
+    MultipartRequest<SendDocument>,
+    MultipartRequest<SendAudio>,
+    MultipartRequest<SendVoice>,
+    MultipartRequest<SendPhoto>
+}
+
+impl_request_link_preview_ext! {
+    JsonRequest<SendMessage>,
+    JsonRequest<EditMessageText>
+}
+
+#[cfg(test)]
+mod tests {
+    use std::ops::Deref;
+
+    use super::*;
+    use teloxide_core::{prelude::Requester, Bot};
+
+    #[test]
+    fn test_reply_to() {
+        let bot = Bot::new("TOKEN");
+
+        let real_reply_req = bot
+            .send_message(ChatId(1234), "test")
+            .reply_parameters(ReplyParameters::new(MessageId(1)));
+        let sugar_reply_req = bot.send_message(ChatId(1234), "test").reply_to(MessageId(1));
+
+        assert_eq!(real_reply_req.deref(), sugar_reply_req.deref())
+    }
+
+    #[test]
+    fn test_reply_to_multipart() {
+        let bot = Bot::new("TOKEN");
+        let document = InputFile::memory("hello world!");
+
+        let real_reply_req = bot
+            .send_document(ChatId(1234), document.clone())
+            .reply_parameters(ReplyParameters::new(MessageId(1)));
+        let sugar_reply_req = bot.send_document(ChatId(1234), document).reply_to(MessageId(1));
+
+        assert_eq!(
+            real_reply_req.deref().reply_parameters,
+            sugar_reply_req.deref().reply_parameters
+        )
+    }
+
+    #[test]
+    fn test_disable_link_preview() {
+        let link_preview_options = LinkPreviewOptions {
+            is_disabled: true,
+            url: None,
+            prefer_small_media: false,
+            prefer_large_media: false,
+            show_above_text: false,
+        };
+        let bot = Bot::new("TOKEN");
+
+        let real_link_req =
+            bot.send_message(ChatId(1234), "test").link_preview_options(link_preview_options);
+        let sugar_link_req = bot.send_message(ChatId(1234), "test").disable_link_preview(true);
+
+        assert_eq!(real_link_req.deref(), sugar_link_req.deref())
+    }
+}