Repository: aiogram/aiogram

Issue:
`ForceReply` doesn't work
## Context

ForceReply does not provide a reply

* Operating System: ubuntu 20.04
* Python Version: 3.9
* aiogram version: 3.0.0b3
* aiohttp version: 3.8.1
* uvloop version (if installed): 0.16.0

## Expected Behavior

ForceReply provide a reply

## Current Behavior

ForceReply does not provide a reply

## Failure Information (for bugs)

Please help provide information about the failure if this is a bug. If it is not a bug, please remove the rest of this template.

### Steps to Reproduce

Just try to run this code:

```python
import logging

from aiogram import Bot, Dispatcher, Router
from aiogram.types import Message, ForceReply

TOKEN = ""
dp = Dispatcher()

router = Router()

logger = logging.getLogger(__name__)


@router.message(commands={"start"})
async def command_start_handler(message: Message) -> None:
    await message.answer(f"Hello, <b>{message.from_user.full_name}!</b>", reply_markup=ForceReply(force_reply=True))


def main() -> None:
    bot = Bot(TOKEN, parse_mode="HTML")

    dp.include_router(router)
    dp.run_polling(bot, )


if __name__ == "__main__":
    main()
```

### Failure Logs

Please include any relevant log snippets or files here.


Discussion:
github-actions[bot]: # :heavy_check_mark: Changelog found.

Thank you for adding a description of the changes
codecov[bot]: # [Codecov](https://codecov.io/gh/aiogram/aiogram/pull/912?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram) Report
> Merging [#912](https://codecov.io/gh/aiogram/aiogram/pull/912?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram) (3d6b756) into [dev-3.x](https://codecov.io/gh/aiogram/aiogram/commit/6ad242399b88f522060d9ce4578d9599e5137762?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram) (6ad2423) will **not change** coverage.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/aiogram/aiogram/pull/912/graphs/tree.svg?width=650&height=150&src=pr&token=cFqEr3p9MX&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram)](https://codecov.io/gh/aiogram/aiogram/pull/912?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram)

```diff
@@            Coverage Diff            @@
##           dev-3.x      #912   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          300       300           
  Lines         8181      8183    +2     
=========================================
+ Hits          8181      8183    +2     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `100.00% <100.00%> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/aiogram/aiogram/pull/912?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram) | Coverage Δ | |
|---|---|---|
| [aiogram/methods/base.py](https://codecov.io/gh/aiogram/aiogram/pull/912/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram#diff-YWlvZ3JhbS9tZXRob2RzL2Jhc2UucHk=) | `100.00% <100.00%> (ø)` | |
| [aiogram/types/force\_reply.py](https://codecov.io/gh/aiogram/aiogram/pull/912/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=aiogram#diff-YWlvZ3JhbS90eXBlcy9mb3JjZV9yZXBseS5weQ==) | `100.00% <100.00%> (ø)` | |


Patch:
diff --git a/CHANGES/901.bugfix.rst b/CHANGES/901.bugfix.rst
new file mode 100644
index 00000000..e920c152
--- /dev/null
+++ b/CHANGES/901.bugfix.rst
@@ -0,0 +1,1 @@
+Fixed false-positive coercing of Union types in API methods
diff --git a/aiogram/methods/base.py b/aiogram/methods/base.py
index 4d787a7b..2a42bd09 100644
--- a/aiogram/methods/base.py
+++ b/aiogram/methods/base.py
@@ -46,6 +46,7 @@ class TelegramMethod(abc.ABC, BaseModel, Generic[TelegramType]):
         allow_population_by_field_name = True
         arbitrary_types_allowed = True
         orm_mode = True
+        smart_union = True  # https://github.com/aiogram/aiogram/issues/901
 
     @root_validator(pre=True)
     def remove_unset(cls, values: Dict[str, Any]) -> Dict[str, Any]:
diff --git a/aiogram/types/force_reply.py b/aiogram/types/force_reply.py
index b69ad94c..bd8e8900 100644
--- a/aiogram/types/force_reply.py
+++ b/aiogram/types/force_reply.py
@@ -2,6 +2,8 @@ from __future__ import annotations
 
 from typing import Optional
 
+from pydantic import Field
+
 from .base import MutableTelegramObject
 
 
@@ -19,7 +21,7 @@ class ForceReply(MutableTelegramObject):
     Source: https://core.telegram.org/bots/api#forcereply
     """
 
-    force_reply: bool
+    force_reply: bool = Field(True, const=True)
     """Shows reply interface to the user, as if they manually selected the bot's message and tapped 'Reply'"""
     input_field_placeholder: Optional[str] = None
     """*Optional*. The placeholder to be shown in the input field when the reply is active; 1-64 characters"""


Test patch:
diff --git a/tests/test_api/test_methods/test_send_message.py b/tests/test_api/test_methods/test_send_message.py
index c2da672e..35324f34 100644
--- a/tests/test_api/test_methods/test_send_message.py
+++ b/tests/test_api/test_methods/test_send_message.py
@@ -3,7 +3,7 @@ import datetime
 import pytest
 
 from aiogram.methods import Request, SendMessage
-from aiogram.types import Chat, Message
+from aiogram.types import Chat, ForceReply, Message
 from tests.mocked_bot import MockedBot
 
 pytestmark = pytest.mark.asyncio
@@ -43,3 +43,8 @@ class TestSendMessage:
         request: Request = bot.get_request()
         assert request.method == "sendMessage"
         assert response == prepare_result.result
+
+    async def test_force_reply(self):
+        # https://github.com/aiogram/aiogram/issues/901
+        method = SendMessage(text="test", chat_id=42, reply_markup=ForceReply())
+        assert isinstance(method.reply_markup, ForceReply)