Files
FragmentAPI/pyfragment/methods/giveaway_premium.py
T
bohd4nx 902b692dcb Refactor methods for Telegram Premium and Stars giveaways
- Added new methods for handling giveaways: `giveaway_premium` and `giveaway_stars`.
- Refactored existing purchase methods into separate files: `purchase_premium.py` and `purchase_stars.py`.
- Removed old premium and stars methods from the codebase.
- Updated `__init__.py` to include new giveaway methods in the public API.
- Introduced new result types for giveaways: `PremiumGiveawayResult` and `StarsGiveawayResult`.
- Updated constants for new giveaway pages.
- Enhanced error handling for configuration and user validation in giveaway methods.
- Updated tests to cover new functionality and refactored existing tests to match new method locations.
2026-03-21 16:05:38 +02:00

140 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import json
from typing import TYPE_CHECKING
import httpx
from pyfragment.types import (
ConfigurationError,
FragmentAPIError,
FragmentError,
UnexpectedError,
UserNotFoundError,
)
from pyfragment.types.constants import BASE_HEADERS, DEVICE, PREMIUM_GIVEAWAY_PAGE
from pyfragment.types.results import PremiumGiveawayResult
from pyfragment.utils import (
execute_transaction_request,
fragment_post,
get_account_info,
get_fragment_hash,
process_transaction,
)
if TYPE_CHECKING:
from pyfragment.client import FragmentClient
# Page-specific headers
HEADERS: dict[str, str] = {
**BASE_HEADERS,
"referer": PREMIUM_GIVEAWAY_PAGE,
"x-aj-referer": PREMIUM_GIVEAWAY_PAGE,
}
async def _search_recipient(
session: httpx.AsyncClient,
fragment_hash: str,
channel: str,
winners: int,
months: int,
) -> str:
result = await fragment_post(
session,
fragment_hash,
HEADERS,
{
"query": channel,
"quantity": winners,
"months": months,
"method": "searchPremiumGiveawayRecipient",
},
)
recipient = result.get("found", {}).get("recipient")
if not recipient:
raise UserNotFoundError(UserNotFoundError.NOT_FOUND.format(username=channel))
return recipient
async def _init_request(
session: httpx.AsyncClient,
fragment_hash: str,
recipient: str,
winners: int,
months: int,
) -> str:
result = await fragment_post(
session,
fragment_hash,
HEADERS,
{
"recipient": recipient,
"quantity": str(winners),
"months": str(months),
"method": "initGiveawayPremiumRequest",
},
)
req_id = result.get("req_id")
if not req_id:
raise FragmentAPIError(FragmentAPIError.NO_REQUEST_ID.format(context="Premium giveaway"))
return req_id
async def giveaway_premium(
client: "FragmentClient",
channel: str,
winners: int,
months: int = 3,
) -> PremiumGiveawayResult:
"""Run a Telegram Premium giveaway for a channel.
Args:
client: Authenticated :class:`FragmentClient` instance.
channel: Channel username (with or without ``@``).
winners: Number of winners — integer from ``1`` to ``24 000``.
months: Premium duration per winner — ``3``, ``6``, or ``12``. Defaults to ``3``.
Returns:
:class:`PremiumGiveawayResult` with ``transaction_id``, ``channel``,
``winners``, and ``months``.
Raises:
ConfigurationError: If ``winners`` is not 124 000 or ``months`` is not 3, 6, or 12.
UserNotFoundError: If the channel is not found on Fragment.
FragmentAPIError: If the Fragment API returns an error.
UnexpectedError: For any other unexpected failure.
"""
if not isinstance(winners, int) or not (1 <= winners <= 24_000):
raise ConfigurationError(ConfigurationError.INVALID_WINNERS_PREMIUM)
if months not in (3, 6, 12):
raise ConfigurationError(ConfigurationError.INVALID_MONTHS)
try:
fragment_hash = await get_fragment_hash(client.cookies, HEADERS, PREMIUM_GIVEAWAY_PAGE, client.timeout)
account = await get_account_info(client)
async with httpx.AsyncClient(cookies=client.cookies, timeout=client.timeout) as session:
recipient = await _search_recipient(session, fragment_hash, channel, winners, months)
req_id = await _init_request(session, fragment_hash, recipient, winners, months)
tx_data = {
"account": json.dumps(account),
"device": DEVICE,
"transaction": 1,
"id": req_id,
"method": "getGiveawayPremiumLink",
}
transaction = await execute_transaction_request(session, HEADERS, tx_data, fragment_hash)
tx_hash = await process_transaction(client, transaction)
return PremiumGiveawayResult(
transaction_id=tx_hash,
channel=channel,
winners=winners,
amount=months,
)
except FragmentError:
raise
except Exception as exc:
raise UnexpectedError(UnexpectedError.UNEXPECTED.format(exc=exc)) from exc