mirror of
https://github.com/MarshalX/telegram-crawler.git
synced 2025-01-11 12:41:37 +01:00
Update content of files
This commit is contained in:
parent
d05905f3e9
commit
ab46330a7f
1 changed files with 114 additions and 81 deletions
|
@ -44,63 +44,65 @@
|
|||
|
||||
<div id="dev_page_content"><!-- scroll_nav -->
|
||||
|
||||
<!-- a24af0992245f838f2b4b418a0a2d5fa9caa27b5 -->
|
||||
|
||||
<p>Many constructors in the API need to be stored in a local database upon reception and should only ever be updated reactively (passively) when received via updates or by other means (as specified in the documentation), to avoid overloading the server by continuously requesting changes for the same unchanged information. </p>
|
||||
<p><a href="/constructor/user">user</a>, <a href="/constructor/chat">chat</a>, <a href="/constructor/channel">channel</a> constructors and their full counterparts <a href="/constructor/userFull">userFull</a>, <a href="/constructor/chatFull">chatFull</a>, <a href="/constructor/channelFull">channelFull</a> are especially important, because they contain important information about users, bots, chats and channels (from now on, <em>peers</em>), and most importantly the <code>access_hash</code> value, <strong>required</strong> to interact with peers in the API. </p>
|
||||
<p>This page describes exactly how and when should the local databases of the constructors listed above be refreshed, and contains a more detailed description of basic peer-related concepts. </p>
|
||||
<blockquote>
|
||||
<p>For simplicity, the documentation often uses the term “cache” instead of “database” when referring to the peer database, however note that it is recommended to persist received information (or at the very least the id+access hash) to a database, to call methods requiring the access hash and view other peer info without refetching the chat history and peer info after startup. </p>
|
||||
<p>For simplicity, the documentation often uses the term "cache" instead of "database" when referring to the peer database, however note that it is recommended to persist received information (or at the very least the id+access hash) to a database, to call methods requiring the access hash and view other peer info without refetching the chat history and peer info after startup. </p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" name="peer-info-database" href="#peer-info-database"><i class="anchor-icon"></i></a>Peer info database</h3>
|
||||
<pre><code>userEmpty#d3bc4b7a id:long = User;
|
||||
user#83314fca flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# bot_can_edit:flags2.1?true close_friend:flags2.2?true stories_hidden:flags2.3?true stories_unavailable:flags2.4?true contact_require_premium:flags2.10?true bot_business:flags2.11?true bot_has_main_app:flags2.13?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector<Username> stories_max_id:flags2.5?int color:flags2.8?PeerColor profile_color:flags2.9?PeerColor bot_active_users:flags2.12?int = User;
|
||||
<h3><a class="anchor" href="#peer-info-database" id="peer-info-database" name="peer-info-database"><i class="anchor-icon"></i></a>Peer info database</h3>
|
||||
<pre><code><a href='/constructor/userEmpty'>userEmpty</a>#d3bc4b7a id:<a href='/type/long'>long</a> = <a href='/type/User'>User</a>;
|
||||
<a href='/constructor/user'>user</a>#83314fca flags:<a href='/type/%23'>#</a> self:flags.10?<a href='/constructor/true'>true</a> contact:flags.11?<a href='/constructor/true'>true</a> mutual_contact:flags.12?<a href='/constructor/true'>true</a> deleted:flags.13?<a href='/constructor/true'>true</a> bot:flags.14?<a href='/constructor/true'>true</a> bot_chat_history:flags.15?<a href='/constructor/true'>true</a> bot_nochats:flags.16?<a href='/constructor/true'>true</a> verified:flags.17?<a href='/constructor/true'>true</a> restricted:flags.18?<a href='/constructor/true'>true</a> min:flags.20?<a href='/constructor/true'>true</a> bot_inline_geo:flags.21?<a href='/constructor/true'>true</a> support:flags.23?<a href='/constructor/true'>true</a> scam:flags.24?<a href='/constructor/true'>true</a> apply_min_photo:flags.25?<a href='/constructor/true'>true</a> fake:flags.26?<a href='/constructor/true'>true</a> bot_attach_menu:flags.27?<a href='/constructor/true'>true</a> premium:flags.28?<a href='/constructor/true'>true</a> attach_menu_enabled:flags.29?<a href='/constructor/true'>true</a> flags2:<a href='/type/%23'>#</a> bot_can_edit:flags2.1?<a href='/constructor/true'>true</a> close_friend:flags2.2?<a href='/constructor/true'>true</a> stories_hidden:flags2.3?<a href='/constructor/true'>true</a> stories_unavailable:flags2.4?<a href='/constructor/true'>true</a> contact_require_premium:flags2.10?<a href='/constructor/true'>true</a> bot_business:flags2.11?<a href='/constructor/true'>true</a> bot_has_main_app:flags2.13?<a href='/constructor/true'>true</a> id:<a href='/type/long'>long</a> access_hash:flags.0?<a href='/type/long'>long</a> first_name:flags.1?<a href='/type/string'>string</a> last_name:flags.2?<a href='/type/string'>string</a> username:flags.3?<a href='/type/string'>string</a> phone:flags.4?<a href='/type/string'>string</a> photo:flags.5?<a href='/type/UserProfilePhoto'>UserProfilePhoto</a> status:flags.6?<a href='/type/UserStatus'>UserStatus</a> bot_info_version:flags.14?<a href='/type/int'>int</a> restriction_reason:flags.18?<a href='/type/Vector%20t'>Vector</a><<a href='/type/RestrictionReason'>RestrictionReason</a>> bot_inline_placeholder:flags.19?<a href='/type/string'>string</a> lang_code:flags.22?<a href='/type/string'>string</a> emoji_status:flags.30?<a href='/type/EmojiStatus'>EmojiStatus</a> usernames:flags2.0?<a href='/type/Vector%20t'>Vector</a><<a href='/type/Username'>Username</a>> stories_max_id:flags2.5?<a href='/type/int'>int</a> color:flags2.8?<a href='/type/PeerColor'>PeerColor</a> profile_color:flags2.9?<a href='/type/PeerColor'>PeerColor</a> bot_active_users:flags2.12?<a href='/type/int'>int</a> = <a href='/type/User'>User</a>;
|
||||
|
||||
chatEmpty#29562865 id:long = Chat;
|
||||
chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
|
||||
chatForbidden#6592a1a7 id:long title:string = Chat;
|
||||
<a href='/constructor/chatEmpty'>chatEmpty</a>#29562865 id:<a href='/type/long'>long</a> = <a href='/type/Chat'>Chat</a>;
|
||||
<a href='/constructor/chat'>chat</a>#41cbf256 flags:<a href='/type/%23'>#</a> creator:flags.0?<a href='/constructor/true'>true</a> left:flags.2?<a href='/constructor/true'>true</a> deactivated:flags.5?<a href='/constructor/true'>true</a> call_active:flags.23?<a href='/constructor/true'>true</a> call_not_empty:flags.24?<a href='/constructor/true'>true</a> noforwards:flags.25?<a href='/constructor/true'>true</a> id:<a href='/type/long'>long</a> title:<a href='/type/string'>string</a> photo:<a href='/type/ChatPhoto'>ChatPhoto</a> participants_count:<a href='/type/int'>int</a> date:<a href='/type/int'>int</a> version:<a href='/type/int'>int</a> migrated_to:flags.6?<a href='/type/InputChannel'>InputChannel</a> admin_rights:flags.14?<a href='/type/ChatAdminRights'>ChatAdminRights</a> default_banned_rights:flags.18?<a href='/type/ChatBannedRights'>ChatBannedRights</a> = <a href='/type/Chat'>Chat</a>;
|
||||
<a href='/constructor/chatForbidden'>chatForbidden</a>#6592a1a7 id:<a href='/type/long'>long</a> title:<a href='/type/string'>string</a> = <a href='/type/Chat'>Chat</a>;
|
||||
|
||||
channel#aadfc8f flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector<Username> stories_max_id:flags2.4?int color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int = Chat;
|
||||
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
|
||||
<a href='/constructor/channel'>channel</a>#aadfc8f flags:<a href='/type/%23'>#</a> creator:flags.0?<a href='/constructor/true'>true</a> left:flags.2?<a href='/constructor/true'>true</a> broadcast:flags.5?<a href='/constructor/true'>true</a> verified:flags.7?<a href='/constructor/true'>true</a> megagroup:flags.8?<a href='/constructor/true'>true</a> restricted:flags.9?<a href='/constructor/true'>true</a> signatures:flags.11?<a href='/constructor/true'>true</a> min:flags.12?<a href='/constructor/true'>true</a> scam:flags.19?<a href='/constructor/true'>true</a> has_link:flags.20?<a href='/constructor/true'>true</a> has_geo:flags.21?<a href='/constructor/true'>true</a> slowmode_enabled:flags.22?<a href='/constructor/true'>true</a> call_active:flags.23?<a href='/constructor/true'>true</a> call_not_empty:flags.24?<a href='/constructor/true'>true</a> fake:flags.25?<a href='/constructor/true'>true</a> gigagroup:flags.26?<a href='/constructor/true'>true</a> noforwards:flags.27?<a href='/constructor/true'>true</a> join_to_send:flags.28?<a href='/constructor/true'>true</a> join_request:flags.29?<a href='/constructor/true'>true</a> forum:flags.30?<a href='/constructor/true'>true</a> flags2:<a href='/type/%23'>#</a> stories_hidden:flags2.1?<a href='/constructor/true'>true</a> stories_hidden_min:flags2.2?<a href='/constructor/true'>true</a> stories_unavailable:flags2.3?<a href='/constructor/true'>true</a> id:<a href='/type/long'>long</a> access_hash:flags.13?<a href='/type/long'>long</a> title:<a href='/type/string'>string</a> username:flags.6?<a href='/type/string'>string</a> photo:<a href='/type/ChatPhoto'>ChatPhoto</a> date:<a href='/type/int'>int</a> restriction_reason:flags.9?<a href='/type/Vector%20t'>Vector</a><<a href='/type/RestrictionReason'>RestrictionReason</a>> admin_rights:flags.14?<a href='/type/ChatAdminRights'>ChatAdminRights</a> banned_rights:flags.15?<a href='/type/ChatBannedRights'>ChatBannedRights</a> default_banned_rights:flags.18?<a href='/type/ChatBannedRights'>ChatBannedRights</a> participants_count:flags.17?<a href='/type/int'>int</a> usernames:flags2.0?<a href='/type/Vector%20t'>Vector</a><<a href='/type/Username'>Username</a>> stories_max_id:flags2.4?<a href='/type/int'>int</a> color:flags2.7?<a href='/type/PeerColor'>PeerColor</a> profile_color:flags2.8?<a href='/type/PeerColor'>PeerColor</a> emoji_status:flags2.9?<a href='/type/EmojiStatus'>EmojiStatus</a> level:flags2.10?<a href='/type/int'>int</a> = <a href='/type/Chat'>Chat</a>;
|
||||
<a href='/constructor/channelForbidden'>channelForbidden</a>#17d493d5 flags:<a href='/type/%23'>#</a> broadcast:flags.5?<a href='/constructor/true'>true</a> megagroup:flags.8?<a href='/constructor/true'>true</a> id:<a href='/type/long'>long</a> access_hash:<a href='/type/long'>long</a> title:<a href='/type/string'>string</a> until_date:flags.16?<a href='/type/int'>int</a> = <a href='/type/Chat'>Chat</a>;
|
||||
|
||||
inputUserEmpty#b98886cf = InputUser;
|
||||
inputUserSelf#f7c1b13f = InputUser;
|
||||
inputUser#f21158c6 user_id:long access_hash:long = InputUser;
|
||||
inputUserFromMessage#1da448e2 peer:InputPeer msg_id:int user_id:long = InputUser;
|
||||
<a href='/constructor/inputUserEmpty'>inputUserEmpty</a>#b98886cf = <a href='/type/InputUser'>InputUser</a>;
|
||||
<a href='/constructor/inputUserSelf'>inputUserSelf</a>#f7c1b13f = <a href='/type/InputUser'>InputUser</a>;
|
||||
<a href='/constructor/inputUser'>inputUser</a>#f21158c6 user_id:<a href='/type/long'>long</a> access_hash:<a href='/type/long'>long</a> = <a href='/type/InputUser'>InputUser</a>;
|
||||
<a href='/constructor/inputUserFromMessage'>inputUserFromMessage</a>#1da448e2 peer:<a href='/type/InputPeer'>InputPeer</a> msg_id:<a href='/type/int'>int</a> user_id:<a href='/type/long'>long</a> = <a href='/type/InputUser'>InputUser</a>;
|
||||
|
||||
// No inputChat, just a long is used (because basic chats don't have access hashes)
|
||||
// No inputChat, just a long is used (because basic chats don't have access hashes)
|
||||
|
||||
inputChannelEmpty#ee8c1e86 = InputChannel;
|
||||
inputChannel#f35aec28 channel_id:long access_hash:long = InputChannel;
|
||||
inputChannelFromMessage#5b934f9d peer:InputPeer msg_id:int channel_id:long = InputChannel;
|
||||
<a href='/constructor/inputChannelEmpty'>inputChannelEmpty</a>#ee8c1e86 = <a href='/type/InputChannel'>InputChannel</a>;
|
||||
<a href='/constructor/inputChannel'>inputChannel</a>#f35aec28 channel_id:<a href='/type/long'>long</a> access_hash:<a href='/type/long'>long</a> = <a href='/type/InputChannel'>InputChannel</a>;
|
||||
<a href='/constructor/inputChannelFromMessage'>inputChannelFromMessage</a>#5b934f9d peer:<a href='/type/InputPeer'>InputPeer</a> msg_id:<a href='/type/int'>int</a> channel_id:<a href='/type/long'>long</a> = <a href='/type/InputChannel'>InputChannel</a>;
|
||||
|
||||
inputPeerEmpty#7f3b18ea = InputPeer;
|
||||
inputPeerSelf#7da07ec9 = InputPeer;
|
||||
inputPeerChat#35a95cb9 chat_id:long = InputPeer;
|
||||
inputPeerUser#dde8a54c user_id:long access_hash:long = InputPeer;
|
||||
inputPeerChannel#27bcbbfc channel_id:long access_hash:long = InputPeer;
|
||||
inputPeerUserFromMessage#a87b0a1c peer:InputPeer msg_id:int user_id:long = InputPeer;
|
||||
inputPeerChannelFromMessage#bd2a0840 peer:InputPeer msg_id:int channel_id:long = InputPeer;
|
||||
<a href='/constructor/inputPeerEmpty'>inputPeerEmpty</a>#7f3b18ea = <a href='/type/InputPeer'>InputPeer</a>;
|
||||
<a href='/constructor/inputPeerSelf'>inputPeerSelf</a>#7da07ec9 = <a href='/type/InputPeer'>InputPeer</a>;
|
||||
<a href='/constructor/inputPeerChat'>inputPeerChat</a>#35a95cb9 chat_id:<a href='/type/long'>long</a> = <a href='/type/InputPeer'>InputPeer</a>;
|
||||
<a href='/constructor/inputPeerUser'>inputPeerUser</a>#dde8a54c user_id:<a href='/type/long'>long</a> access_hash:<a href='/type/long'>long</a> = <a href='/type/InputPeer'>InputPeer</a>;
|
||||
<a href='/constructor/inputPeerChannel'>inputPeerChannel</a>#27bcbbfc channel_id:<a href='/type/long'>long</a> access_hash:<a href='/type/long'>long</a> = <a href='/type/InputPeer'>InputPeer</a>;
|
||||
<a href='/constructor/inputPeerUserFromMessage'>inputPeerUserFromMessage</a>#a87b0a1c peer:<a href='/type/InputPeer'>InputPeer</a> msg_id:<a href='/type/int'>int</a> user_id:<a href='/type/long'>long</a> = <a href='/type/InputPeer'>InputPeer</a>;
|
||||
<a href='/constructor/inputPeerChannelFromMessage'>inputPeerChannelFromMessage</a>#bd2a0840 peer:<a href='/type/InputPeer'>InputPeer</a> msg_id:<a href='/type/int'>int</a> channel_id:<a href='/type/long'>long</a> = <a href='/type/InputPeer'>InputPeer</a>;
|
||||
|
||||
---functions---
|
||||
|
||||
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
||||
messages.getChats#49e9528f id:Vector<long> = messages.Chats;
|
||||
channels.getChannels#a7f6bbb id:Vector<InputChannel> = messages.Chats;</code></pre>
|
||||
<p>The peer info database contains the following information:<br><em> The <a href="#peer-id">peer ID »</a>
|
||||
</em> The <a href="#access-hash">access hash »</a><br>* <a href="#other-info">Other info »</a></p>
|
||||
<a href='/method/users.getUsers'>users.getUsers</a>#d91a548 id:<a href='/type/Vector%20t'>Vector</a><<a href='/type/InputUser'>InputUser</a>> = <a href='/type/Vector%20t'>Vector</a><<a href='/type/User'>User</a>>;
|
||||
<a href='/method/messages.getChats'>messages.getChats</a>#49e9528f id:<a href='/type/Vector%20t'>Vector</a><<a href='/type/long'>long</a>> = <a href='/type/messages.Chats'>messages.Chats</a>;
|
||||
<a href='/method/channels.getChannels'>channels.getChannels</a>#a7f6bbb id:<a href='/type/Vector%20t'>Vector</a><<a href='/type/InputChannel'>InputChannel</a>> = <a href='/type/messages.Chats'>messages.Chats</a>;</code></pre>
|
||||
<p>The peer info database contains the following information: </p>
|
||||
<ul>
|
||||
<li>The <a href="#peer-id">peer ID »</a></li>
|
||||
<li>The <a href="#access-hash">access hash »</a></li>
|
||||
<li><a href="#other-info">Other info »</a></li>
|
||||
</ul>
|
||||
<p>And it must be populated as follows:</p>
|
||||
<ul>
|
||||
<li><a href="#saving-constructors">By saving received user, chat, channel constructors »</a></li>
|
||||
<li><a href="#handling-certain-updates">By handling certain updates »</a></li>
|
||||
<li><a href="#manual-refreshes">By manual refreshes »</a></li>
|
||||
<li><a href="#saving-constructors">By saving received user, chat, channel constructors »</a></li>
|
||||
<li><a href="#handling-certain-updates">By handling certain updates »</a></li>
|
||||
<li><a href="#manual-refreshes">By manual refreshes »</a></li>
|
||||
</ul>
|
||||
<p>Example implementation: <a href="https://github.com/tdlib/td/">tdlib</a>.</p>
|
||||
<h4><a class="anchor" name="saving-constructors" href="#saving-constructors"><i class="anchor-icon"></i></a>Saving constructors</h4>
|
||||
<p>The peer info database needs to be updated every time a new constructor of type <a href="/constructor/user">user</a>, <a href="/constructor/chat">chat</a> and <a href="/constructor/channel">channel</a> (and their <code>forbidden</code> counterparts, used for peers that the user can't access, but can view basic info about) is received. </p>
|
||||
<p>These constructors are received when interacting with the API (i.e. in common chats, through the search function, <a href="/api/invites#public-usernames">username resolution</a>, <a href="/api/links#temporary-profile-links">temporary profile links</a>, and so on…). </p>
|
||||
<p>Unless specified otherwise (see the constructor pages for the special cases), when updating the local peer database, all fields from the newly received constructor take priority over the old constructor cached locally (including by removing fields that aren't set in the new constructor). </p>
|
||||
<h4><a class="anchor" name="handling-certain-updates" href="#handling-certain-updates"><i class="anchor-icon"></i></a>Handling certain updates</h4>
|
||||
<h4><a class="anchor" href="#saving-constructors" id="saving-constructors" name="saving-constructors"><i class="anchor-icon"></i></a>Saving constructors</h4>
|
||||
<p>The peer info database needs to be updated every time a new constructor of type <a href="/constructor/user">user</a>, <a href="/constructor/chat">chat</a> and <a href="/constructor/channel">channel</a> (and their <code>forbidden</code> counterparts, used for peers that the user can't access, but can view basic info about) is received. </p>
|
||||
<p>These constructors are received when interacting with the API (i.e. in common chats, through the search function, <a href="/api/invites#public-usernames">username resolution</a>, <a href="/api/links#temporary-profile-links">temporary profile links</a>, and so on...). </p>
|
||||
<p>Unless specified otherwise (see the constructor pages for the special cases), when updating the local peer database, all fields from the newly received constructor take priority over the old constructor cached locally (including by removing fields that aren't set in the new constructor). </p>
|
||||
<h4><a class="anchor" href="#handling-certain-updates" id="handling-certain-updates" name="handling-certain-updates"><i class="anchor-icon"></i></a>Handling certain updates</h4>
|
||||
<p>The following updates should trigger an update of a small subset of the info contained in the peer database (both non-full and <a href="#full-info-database">full variants</a>):</p>
|
||||
<ul>
|
||||
<li><a href="/constructor/updateUserStatus">updateUserStatus</a> - Update <a href="/constructor/user">user</a>.<code>status</code></li>
|
||||
|
@ -113,74 +115,106 @@ channels.getChannels#a7f6bbb id:Vector<InputChannel> = messages.Chats;</co
|
|||
<li><a href="/constructor/updateChatParticipant">updateChatParticipant</a> - Update <a href="/constructor/chat">chat</a>.<code>participants_count</code>, <a href="/constructor/chatFull">chatFull</a>.<code>participants</code>. </li>
|
||||
<li><a href="/constructor/updateChannelAvailableMessages">updateChannelAvailableMessages</a> - Update <a href="/constructor/channel">channel</a>.<code>hidden_prehistory</code></li>
|
||||
</ul>
|
||||
<h4><a class="anchor" name="manual-refreshes" href="#manual-refreshes"><i class="anchor-icon"></i></a>Manual refreshes</h4>
|
||||
<h4><a class="anchor" href="#manual-refreshes" id="manual-refreshes" name="manual-refreshes"><i class="anchor-icon"></i></a>Manual refreshes</h4>
|
||||
<p>For performance reasons, the server will not always send updates containing updated information about all peers: for this reason, information about <em>already cached</em> peers may be refreshed manually in certain conditions using the bulked <a href="/method/users.getUsers">users.getUsers</a>, <a href="/method/messages.getChats">messages.getChats</a>, <a href="/method/channels.getChannels">channels.getChannels</a> methods, all requiring the previously cached <code>access_hash</code>. </p>
|
||||
<p>The following list is non-exhaustive, and clients may choose to refresh peer information in some other conditions as well (i.e. when opening the profile page, etc). </p>
|
||||
<ul>
|
||||
<li>When fetching info about one of the following internal user IDs, if the info isn't already cached or if the cached info is <code>min</code>: 777000 (service notifications user), 1271266957 (replies bot), 1087968824 (anonymous bot), 136817688 (channel bot), 5434988373 (antispam bot).<br>Info about these IDs may be fetched with the zero access hash even by users. </li>
|
||||
<li>After invoking <a href="/method/bots.setBotInfo">bots.setBotInfo</a> after changing <code>name</code> (but <strong>not</strong> the <code>about</code> or the <code>description</code>, as changing those fields already triggers a refresh of the full info database, and with it the peer database), for the bot whose info we changed</li>
|
||||
<li>After receiving a <code>CHAT_FORWARDS_RESTRICTED</code> error when forwarding messages from a chat, to refresh info about the source chat (i.e. the fact that we received this error means that the client didn't locally prevent the user from forwarding a message from the protected chat, because the locally cached <a href="/constructor/channel">channel</a>.<code>noforwards</code>/<a href="/constructor/chat">chat</a>.<code>noforwards</code> flag is out of date).</li>
|
||||
<li>After receiving a <code>CHAT_GUEST_SEND_FORBIDDEN</code> error when sending messages to a <a href="/api/discussion">discussion group</a>, to refresh info about the discussion group (i.e. the fact that we received this error means that the client didn't locally prevent the non-member user from sending a message to a discussion group where only members can send messages, because the locally cached <a href="/constructor/channel">channel</a>.<code>join_to_send</code> flag is out of date).</li>
|
||||
<li>After receiving a <code>USER_NOT_PARTICIPANT</code> error when calling <a href="/method/channels.leaveChannel">channels.leaveChannel</a>, to refresh info about the channel/supergroup (i.e. the fact that we received this error means that the client tried to leave a channel/supergroup they're not a member of, and the client didn't try to prevent this locally because its <a href="/constructor/channel">channel</a> constructor is out of date). </li>
|
||||
<li><p>After invoking the following methods (both if the call succeds and after receiving a <code>USERNAME_NOT_MODIFIED</code> error, which is also a success):</p>
|
||||
<li>
|
||||
<p>When fetching info about one of the following internal user IDs, if the info isn't already cached or if the cached info is <code>min</code>: 777000 (service notifications user), 1271266957 (replies bot), 1087968824 (anonymous bot), 136817688 (channel bot), 5434988373 (antispam bot).<br>
|
||||
Info about these IDs may be fetched with the zero access hash even by users. </p>
|
||||
</li>
|
||||
<li>
|
||||
<p>After invoking <a href="/method/bots.setBotInfo">bots.setBotInfo</a> after changing <code>name</code> (but <strong>not</strong> the <code>about</code> or the <code>description</code>, as changing those fields already triggers a refresh of the full info database, and with it the peer database), for the bot whose info we changed</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>After receiving a <code>CHAT_FORWARDS_RESTRICTED</code> error when forwarding messages from a chat, to refresh info about the source chat (i.e. the fact that we received this error means that the client didn't locally prevent the user from forwarding a message from the protected chat, because the locally cached <a href="/constructor/channel">channel</a>.<code>noforwards</code>/<a href="/constructor/chat">chat</a>.<code>noforwards</code> flag is out of date).</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>After receiving a <code>CHAT_GUEST_SEND_FORBIDDEN</code> error when sending messages to a <a href="/api/discussion">discussion group</a>, to refresh info about the discussion group (i.e. the fact that we received this error means that the client didn't locally prevent the non-member user from sending a message to a discussion group where only members can send messages, because the locally cached <a href="/constructor/channel">channel</a>.<code>join_to_send</code> flag is out of date).</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>After receiving a <code>USER_NOT_PARTICIPANT</code> error when calling <a href="/method/channels.leaveChannel">channels.leaveChannel</a>, to refresh info about the channel/supergroup (i.e. the fact that we received this error means that the client tried to leave a channel/supergroup they're not a member of, and the client didn't try to prevent this locally because its <a href="/constructor/channel">channel</a> constructor is out of date). </p>
|
||||
</li>
|
||||
<li>
|
||||
<p>After invoking the following methods (both if the call succeds and after receiving a <code>USERNAME_NOT_MODIFIED</code> error, which is also a success):</p>
|
||||
<ul>
|
||||
<li><a href="/method/account.toggleUsername">account.toggleUsername</a>, <a href="/method/account.reorderUsernames">account.reorderUsernames</a> - For ourselves</li>
|
||||
<li><a href="/method/bots.toggleUsername">bots.toggleUsername</a>, <a href="/method/bots.reorderUsernames">bots.reorderUsernames</a> - For the bot whose username we updated</li>
|
||||
<li><a href="/method/channels.toggleUsername">channels.toggleUsername</a>, <a href="/method/channels.reorderUsernames">channels.reorderUsernames</a> - For the channel whose username we updated</li>
|
||||
</ul>
|
||||
<p>Info should <strong>only</strong> be manually refreshed with a call to <a href="/method/users.getUsers">users.getUsers</a>, <a href="/method/channels.getChannels">channels.getChannels</a> if the new username order/active username cannot be applied locally (i.e. the method call successfully set as active some username that isn't associated to the peer in our local cache, and so on), otherwise the <code>username</code> and <code>usernames</code> fields of the peer info database should be updated locally, using the info that was passed to the toggle/reorder methods by the user. </p>
|
||||
<p>Info should <strong>only</strong> be manually refreshed with a call to <a href="/method/users.getUsers">users.getUsers</a>, <a href="/method/channels.getChannels">channels.getChannels</a> if the new username order/active username cannot be applied locally (i.e. the method call successfully set as active some username that isn't associated to the peer in our local cache, and so on), otherwise the <code>username</code> and <code>usernames</code> fields of the peer info database should be updated locally, using the info that was passed to the toggle/reorder methods by the user. </p>
|
||||
</li>
|
||||
<li>After invoking the following methods, if the user for whom we set the profile photo is <strong>not</strong> returned in <a href="/constructor/photos.photo">photos.photo</a>.<code>users</code>:<ul>
|
||||
<li>
|
||||
<p>After invoking the following methods, if the user for whom we set the profile photo is <strong>not</strong> returned in <a href="/constructor/photos.photo">photos.photo</a>.<code>users</code>:</p>
|
||||
<ul>
|
||||
<li><a href="/method/photos.updateProfilePhoto">photos.updateProfilePhoto</a></li>
|
||||
<li><a href="/method/photos.uploadProfilePhoto">photos.uploadProfilePhoto</a></li>
|
||||
<li><a href="/method/photos.uploadContactProfilePhoto">photos.uploadContactProfilePhoto</a> - Only if <code>suggest</code> is not set</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>After invoking <a href="/method/photos.deletePhotos">photos.deletePhotos</a>, if the local cache doesn't have any more photos left for the current user after removing the ones passed to the method. </li>
|
||||
<li>After failing to download a peer photo.</li>
|
||||
<li><a href="/method/contacts.getStatuses">contacts.getStatuses</a> should be invoked by clients every <code>70000-100000</code> seconds to update the <a href="/constructor/user">user</a>.<code>status</code> field of contacts.<br>The exact contact status polling interval should be randomly chosen between <code>70000</code> and <code>100000</code>, and re-chosen every time <a href="/method/contacts.getStatuses">contacts.getStatuses</a> is invoked.<br>If a <a href="/method/contacts.getStatuses">contacts.getStatuses</a> query fails, repeat the method call after <code>5</code> to <code>10</code> seconds.</li>
|
||||
<li>
|
||||
<p>After invoking <a href="/method/photos.deletePhotos">photos.deletePhotos</a>, if the local cache doesn't have any more photos left for the current user after removing the ones passed to the method. </p>
|
||||
</li>
|
||||
<li>
|
||||
<p>After failing to download a peer photo.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><a href="/method/contacts.getStatuses">contacts.getStatuses</a> should be invoked by clients every <code>70000-100000</code> seconds to update the <a href="/constructor/user">user</a>.<code>status</code> field of contacts.<br>
|
||||
The exact contact status polling interval should be randomly chosen between <code>70000</code> and <code>100000</code>, and re-chosen every time <a href="/method/contacts.getStatuses">contacts.getStatuses</a> is invoked.<br>
|
||||
If a <a href="/method/contacts.getStatuses">contacts.getStatuses</a> query fails, repeat the method call after <code>5</code> to <code>10</code> seconds.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" name="peer-id" href="#peer-id"><i class="anchor-icon"></i></a>Peer ID</h4>
|
||||
<h4><a class="anchor" href="#peer-id" id="peer-id" name="peer-id"><i class="anchor-icon"></i></a>Peer ID</h4>
|
||||
<p>The peer <code>id</code> is a unique 64-bit ID used to identify a specific user, chat or channel. </p>
|
||||
<p>This field should be used as primary key in the channel, chat and user databases. </p>
|
||||
<p>Note that the ID sequences of users, chats and channels <strong>overlap</strong>, so you must either:<br><em> Use separate tables/hashmaps for <a href="/constructor/user">user</a>s, <a href="/constructor/chat">chat</a>s and <a href="/constructor/channel">channel</a>s OR
|
||||
</em> Transform the peer IDs to bot API IDs as specified <a href="/api/bots/ids">here »</a>, which will allow you to use a single ID sequence (and database) for all three peer types, maintaining uniqueness.<br> In this case, a single table <em>can</em> be used for all peer types, but since the structures of the constructors are different, to avoid useless typechecks it might be a good idea to use three tables, as with the first approach. </p>
|
||||
<p>It's a good idea to transform peer IDs to <a href="/api/bots/ids">bot API IDs</a> even if you do decide to use separate databases, as it will make IDs more visually recognizable both for you and your users, as well as guarantee compatibility with the bot API.</p>
|
||||
<h4><a class="anchor" name="access-hash" href="#access-hash"><i class="anchor-icon"></i></a>Access hash</h4>
|
||||
<p>The <code>access_hash</code> is the second most important field stored in the <a href="#peer-info-database">peer database</a>, used to generate <a href="/type/InputPeer">InputPeer</a>, <a href="/type/InputUser">inputUser</a>, <a href="/type/InputChannel">inputChannel</a> constructors used to interact with peers in the API.<br>Note that <a href="/constructor/chat">chat</a>s (<a href="/api/channel">basic groups »</a>) do not have or need an access hash.<br><a href="/constructor/user">user</a>s and <a href="/constructor/channel">channel</a>s (<a href="/api/channel">supergroups and channels »</a>) have an access hash, and it can come in various flavors:</p>
|
||||
<p>Note that the ID sequences of users, chats and channels <strong>overlap</strong>, so you must either:</p>
|
||||
<ul>
|
||||
<li>Use separate tables/hashmaps for <a href="/constructor/user">user</a>s, <a href="/constructor/chat">chat</a>s and <a href="/constructor/channel">channel</a>s OR</li>
|
||||
<li>Transform the peer IDs to bot API IDs as specified <a href="/api/bots/ids">here »</a>, which will allow you to use a single ID sequence (and database) for all three peer types, maintaining uniqueness.<br>
|
||||
In this case, a single table <em>can</em> be used for all peer types, but since the structures of the constructors are different, to avoid useless typechecks it might be a good idea to use three tables, as with the first approach. </li>
|
||||
</ul>
|
||||
<p>It's a good idea to transform peer IDs to <a href="/api/bots/ids">bot API IDs</a> even if you do decide to use separate databases, as it will make IDs more visually recognizable both for you and your users, as well as guarantee compatibility with the bot API.</p>
|
||||
<h4><a class="anchor" href="#access-hash" id="access-hash" name="access-hash"><i class="anchor-icon"></i></a>Access hash</h4>
|
||||
<p>The <code>access_hash</code> is the second most important field stored in the <a href="#peer-info-database">peer database</a>, used to generate <a href="/type/InputPeer">InputPeer</a>, <a href="/type/InputUser">inputUser</a>, <a href="/type/InputChannel">inputChannel</a> constructors used to interact with peers in the API.<br>
|
||||
Note that <a href="/constructor/chat">chat</a>s (<a href="/api/channel">basic groups »</a>) do not have or need an access hash.<br>
|
||||
<a href="/constructor/user">user</a>s and <a href="/constructor/channel">channel</a>s (<a href="/api/channel">supergroups and channels »</a>) have an access hash, and it can come in various flavors:</p>
|
||||
<ul>
|
||||
<li>Full access hash: can be used everywhere in the API.</li>
|
||||
<li>Min access hash: received from <a href="/api/min">min constructors »</a>, can only be used to fetch profile pictures using <a href="/constructor/inputPeerPhotoFileLocation"><code>inputPeerPhotoFileLocation</code> »</a>. </li>
|
||||
<li>From-message access hash: not a real access hash, constructed as specified <a href="/api/min">here »</a>, must be used when only a min access hash is available locally, but a full access hash is required. </li>
|
||||
<li>Min access hash: received from <a href="/api/min">min constructors »</a>, can only be used to fetch profile pictures using <a href="/constructor/inputPeerPhotoFileLocation"><code>inputPeerPhotoFileLocation</code> »</a>. </li>
|
||||
<li>From-message access hash: not a real access hash, constructed as specified <a href="/api/min">here »</a>, must be used when only a min access hash is available locally, but a full access hash is required. </li>
|
||||
<li>Zero access hash: equal to <code>0</code>, must be used by bots when only a min access hash (or no access hash) is available locally, but a full access hash is required. </li>
|
||||
</ul>
|
||||
<p>The access hash versions listed above are listed in descending priority, and if a version with higher priority is currently cached, it must not be overwritten with a lower priority version. </p>
|
||||
<p>Access hashes are received when interacting with the API (i.e. in common chats, through the search function, <a href="/api/invites#public-usernames">username resolution</a>, <a href="/api/links#temporary-profile-links">temporary profile links</a>, and so on…): if you have only a user/channel/supergroup ID without any kind of access hash, you <strong>cannot</strong> interact with that peer.<br>Access hashes may not be reused across different accounts or different sessions of the same account.<br>This is a core spam prevention feature of Telegram. </p>
|
||||
<p>Access hashes are received when interacting with the API (i.e. in common chats, through the search function, <a href="/api/invites#public-usernames">username resolution</a>, <a href="/api/links#temporary-profile-links">temporary profile links</a>, and so on...): if you have only a user/channel/supergroup ID without any kind of access hash, you <strong>cannot</strong> interact with that peer.<br>
|
||||
Access hashes may not be reused across different accounts or different sessions of the same account.<br>
|
||||
This is a core spam prevention feature of Telegram. </p>
|
||||
<p>Clients and client APIs should avoid exposing access hashes to users, as they cannot be reused outside of the current session, and the user should not be burdened with storing them, when the client can perfectly do the job by itself. </p>
|
||||
<p>Note: some other, non-peer-related constructors (i.e. not <a href="/constructor/user">user</a>, <a href="/constructor/chat">chat</a> or <a href="/constructor/channel">channel</a>) may also contain access hashes, which should be stored in a different database. </p>
|
||||
<h4><a class="anchor" name="other-info" href="#other-info"><i class="anchor-icon"></i></a>Other info</h4>
|
||||
<p>Various other fields commonly used by the client, as specified in the constructor pages (<a href="/constructor/user">user</a>, <a href="/constructor/chat">chat</a> and <a href="/constructor/channel">channel</a>).<br>As specified in the constructor docs, some of the fields must not be overwritten if a <a href="/api/min">min constructor</a> is received, and a change in some other fields must trigger invalidation of the <a href="#full-info-database">full info database »</a>. </p>
|
||||
<h3><a class="anchor" name="full-info-database" href="#full-info-database"><i class="anchor-icon"></i></a>Full info database</h3>
|
||||
<pre><code>users.userFull#3b6d152e full_user:UserFull chats:Vector<Chat> users:Vector<User> = users.UserFull;
|
||||
messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
|
||||
<h4><a class="anchor" href="#other-info" id="other-info" name="other-info"><i class="anchor-icon"></i></a>Other info</h4>
|
||||
<p>Various other fields commonly used by the client, as specified in the constructor pages (<a href="/constructor/user">user</a>, <a href="/constructor/chat">chat</a> and <a href="/constructor/channel">channel</a>).<br>
|
||||
As specified in the constructor docs, some of the fields must not be overwritten if a <a href="/api/min">min constructor</a> is received, and a change in some other fields must trigger invalidation of the <a href="#full-info-database">full info database »</a>. </p>
|
||||
<h3><a class="anchor" href="#full-info-database" id="full-info-database" name="full-info-database"><i class="anchor-icon"></i></a>Full info database</h3>
|
||||
<pre><code><a href='/constructor/users.userFull'>users.userFull</a>#3b6d152e full_user:<a href='/type/UserFull'>UserFull</a> chats:<a href='/type/Vector%20t'>Vector</a><<a href='/type/Chat'>Chat</a>> users:<a href='/type/Vector%20t'>Vector</a><<a href='/type/User'>User</a>> = <a href='/type/users.UserFull'>users.UserFull</a>;
|
||||
<a href='/constructor/messages.chatFull'>messages.chatFull</a>#e5d7d19c full_chat:<a href='/type/ChatFull'>ChatFull</a> chats:<a href='/type/Vector%20t'>Vector</a><<a href='/type/Chat'>Chat</a>> users:<a href='/type/Vector%20t'>Vector</a><<a href='/type/User'>User</a>> = <a href='/type/messages.ChatFull'>messages.ChatFull</a>;
|
||||
|
||||
userFull#cc997720 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme_emoticon:flags.15?string private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights premium_gifts:flags.19?Vector<PremiumGiftOption> wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int = UserFull;
|
||||
chatFull#2633421b flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions reactions_limit:flags.20?int = ChatFull;
|
||||
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;
|
||||
<a href='/constructor/userFull'>userFull</a>#cc997720 flags:<a href='/type/%23'>#</a> blocked:flags.0?<a href='/constructor/true'>true</a> phone_calls_available:flags.4?<a href='/constructor/true'>true</a> phone_calls_private:flags.5?<a href='/constructor/true'>true</a> can_pin_message:flags.7?<a href='/constructor/true'>true</a> has_scheduled:flags.12?<a href='/constructor/true'>true</a> video_calls_available:flags.13?<a href='/constructor/true'>true</a> voice_messages_forbidden:flags.20?<a href='/constructor/true'>true</a> translations_disabled:flags.23?<a href='/constructor/true'>true</a> stories_pinned_available:flags.26?<a href='/constructor/true'>true</a> blocked_my_stories_from:flags.27?<a href='/constructor/true'>true</a> wallpaper_overridden:flags.28?<a href='/constructor/true'>true</a> contact_require_premium:flags.29?<a href='/constructor/true'>true</a> read_dates_private:flags.30?<a href='/constructor/true'>true</a> flags2:<a href='/type/%23'>#</a> sponsored_enabled:flags2.7?<a href='/constructor/true'>true</a> id:<a href='/type/long'>long</a> about:flags.1?<a href='/type/string'>string</a> settings:<a href='/type/PeerSettings'>PeerSettings</a> personal_photo:flags.21?<a href='/type/Photo'>Photo</a> profile_photo:flags.2?<a href='/type/Photo'>Photo</a> fallback_photo:flags.22?<a href='/type/Photo'>Photo</a> notify_settings:<a href='/type/PeerNotifySettings'>PeerNotifySettings</a> bot_info:flags.3?<a href='/type/BotInfo'>BotInfo</a> pinned_msg_id:flags.6?<a href='/type/int'>int</a> common_chats_count:<a href='/type/int'>int</a> folder_id:flags.11?<a href='/type/int'>int</a> ttl_period:flags.14?<a href='/type/int'>int</a> theme_emoticon:flags.15?<a href='/type/string'>string</a> private_forward_name:flags.16?<a href='/type/string'>string</a> bot_group_admin_rights:flags.17?<a href='/type/ChatAdminRights'>ChatAdminRights</a> bot_broadcast_admin_rights:flags.18?<a href='/type/ChatAdminRights'>ChatAdminRights</a> premium_gifts:flags.19?<a href='/type/Vector%20t'>Vector</a><<a href='/type/PremiumGiftOption'>PremiumGiftOption</a>> wallpaper:flags.24?<a href='/type/WallPaper'>WallPaper</a> stories:flags.25?<a href='/type/PeerStories'>PeerStories</a> business_work_hours:flags2.0?<a href='/type/BusinessWorkHours'>BusinessWorkHours</a> business_location:flags2.1?<a href='/type/BusinessLocation'>BusinessLocation</a> business_greeting_message:flags2.2?<a href='/type/BusinessGreetingMessage'>BusinessGreetingMessage</a> business_away_message:flags2.3?<a href='/type/BusinessAwayMessage'>BusinessAwayMessage</a> business_intro:flags2.4?<a href='/type/BusinessIntro'>BusinessIntro</a> birthday:flags2.5?<a href='/type/Birthday'>Birthday</a> personal_channel_id:flags2.6?<a href='/type/long'>long</a> personal_channel_message:flags2.6?<a href='/type/int'>int</a> = <a href='/type/UserFull'>UserFull</a>;
|
||||
<a href='/constructor/chatFull'>chatFull</a>#2633421b flags:<a href='/type/%23'>#</a> can_set_username:flags.7?<a href='/constructor/true'>true</a> has_scheduled:flags.8?<a href='/constructor/true'>true</a> translations_disabled:flags.19?<a href='/constructor/true'>true</a> id:<a href='/type/long'>long</a> about:<a href='/type/string'>string</a> participants:<a href='/type/ChatParticipants'>ChatParticipants</a> chat_photo:flags.2?<a href='/type/Photo'>Photo</a> notify_settings:<a href='/type/PeerNotifySettings'>PeerNotifySettings</a> exported_invite:flags.13?<a href='/type/ExportedChatInvite'>ExportedChatInvite</a> bot_info:flags.3?<a href='/type/Vector%20t'>Vector</a><<a href='/type/BotInfo'>BotInfo</a>> pinned_msg_id:flags.6?<a href='/type/int'>int</a> folder_id:flags.11?<a href='/type/int'>int</a> call:flags.12?<a href='/type/InputGroupCall'>InputGroupCall</a> ttl_period:flags.14?<a href='/type/int'>int</a> groupcall_default_join_as:flags.15?<a href='/type/Peer'>Peer</a> theme_emoticon:flags.16?<a href='/type/string'>string</a> requests_pending:flags.17?<a href='/type/int'>int</a> recent_requesters:flags.17?<a href='/type/Vector%20t'>Vector</a><<a href='/type/long'>long</a>> available_reactions:flags.18?<a href='/type/ChatReactions'>ChatReactions</a> reactions_limit:flags.20?<a href='/type/int'>int</a> = <a href='/type/ChatFull'>ChatFull</a>;
|
||||
<a href='/constructor/channelFull'>channelFull</a>#bbab348d flags:<a href='/type/%23'>#</a> can_view_participants:flags.3?<a href='/constructor/true'>true</a> can_set_username:flags.6?<a href='/constructor/true'>true</a> can_set_stickers:flags.7?<a href='/constructor/true'>true</a> hidden_prehistory:flags.10?<a href='/constructor/true'>true</a> can_set_location:flags.16?<a href='/constructor/true'>true</a> has_scheduled:flags.19?<a href='/constructor/true'>true</a> can_view_stats:flags.20?<a href='/constructor/true'>true</a> blocked:flags.22?<a href='/constructor/true'>true</a> flags2:<a href='/type/%23'>#</a> can_delete_channel:flags2.0?<a href='/constructor/true'>true</a> antispam:flags2.1?<a href='/constructor/true'>true</a> participants_hidden:flags2.2?<a href='/constructor/true'>true</a> translations_disabled:flags2.3?<a href='/constructor/true'>true</a> stories_pinned_available:flags2.5?<a href='/constructor/true'>true</a> view_forum_as_messages:flags2.6?<a href='/constructor/true'>true</a> restricted_sponsored:flags2.11?<a href='/constructor/true'>true</a> can_view_revenue:flags2.12?<a href='/constructor/true'>true</a> paid_media_allowed:flags2.14?<a href='/constructor/true'>true</a> can_view_stars_revenue:flags2.15?<a href='/constructor/true'>true</a> id:<a href='/type/long'>long</a> about:<a href='/type/string'>string</a> participants_count:flags.0?<a href='/type/int'>int</a> admins_count:flags.1?<a href='/type/int'>int</a> kicked_count:flags.2?<a href='/type/int'>int</a> banned_count:flags.2?<a href='/type/int'>int</a> online_count:flags.13?<a href='/type/int'>int</a> read_inbox_max_id:<a href='/type/int'>int</a> read_outbox_max_id:<a href='/type/int'>int</a> unread_count:<a href='/type/int'>int</a> chat_photo:<a href='/type/Photo'>Photo</a> notify_settings:<a href='/type/PeerNotifySettings'>PeerNotifySettings</a> exported_invite:flags.23?<a href='/type/ExportedChatInvite'>ExportedChatInvite</a> bot_info:<a href='/type/Vector%20t'>Vector</a><<a href='/type/BotInfo'>BotInfo</a>> migrated_from_chat_id:flags.4?<a href='/type/long'>long</a> migrated_from_max_id:flags.4?<a href='/type/int'>int</a> pinned_msg_id:flags.5?<a href='/type/int'>int</a> stickerset:flags.8?<a href='/type/StickerSet'>StickerSet</a> available_min_id:flags.9?<a href='/type/int'>int</a> folder_id:flags.11?<a href='/type/int'>int</a> linked_chat_id:flags.14?<a href='/type/long'>long</a> location:flags.15?<a href='/type/ChannelLocation'>ChannelLocation</a> slowmode_seconds:flags.17?<a href='/type/int'>int</a> slowmode_next_send_date:flags.18?<a href='/type/int'>int</a> stats_dc:flags.12?<a href='/type/int'>int</a> pts:<a href='/type/int'>int</a> call:flags.21?<a href='/type/InputGroupCall'>InputGroupCall</a> ttl_period:flags.24?<a href='/type/int'>int</a> pending_suggestions:flags.25?<a href='/type/Vector%20t'>Vector</a><<a href='/type/string'>string</a>> groupcall_default_join_as:flags.26?<a href='/type/Peer'>Peer</a> theme_emoticon:flags.27?<a href='/type/string'>string</a> requests_pending:flags.28?<a href='/type/int'>int</a> recent_requesters:flags.28?<a href='/type/Vector%20t'>Vector</a><<a href='/type/long'>long</a>> default_send_as:flags.29?<a href='/type/Peer'>Peer</a> available_reactions:flags.30?<a href='/type/ChatReactions'>ChatReactions</a> reactions_limit:flags2.13?<a href='/type/int'>int</a> stories:flags2.4?<a href='/type/PeerStories'>PeerStories</a> wallpaper:flags2.7?<a href='/type/WallPaper'>WallPaper</a> boosts_applied:flags2.8?<a href='/type/int'>int</a> boosts_unrestrict:flags2.9?<a href='/type/int'>int</a> emojiset:flags2.10?<a href='/type/StickerSet'>StickerSet</a> = <a href='/type/ChatFull'>ChatFull</a>;
|
||||
|
||||
---functions---
|
||||
|
||||
users.getFullUser#b60f5918 id:InputUser = users.UserFull;
|
||||
messages.getFullChat#aeb00b34 chat_id:long = messages.ChatFull;
|
||||
channels.getFullChannel#8736a09 channel:InputChannel = messages.ChatFull;</code></pre>
|
||||
<a href='/method/users.getFullUser'>users.getFullUser</a>#b60f5918 id:<a href='/type/InputUser'>InputUser</a> = <a href='/type/users.UserFull'>users.UserFull</a>;
|
||||
<a href='/method/messages.getFullChat'>messages.getFullChat</a>#aeb00b34 chat_id:<a href='/type/long'>long</a> = <a href='/type/messages.ChatFull'>messages.ChatFull</a>;
|
||||
<a href='/method/channels.getFullChannel'>channels.getFullChannel</a>#8736a09 channel:<a href='/type/InputChannel'>InputChannel</a> = <a href='/type/messages.ChatFull'>messages.ChatFull</a>;</code></pre>
|
||||
<p>Example implementation: <a href="https://github.com/tdlib/td/">tdlib</a>.</p>
|
||||
<p>The full info database contains info from the <a href="/constructor/userFull">userFull</a>, <a href="/constructor/chatFull">chatFull</a> and <a href="/constructor/channelFull">channelFull</a> constructors. </p>
|
||||
<p>To populate the full info database for a peer, invoke <a href="/method/users.getFullUser">users.getFullUser</a>, <a href="/method/messages.getFullChat">messages.getFullChat</a>, <a href="/method/channels.getFullChannel">channels.getFullChannel</a>, all requiring the previously cached <a href="#access-hash">access_hash »</a>. </p>
|
||||
<p>To populate the full info database for a peer, invoke <a href="/method/users.getFullUser">users.getFullUser</a>, <a href="/method/messages.getFullChat">messages.getFullChat</a>, <a href="/method/channels.getFullChannel">channels.getFullChannel</a>, all requiring the previously cached <a href="#access-hash">access_hash »</a>. </p>
|
||||
<p>Invalidate only <a href="/constructor/userFull">userFull</a> and <a href="/constructor/channelFull">channelFull</a> entries 60 seconds after they are stored.</p>
|
||||
<p>Refresh the full info database when the client needs some data from a full constructor, <strong>and</strong> there is no entry already in the database, or the required entry was invalidated by the TTL, or if:</p>
|
||||
<ul>
|
||||
<li>Some event (specified <a href="#peer-info-database">here »</a>) changes the value of a very specific subset of fields of an entry in the (non-full!) <a href="#peer-info-database">peer info database »</a>.<br>See the documentation in the <a href="/constructor/user">user</a> and <a href="/constructor/channel">channel</a> constructor pages for more info (search for the keyword “invalidate”). </li>
|
||||
<li>When receiving an <a href="/constructor/updateUser">updateUser</a>, <a href="/constructor/updateChat">updateChat</a>, <a href="/constructor/updateChannel">updateChannel</a>, and some other updates, as specified <a href="/type/Update">here »</a></li>
|
||||
<li>Some event (specified <a href="#peer-info-database">here »</a>) changes the value of a very specific subset of fields of an entry in the (non-full!) <a href="#peer-info-database">peer info database »</a>.<br>
|
||||
See the documentation in the <a href="/constructor/user">user</a> and <a href="/constructor/channel">channel</a> constructor pages for more info (search for the keyword "invalidate"). </li>
|
||||
<li>When receiving an <a href="/constructor/updateUser">updateUser</a>, <a href="/constructor/updateChat">updateChat</a>, <a href="/constructor/updateChannel">updateChannel</a>, and some other updates, as specified <a href="/type/Update">here »</a></li>
|
||||
<li>After invoking <a href="/method/bots.setBotInfo">bots.setBotInfo</a> (even on error) after changing <code>about</code> or <code>description</code> (but <strong>not</strong> <code>name</code>), for the bot whose info we changed.</li>
|
||||
<li>After invoking <a href="/method/messages.setChatWallPaper">messages.setChatWallPaper</a> to <em>remove</em> the wallpaper and receiving an error, for the peer whose wallpapers we tried to change, to fetch the correct and updated wallpaper settings. </li>
|
||||
<li>After invoking <a href="/method/messages.setChatAvailableReactions">messages.setChatAvailableReactions</a> and getting an error different from <code>CHAT_NOT_MODIFIED</code>, for the peer whose reaction settings we tried to change. </li>
|
||||
|
@ -189,7 +223,7 @@ channels.getFullChannel#8736a09 channel:InputChannel = messages.ChatFull;</code>
|
|||
<li>The <a href="/constructor/channelFull">channelFull</a>.<code>linked_chat_id</code> of channnel/supergroup A is updated to point to channel/supergroup B, but the <a href="/constructor/channelFull">channelFull</a>.<code>linked_chat_id</code> of channel/supergroup B does not point to channel/supergroup A, refresh the <a href="/constructor/channelFull">channelFull</a> of channel/supergroup B.</li>
|
||||
<li>Info about a bot that is a participant to the channel/supergroup is fetched by other means, but the bot is not contained in <a href="/constructor/channelFull">channelFull</a>.<code>bot_info</code>. </li>
|
||||
<li>If <a href="/constructor/channelFull">channelFull</a>.<code>participants_count</code> is less than <a href="/constructor/channelFull">channelFull</a>.<code>admins_count</code> after a local update of the admin list by other means.</li>
|
||||
<li>If the currently logged in user's <a href="/constructor/inputPrivacyKeyStatusTimestamp">inputPrivacyKeyStatusTimestamp</a> <a href="/api/privacy">privacy setting »</a> was changed, refresh the entire <a href="/constructor/userFull">userFull</a> cache for all users. </li>
|
||||
<li>If the currently logged in user's <a href="/constructor/inputPrivacyKeyStatusTimestamp">inputPrivacyKeyStatusTimestamp</a> <a href="/api/privacy">privacy setting »</a> was changed, refresh the entire <a href="/constructor/userFull">userFull</a> cache for all users. </li>
|
||||
<li>After receiving an error different from <code>USER_NOT_PARTICIPANT</code> when calling <a href="/method/channels.leaveChannel">channels.leaveChannel</a></li>
|
||||
<li>If the profile picture is updated or removed</li>
|
||||
<li>After successfully invoking any of the following methods, for the bot in question:<ul>
|
||||
|
@ -209,22 +243,21 @@ channels.getFullChannel#8736a09 channel:InputChannel = messages.ChatFull;</code>
|
|||
<li>If we banned a chat/supergroup participant specifying a <a href="/constructor/chatBannedRights">chatBannedRights</a>.<code>until_date</code>, the full cache of the chat/supergroup should be refresh for the admin at <code>until_date</code>. </li>
|
||||
</ul>
|
||||
<p>The above list is non-exhaustive, and clients may choose to refresh peer information in some other conditions as well (i.e. when opening the profile page, etc). </p>
|
||||
<h3><a class="anchor" name="quality-of-life-checks" href="#quality-of-life-checks"><i class="anchor-icon"></i></a>Quality of life checks</h3>
|
||||
<h3><a class="anchor" href="#quality-of-life-checks" id="quality-of-life-checks" name="quality-of-life-checks"><i class="anchor-icon"></i></a>Quality of life checks</h3>
|
||||
<p>Note the following: peer information is also used for quality-of-life improvements, i.e. to directly prevent the user from doing an operation that is denied by the peer information, instead of allowing the operation and then showing an error. </p>
|
||||
<p>These improvements should be implemented by all clients, however, the server will also always prevent the user from doing illegal operations, by emitting an appropriate <a href="/api/errors">RPC error</a>, as sometimes it is still possible to make an illegal operation, even if a local check <em>is</em> implemented (see below). </p>
|
||||
<p>Instead of (or along with) preventing users from doing illegal operations on the client side, clients should always provide localized versions of errors returned by the server (as listed in the JSON file downloadable from the <a href="/api/errors">RPC error page</a>), to inform the user as to why an attempted operation has failed. </p>
|
||||
<p>In other words, if the client didn't prevent the failed method call locally because:</p>
|
||||
<p>In other words, if the client didn't prevent the failed method call locally because:</p>
|
||||
<ul>
|
||||
<li>It does not implement a local check for simplicity or</li>
|
||||
<li>It <em>does</em> implement a local check, but:<ul>
|
||||
<li>Peer info is outdated or</li>
|
||||
<li>An update was sent by the server for the peer info, but it wasn't applied in time due to an (unavoidable!) race condition between the server sending the update and the client sending the query.</li>
|
||||
<li>Other unspecified reasons (a new check introduced in a future layer by a new feature, etc…)</li>
|
||||
<li>An update was sent by the server for the peer info, but it wasn't applied in time due to an (unavoidable!) race condition between the server sending the update and the client sending the query.</li>
|
||||
<li>Other unspecified reasons (a new check introduced in a future layer by a new feature, etc...)</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>…it should still let the user know <em>why</em> the query failed, based on the description of the RPC error (if available in the <a href="/api/errors">JSON error database</a>, otherwise by showing the RPC error itself). </p>
|
||||
</div>
|
||||
<p>...it should still let the user know <em>why</em> the query failed, based on the description of the RPC error (if available in the <a href="/api/errors">JSON error database</a>, otherwise by showing the RPC error itself).</p></div>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Reference in a new issue