Paid media

Content creators can accept Stars by publishing paid photos or videos on their channels. Subscribers will be allowed to view such posts only after paying the author to unlock them.

Creators can then withdraw Stars using the Toncoin cryptocurrency », or use them to advertise their channel and get even more subscribers – all of this with next to 0 commission from Telegram.

Posting paid media

channelFull#bbab348d flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet = ChatFull;

inputMediaPaidMedia#aa661fc3 stars_amount:long extended_media:Vector<InputMedia> = InputMedia;

---functions---

messages.sendMedia#7852834e flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true peer:InputPeer reply_to:flags.0?InputReplyTo media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long = Updates;

Channel administrators may forward or post paid media if the channelFull.paid_media_allowed flag is set.

To post paid media, use messages.sendMedia, passing an inputMediaPaidMedia constructor, containing:

Viewing paid media

messageExtendedMediaPreview#ad628cc8 flags:# w:flags.0?int h:flags.0?int thumb:flags.1?PhotoSize video_duration:flags.2?int = MessageExtendedMedia;
messageExtendedMedia#ee479c64 media:MessageMedia = MessageExtendedMedia;

messageMediaPaidMedia#a8852491 stars_amount:long extended_media:Vector<MessageExtendedMedia> = MessageMedia;

inputInvoiceMessage#c5b56859 peer:InputPeer msg_id:int = InputInvoice;

updateMessageExtendedMedia#d5a41724 peer:Peer msg_id:int extended_media:Vector<MessageExtendedMedia> = Update;

starsTransaction#2db5418f flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true id:string stars:long date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector<MessageMedia> = StarsTransaction;

---functions---

messages.getExtendedMedia#84f80814 peer:InputPeer id:Vector<int> = Updates;

Paid media is represented by a messageMediaPaidMedia constructor, containing:

To purchase paid media, follow the usual payment flow », passing an inputInvoiceMessage with the peer and message ID of the paid media.

Once the payment succeds, an updateMessageExtendedMedia will be emitted, replacing the messageExtendedMediaPreview constructors associated with the message with messageExtendedMedia constructors.
No other updates will be emitted (i.e. no updateEditChannelMessage updates will be emitted for the message containing the paid media, even if re-fetching the same messages through other means like messages.getHistory will return the revealed messageExtendedMedia constructors).

The associated starsTransaction that will be generated will be of type starsTransactionPeer (with peer equal to the channel), msg_id equal to the message ID of the paid media and extended_media set to the revealed paid media.

Note: the updateMessageExtendedMedia update does not have a pts/qts field.
This means that this update can only be received passively via the socket (see here »), and it cannot be returned by updates.getDifference or updates.getChannelDifference.
This implies that if a certain client is offline, and another session purchases a paid media, the first client will not receive the revealed messageExtendedMedia constructors when it reconnects to the server, and it would have no way to know that a cached paid media can be revealed to the user.

To bypass this issue, if:

  • One or more messages containing not-yet-bought paid media are visible to the user.

  • From the messages selected above, include only messages received before the client last went offline (i.e. exclude paid media messages that were received and cached via updates or getHistory/getMessages/etc N seconds ago, and the client connected to the server M >= N seconds ago).

  • From the messages selected above, include only messages for which messages.getExtendedMedia was called more than 15 seconds ago.

  • For all messages satisfying the above conditions, make a single query to messages.getExtendedMedia, aggregating matching message IDs in id.
    The method will return an array of updateMessageExtendedMedia updates, only for passed messages containing already bought paid media.
    No information will be returned for passed messages containing not yet bought paid media, or not containing paid media.

    Repeat the method call every 15 seconds if at least one of the messages satisfying the above conditions is still visible.
    Repeat the method call immediately if a new paid message satisfying the above conditions scrolls into view.