Queer European MD passionate about IT

api.py 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451
  1. """This module provides a python mirror for Telegram bot API.
  2. All methods and parameters are the same as the original json API.
  3. A simple aiohttp asynchronous web client is used to make requests.
  4. """
  5. # Standard library modules
  6. import asyncio
  7. import datetime
  8. import json
  9. import logging
  10. from typing import Union, List
  11. # Third party modules
  12. import aiohttp
  13. import aiohttp.web
  14. class TelegramError(Exception):
  15. """Telegram API exceptions class."""
  16. # noinspection PyUnusedLocal
  17. def __init__(self, error_code=0, description=None, ok=False,
  18. *args, **kwargs):
  19. """Get an error response and return corresponding Exception."""
  20. self._code = error_code
  21. if description is None:
  22. self._description = 'Generic error'
  23. else:
  24. self._description = description
  25. super().__init__(self.description)
  26. @property
  27. def code(self):
  28. """Telegram error code."""
  29. return self._code
  30. @property
  31. def description(self):
  32. """Human-readable description of error."""
  33. return f"Error {self.code}: {self._description}"
  34. class ChatPermissions(dict):
  35. """Actions that a non-administrator user is allowed to take in a chat."""
  36. def __init__(self,
  37. can_send_messages: bool = True,
  38. can_send_media_messages: bool = True,
  39. can_send_polls: bool = True,
  40. can_send_other_messages: bool = True,
  41. can_add_web_page_previews: bool = True,
  42. can_change_info: bool = True,
  43. can_invite_users: bool = True,
  44. can_pin_messages: bool = True):
  45. super().__init__(self)
  46. self['can_send_messages'] = can_send_messages
  47. self['can_send_media_messages'] = can_send_media_messages
  48. self['can_send_polls'] = can_send_polls
  49. self['can_send_other_messages'] = can_send_other_messages
  50. self['can_add_web_page_previews'] = can_add_web_page_previews
  51. self['can_change_info'] = can_change_info
  52. self['can_invite_users'] = can_invite_users
  53. self['can_pin_messages'] = can_pin_messages
  54. class Command(dict):
  55. def __init__(self,
  56. command: str = None,
  57. description: str = None):
  58. super().__init__(self)
  59. self['command'] = command
  60. self['description'] = description
  61. # This class needs to mirror Telegram API, so camelCase method are needed
  62. # noinspection PyPep8Naming
  63. class TelegramBot:
  64. """Provide python method having the same signature as Telegram API methods.
  65. All mirrored methods are camelCase.
  66. """
  67. loop = asyncio.get_event_loop()
  68. app = aiohttp.web.Application()
  69. sessions_timeouts = {
  70. 'getUpdates': dict(
  71. timeout=35,
  72. close=False
  73. ),
  74. 'sendMessage': dict(
  75. timeout=20,
  76. close=False
  77. )
  78. }
  79. _absolute_cooldown_timedelta = datetime.timedelta(seconds=1/30)
  80. _per_chat_cooldown_timedelta = datetime.timedelta(seconds=1)
  81. _allowed_messages_per_group_per_minute = 20
  82. def __init__(self, token):
  83. """Set bot token and store HTTP sessions."""
  84. self._token = token
  85. self.sessions = dict()
  86. self._flood_wait = 0
  87. # Each `telegram_id` key has a list of `datetime.datetime` as value
  88. self.last_sending_time = {
  89. 'absolute': (
  90. datetime.datetime.now()
  91. - self.absolute_cooldown_timedelta
  92. ),
  93. 0: []
  94. }
  95. @property
  96. def token(self):
  97. """Telegram API bot token."""
  98. return self._token
  99. @property
  100. def flood_wait(self):
  101. """Seconds to wait before next API requests."""
  102. return self._flood_wait
  103. @property
  104. def absolute_cooldown_timedelta(self):
  105. """Return time delta to wait between messages (any chat).
  106. Return class value (all bots have the same limits).
  107. """
  108. return self.__class__._absolute_cooldown_timedelta
  109. @property
  110. def per_chat_cooldown_timedelta(self):
  111. """Return time delta to wait between messages in a chat.
  112. Return class value (all bots have the same limits).
  113. """
  114. return self.__class__._per_chat_cooldown_timedelta
  115. @property
  116. def longest_cooldown_timedelta(self):
  117. """Return the longest cooldown timedelta.
  118. Updates sent more than `longest_cooldown_timedelta` ago will be
  119. forgotten.
  120. """
  121. return datetime.timedelta(minutes=1)
  122. @property
  123. def allowed_messages_per_group_per_minute(self):
  124. """Return maximum number of messages allowed in a group per minute.
  125. Group, supergroup and channels are considered.
  126. Return class value (all bots have the same limits).
  127. """
  128. return self.__class__._allowed_messages_per_group_per_minute
  129. @staticmethod
  130. def check_telegram_api_json(response):
  131. """Take a json Telegram response, check it and return its content.
  132. Example of well-formed json Telegram responses:
  133. {
  134. "ok": False,
  135. "error_code": 401,
  136. "description": "Unauthorized"
  137. }
  138. {
  139. "ok": True,
  140. "result": ...
  141. }
  142. """
  143. assert 'ok' in response, (
  144. "All Telegram API responses have an `ok` field."
  145. )
  146. if not response['ok']:
  147. raise TelegramError(**response)
  148. return response['result']
  149. @staticmethod
  150. def adapt_parameters(parameters, exclude=None):
  151. """Build a aiohttp.FormData object from given `parameters`.
  152. Exclude `self`, empty values and parameters in `exclude` list.
  153. Cast integers to string to avoid TypeError during json serialization.
  154. """
  155. if exclude is None:
  156. exclude = []
  157. exclude.append('self')
  158. # quote_fields=False, otherwise some file names cause troubles
  159. data = aiohttp.FormData(quote_fields=False)
  160. for key, value in parameters.items():
  161. if not (key in exclude or value is None):
  162. if (
  163. type(value) in (int, list,)
  164. or (type(value) is dict and 'file' not in value)
  165. ):
  166. value = json.dumps(value, separators=(',', ':'))
  167. data.add_field(key, value)
  168. return data
  169. def get_session(self, api_method):
  170. """According to API method, return proper session and information.
  171. Return a tuple (session, session_must_be_closed)
  172. session : aiohttp.ClientSession
  173. Client session with proper timeout
  174. session_must_be_closed : bool
  175. True if session must be closed after being used once
  176. """
  177. cls = self.__class__
  178. if api_method in cls.sessions_timeouts:
  179. if api_method not in self.sessions:
  180. self.sessions[api_method] = aiohttp.ClientSession(
  181. loop=cls.loop,
  182. timeout=aiohttp.ClientTimeout(
  183. total=cls.sessions_timeouts[api_method]['timeout']
  184. )
  185. )
  186. session = self.sessions[api_method]
  187. session_must_be_closed = cls.sessions_timeouts[api_method]['close']
  188. else:
  189. session = aiohttp.ClientSession(
  190. loop=cls.loop,
  191. timeout=aiohttp.ClientTimeout(total=None)
  192. )
  193. session_must_be_closed = True
  194. return session, session_must_be_closed
  195. def set_flood_wait(self, flood_wait):
  196. """Wait `flood_wait` seconds before next request."""
  197. self._flood_wait = flood_wait
  198. async def prevent_flooding(self, chat_id):
  199. """Await until request may be sent safely.
  200. Telegram flood control won't allow too many API requests in a small
  201. period.
  202. Exact limits are unknown, but less than 30 total private chat messages
  203. per second, less than 1 private message per chat and less than 20
  204. group chat messages per chat per minute should be safe.
  205. """
  206. now = datetime.datetime.now
  207. if type(chat_id) is int and chat_id > 0:
  208. while (
  209. now() < (
  210. self.last_sending_time['absolute']
  211. + self.absolute_cooldown_timedelta
  212. )
  213. ) or (
  214. chat_id in self.last_sending_time
  215. and (
  216. now() < (
  217. self.last_sending_time[chat_id]
  218. + self.per_chat_cooldown_timedelta
  219. )
  220. )
  221. ):
  222. await asyncio.sleep(
  223. self.absolute_cooldown_timedelta.seconds
  224. )
  225. self.last_sending_time[chat_id] = now()
  226. else:
  227. while (
  228. now() < (
  229. self.last_sending_time['absolute']
  230. + self.absolute_cooldown_timedelta
  231. )
  232. ) or (
  233. chat_id in self.last_sending_time
  234. and len(
  235. [
  236. sending_datetime
  237. for sending_datetime in self.last_sending_time[chat_id]
  238. if sending_datetime >= (
  239. now()
  240. - datetime.timedelta(minutes=1)
  241. )
  242. ]
  243. ) >= self.allowed_messages_per_group_per_minute
  244. ) or (
  245. chat_id in self.last_sending_time
  246. and len(self.last_sending_time[chat_id]) > 0
  247. and now() < (
  248. self.last_sending_time[chat_id][-1]
  249. + self.per_chat_cooldown_timedelta
  250. )
  251. ):
  252. await asyncio.sleep(0.5)
  253. if chat_id not in self.last_sending_time:
  254. self.last_sending_time[chat_id] = []
  255. self.last_sending_time[chat_id].append(now())
  256. self.last_sending_time[chat_id] = [
  257. sending_datetime
  258. for sending_datetime in self.last_sending_time[chat_id]
  259. if sending_datetime >= (
  260. now()
  261. - self.longest_cooldown_timedelta
  262. )
  263. ]
  264. self.last_sending_time['absolute'] = now()
  265. return
  266. async def api_request(self, method, parameters=None, exclude=None):
  267. """Return the result of a Telegram bot API request, or an Exception.
  268. Opened sessions will be used more than one time (if appropriate) and
  269. will be closed on `Bot.app.cleanup`.
  270. Result may be a Telegram API json response, None, or Exception.
  271. """
  272. if exclude is None:
  273. exclude = []
  274. if parameters is None:
  275. parameters = {}
  276. response_object = None
  277. session, session_must_be_closed = self.get_session(method)
  278. # Prevent Telegram flood control for all methods having a `chat_id`
  279. if 'chat_id' in parameters:
  280. await self.prevent_flooding(parameters['chat_id'])
  281. parameters = self.adapt_parameters(parameters, exclude=exclude)
  282. try:
  283. async with session.post(
  284. "https://api.telegram.org/bot"
  285. f"{self.token}/{method}",
  286. data=parameters
  287. ) as response:
  288. try:
  289. response_object = self.check_telegram_api_json(
  290. await response.json() # Telegram returns json objects
  291. )
  292. except TelegramError as e:
  293. logging.error(f"API error response - {e}")
  294. if e.code == 420: # Flood error!
  295. try:
  296. flood_wait = int(
  297. e.description.split('_')[-1]
  298. ) + 30
  299. except Exception as e:
  300. logging.error(f"{e}")
  301. flood_wait = 5*60
  302. logging.critical(
  303. "Telegram antiflood control triggered!\n"
  304. f"Wait {flood_wait} seconds before making another "
  305. "request"
  306. )
  307. self.set_flood_wait(flood_wait)
  308. response_object = e
  309. except Exception as e:
  310. logging.error(f"{e}", exc_info=True)
  311. response_object = e
  312. except asyncio.TimeoutError as e:
  313. logging.info(f"{e}: {method} API call timed out")
  314. except Exception as e:
  315. logging.info(f"Unexpected exception:\n{e}")
  316. response_object = e
  317. finally:
  318. if session_must_be_closed and not session.closed:
  319. await session.close()
  320. return response_object
  321. async def getMe(self):
  322. """Get basic information about the bot in form of a User object.
  323. Useful to test `self.token`.
  324. See https://core.telegram.org/bots/api#getme for details.
  325. """
  326. return await self.api_request(
  327. 'getMe',
  328. )
  329. async def getUpdates(self, offset, timeout, limit, allowed_updates):
  330. """Get a list of updates starting from `offset`.
  331. If there are no updates, keep the request hanging until `timeout`.
  332. If there are more than `limit` updates, retrieve them in packs of
  333. `limit`.
  334. Allowed update types (empty list to allow all).
  335. See https://core.telegram.org/bots/api#getupdates for details.
  336. """
  337. return await self.api_request(
  338. method='getUpdates',
  339. parameters=locals()
  340. )
  341. async def setWebhook(self, url=None, certificate=None,
  342. max_connections=None, allowed_updates=None):
  343. """Set or remove a webhook. Telegram will post to `url` new updates.
  344. See https://core.telegram.org/bots/api#setwebhook for details.
  345. """
  346. if type(certificate) is str:
  347. try:
  348. certificate = dict(
  349. file=open(certificate, 'r')
  350. )
  351. except FileNotFoundError as e:
  352. logging.error(f"{e}\nCertificate set to `None`")
  353. certificate = None
  354. result = await self.api_request(
  355. 'setWebhook',
  356. parameters=locals()
  357. )
  358. if type(certificate) is dict: # Close certificate file, if it was open
  359. certificate['file'].close()
  360. return result
  361. async def deleteWebhook(self):
  362. """Remove webhook integration and switch back to getUpdate.
  363. See https://core.telegram.org/bots/api#deletewebhook for details.
  364. """
  365. return await self.api_request(
  366. 'deleteWebhook',
  367. )
  368. async def getWebhookInfo(self):
  369. """Get current webhook status.
  370. See https://core.telegram.org/bots/api#getwebhookinfo for details.
  371. """
  372. return await self.api_request(
  373. 'getWebhookInfo',
  374. )
  375. async def sendMessage(self, chat_id, text,
  376. parse_mode=None,
  377. disable_web_page_preview=None,
  378. disable_notification=None,
  379. reply_to_message_id=None,
  380. reply_markup=None):
  381. """Send a text message. On success, return it.
  382. See https://core.telegram.org/bots/api#sendmessage for details.
  383. """
  384. return await self.api_request(
  385. 'sendMessage',
  386. parameters=locals()
  387. )
  388. async def forwardMessage(self, chat_id, from_chat_id, message_id,
  389. disable_notification=None):
  390. """Forward a message.
  391. See https://core.telegram.org/bots/api#forwardmessage for details.
  392. """
  393. return await self.api_request(
  394. 'forwardMessage',
  395. parameters=locals()
  396. )
  397. async def sendPhoto(self, chat_id, photo,
  398. caption=None,
  399. parse_mode=None,
  400. disable_notification=None,
  401. reply_to_message_id=None,
  402. reply_markup=None):
  403. """Send a photo from file_id, HTTP url or file.
  404. See https://core.telegram.org/bots/api#sendphoto for details.
  405. """
  406. return await self.api_request(
  407. 'sendPhoto',
  408. parameters=locals()
  409. )
  410. async def sendAudio(self, chat_id, audio,
  411. caption=None,
  412. parse_mode=None,
  413. duration=None,
  414. performer=None,
  415. title=None,
  416. thumb=None,
  417. disable_notification=None,
  418. reply_to_message_id=None,
  419. reply_markup=None):
  420. """Send an audio file from file_id, HTTP url or file.
  421. See https://core.telegram.org/bots/api#sendaudio for details.
  422. """
  423. return await self.api_request(
  424. 'sendAudio',
  425. parameters=locals()
  426. )
  427. async def sendDocument(self, chat_id, document,
  428. thumb=None,
  429. caption=None,
  430. parse_mode=None,
  431. disable_notification=None,
  432. reply_to_message_id=None,
  433. reply_markup=None):
  434. """Send a document from file_id, HTTP url or file.
  435. See https://core.telegram.org/bots/api#senddocument for details.
  436. """
  437. return await self.api_request(
  438. 'sendDocument',
  439. parameters=locals()
  440. )
  441. async def sendVideo(self, chat_id, video,
  442. duration=None,
  443. width=None,
  444. height=None,
  445. thumb=None,
  446. caption=None,
  447. parse_mode=None,
  448. supports_streaming=None,
  449. disable_notification=None,
  450. reply_to_message_id=None,
  451. reply_markup=None):
  452. """Send a video from file_id, HTTP url or file.
  453. See https://core.telegram.org/bots/api#sendvideo for details.
  454. """
  455. return await self.api_request(
  456. 'sendVideo',
  457. parameters=locals()
  458. )
  459. async def sendAnimation(self, chat_id, animation,
  460. duration=None,
  461. width=None,
  462. height=None,
  463. thumb=None,
  464. caption=None,
  465. parse_mode=None,
  466. disable_notification=None,
  467. reply_to_message_id=None,
  468. reply_markup=None):
  469. """Send animation files (GIF or H.264/MPEG-4 AVC video without sound).
  470. See https://core.telegram.org/bots/api#sendanimation for details.
  471. """
  472. return await self.api_request(
  473. 'sendAnimation',
  474. parameters=locals()
  475. )
  476. async def sendVoice(self, chat_id, voice,
  477. caption=None,
  478. parse_mode=None,
  479. duration=None,
  480. disable_notification=None,
  481. reply_to_message_id=None,
  482. reply_markup=None):
  483. """Send an audio file to be displayed as playable voice message.
  484. `voice` must be in an .ogg file encoded with OPUS.
  485. See https://core.telegram.org/bots/api#sendvoice for details.
  486. """
  487. return await self.api_request(
  488. 'sendVoice',
  489. parameters=locals()
  490. )
  491. async def sendVideoNote(self, chat_id, video_note,
  492. duration=None,
  493. length=None,
  494. thumb=None,
  495. disable_notification=None,
  496. reply_to_message_id=None,
  497. reply_markup=None):
  498. """Send a rounded square mp4 video message of up to 1 minute long.
  499. See https://core.telegram.org/bots/api#sendvideonote for details.
  500. """
  501. return await self.api_request(
  502. 'sendVideoNote',
  503. parameters=locals()
  504. )
  505. async def sendMediaGroup(self, chat_id, media,
  506. disable_notification=None,
  507. reply_to_message_id=None):
  508. """Send a group of photos or videos as an album.
  509. `media` must be a list of `InputMediaPhoto` and/or `InputMediaVideo`
  510. objects.
  511. See https://core.telegram.org/bots/api#sendmediagroup for details.
  512. """
  513. return await self.api_request(
  514. 'sendMediaGroup',
  515. parameters=locals()
  516. )
  517. async def sendLocation(self, chat_id, latitude, longitude,
  518. live_period=None,
  519. disable_notification=None,
  520. reply_to_message_id=None,
  521. reply_markup=None):
  522. """Send a point on the map. May be kept updated for a `live_period`.
  523. See https://core.telegram.org/bots/api#sendlocation for details.
  524. """
  525. return await self.api_request(
  526. 'sendLocation',
  527. parameters=locals()
  528. )
  529. async def editMessageLiveLocation(self, latitude, longitude,
  530. chat_id=None, message_id=None,
  531. inline_message_id=None,
  532. reply_markup=None):
  533. """Edit live location messages.
  534. A location can be edited until its live_period expires or editing is
  535. explicitly disabled by a call to stopMessageLiveLocation.
  536. The message to be edited may be identified through `inline_message_id`
  537. OR the couple (`chat_id`, `message_id`).
  538. See https://core.telegram.org/bots/api#editmessagelivelocation
  539. for details.
  540. """
  541. return await self.api_request(
  542. 'editMessageLiveLocation',
  543. parameters=locals()
  544. )
  545. async def stopMessageLiveLocation(self,
  546. chat_id=None, message_id=None,
  547. inline_message_id=None,
  548. reply_markup=None):
  549. """Stop updating a live location message before live_period expires.
  550. The position to be stopped may be identified through
  551. `inline_message_id` OR the couple (`chat_id`, `message_id`).
  552. `reply_markup` type may be only `InlineKeyboardMarkup`.
  553. See https://core.telegram.org/bots/api#stopmessagelivelocation
  554. for details.
  555. """
  556. return await self.api_request(
  557. 'stopMessageLiveLocation',
  558. parameters=locals()
  559. )
  560. async def sendVenue(self, chat_id, latitude, longitude, title, address,
  561. foursquare_id=None,
  562. foursquare_type=None,
  563. disable_notification=None,
  564. reply_to_message_id=None,
  565. reply_markup=None):
  566. """Send information about a venue.
  567. Integrated with FourSquare.
  568. See https://core.telegram.org/bots/api#sendvenue for details.
  569. """
  570. return await self.api_request(
  571. 'sendVenue',
  572. parameters=locals()
  573. )
  574. async def sendContact(self, chat_id, phone_number, first_name,
  575. last_name=None,
  576. vcard=None,
  577. disable_notification=None,
  578. reply_to_message_id=None,
  579. reply_markup=None):
  580. """Send a phone contact.
  581. See https://core.telegram.org/bots/api#sendcontact for details.
  582. """
  583. return await self.api_request(
  584. 'sendContact',
  585. parameters=locals()
  586. )
  587. async def sendPoll(self, chat_id, question, options,
  588. dummy=None,
  589. disable_notification=None,
  590. reply_to_message_id=None,
  591. reply_markup=None):
  592. """Send a native poll in a group, a supergroup or channel.
  593. See https://core.telegram.org/bots/api#sendpoll for details.
  594. """
  595. return await self.api_request(
  596. 'sendPoll',
  597. parameters=locals()
  598. )
  599. async def sendChatAction(self, chat_id, action):
  600. """Fake a typing status or similar.
  601. See https://core.telegram.org/bots/api#sendchataction for details.
  602. """
  603. return await self.api_request(
  604. 'sendChatAction',
  605. parameters=locals()
  606. )
  607. async def getUserProfilePhotos(self, user_id,
  608. offset=None,
  609. limit=None,):
  610. """Get a list of profile pictures for a user.
  611. See https://core.telegram.org/bots/api#getuserprofilephotos
  612. for details.
  613. """
  614. return await self.api_request(
  615. 'getUserProfilePhotos',
  616. parameters=locals()
  617. )
  618. async def getFile(self, file_id):
  619. """Get basic info about a file and prepare it for downloading.
  620. For the moment, bots can download files of up to
  621. 20MB in size.
  622. On success, a File object is returned. The file can then be downloaded
  623. via the link https://api.telegram.org/file/bot<token>/<file_path>,
  624. where <file_path> is taken from the response.
  625. See https://core.telegram.org/bots/api#getfile for details.
  626. """
  627. return await self.api_request(
  628. 'getFile',
  629. parameters=locals()
  630. )
  631. async def kickChatMember(self, chat_id, user_id,
  632. until_date=None):
  633. """Kick a user from a group, a supergroup or a channel.
  634. In the case of supergroups and channels, the user will not be able to
  635. return to the group on their own using invite links, etc., unless
  636. unbanned first.
  637. Note: In regular groups (non-supergroups), this method will only work
  638. if the ‘All Members Are Admins’ setting is off in the target group.
  639. Otherwise members may only be removed by the group's creator or by
  640. the member that added them.
  641. See https://core.telegram.org/bots/api#kickchatmember for details.
  642. """
  643. return await self.api_request(
  644. 'kickChatMember',
  645. parameters=locals()
  646. )
  647. async def unbanChatMember(self, chat_id, user_id):
  648. """Unban a previously kicked user in a supergroup or channel.
  649. The user will not return to the group or channel automatically, but
  650. will be able to join via link, etc.
  651. The bot must be an administrator for this to work.
  652. Return True on success.
  653. See https://core.telegram.org/bots/api#unbanchatmember for details.
  654. """
  655. return await self.api_request(
  656. 'unbanChatMember',
  657. parameters=locals()
  658. )
  659. async def restrictChatMember(self, chat_id, user_id,
  660. until_date=None,
  661. can_send_messages=None,
  662. can_send_media_messages=None,
  663. can_send_other_messages=None,
  664. can_add_web_page_previews=None):
  665. """Restrict a user in a supergroup.
  666. The bot must be an administrator in the supergroup for this to work
  667. and must have the appropriate admin rights.
  668. Pass True for all boolean parameters to lift restrictions from a
  669. user.
  670. Return True on success.
  671. See https://core.telegram.org/bots/api#restrictchatmember for details.
  672. """
  673. return await self.api_request(
  674. 'restrictChatMember',
  675. parameters=locals()
  676. )
  677. async def promoteChatMember(self, chat_id, user_id,
  678. can_change_info=None,
  679. can_post_messages=None,
  680. can_edit_messages=None,
  681. can_delete_messages=None,
  682. can_invite_users=None,
  683. can_restrict_members=None,
  684. can_pin_messages=None,
  685. can_promote_members=None):
  686. """Promote or demote a user in a supergroup or a channel.
  687. The bot must be an administrator in the chat for this to work and must
  688. have the appropriate admin rights.
  689. Pass False for all boolean parameters to demote a user.
  690. Return True on success.
  691. See https://core.telegram.org/bots/api#promotechatmember for details.
  692. """
  693. return await self.api_request(
  694. 'promoteChatMember',
  695. parameters=locals()
  696. )
  697. async def exportChatInviteLink(self, chat_id):
  698. """Generate a new invite link for a chat and revoke any active link.
  699. The bot must be an administrator in the chat for this to work and must
  700. have the appropriate admin rights.
  701. Return the new invite link as String on success.
  702. NOTE: to get the current invite link, use `getChat` method.
  703. See https://core.telegram.org/bots/api#exportchatinvitelink
  704. for details.
  705. """
  706. return await self.api_request(
  707. 'exportChatInviteLink',
  708. parameters=locals()
  709. )
  710. async def setChatPhoto(self, chat_id, photo):
  711. """Set a new profile photo for the chat.
  712. Photos can't be changed for private chats.
  713. `photo` must be an input file (file_id and urls are not allowed).
  714. The bot must be an administrator in the chat for this to work and must
  715. have the appropriate admin rights.
  716. Return True on success.
  717. See https://core.telegram.org/bots/api#setchatphoto for details.
  718. """
  719. return await self.api_request(
  720. 'setChatPhoto',
  721. parameters=locals()
  722. )
  723. async def deleteChatPhoto(self, chat_id):
  724. """Delete a chat photo.
  725. Photos can't be changed for private chats.
  726. The bot must be an administrator in the chat for this to work and must
  727. have the appropriate admin rights.
  728. Return True on success.
  729. See https://core.telegram.org/bots/api#deletechatphoto for details.
  730. """
  731. return await self.api_request(
  732. 'deleteChatPhoto',
  733. parameters=locals()
  734. )
  735. async def setChatTitle(self, chat_id, title):
  736. """Change the title of a chat.
  737. Titles can't be changed for private chats.
  738. The bot must be an administrator in the chat for this to work and must
  739. have the appropriate admin rights.
  740. Return True on success.
  741. See https://core.telegram.org/bots/api#setchattitle for details.
  742. """
  743. return await self.api_request(
  744. 'setChatTitle',
  745. parameters=locals()
  746. )
  747. async def setChatDescription(self, chat_id, description):
  748. """Change the description of a supergroup or a channel.
  749. The bot must be an administrator in the chat for this to work and must
  750. have the appropriate admin rights.
  751. Return True on success.
  752. See https://core.telegram.org/bots/api#setchatdescription for details.
  753. """
  754. return await self.api_request(
  755. 'setChatDescription',
  756. parameters=locals()
  757. )
  758. async def pinChatMessage(self, chat_id, message_id,
  759. disable_notification=None):
  760. """Pin a message in a group, a supergroup, or a channel.
  761. The bot must be an administrator in the chat for this to work and must
  762. have the ‘can_pin_messages’ admin right in the supergroup or
  763. ‘can_edit_messages’ admin right in the channel.
  764. Return True on success.
  765. See https://core.telegram.org/bots/api#pinchatmessage for details.
  766. """
  767. return await self.api_request(
  768. 'pinChatMessage',
  769. parameters=locals()
  770. )
  771. async def unpinChatMessage(self, chat_id):
  772. """Unpin a message in a group, a supergroup, or a channel.
  773. The bot must be an administrator in the chat for this to work and must
  774. have the ‘can_pin_messages’ admin right in the supergroup or
  775. ‘can_edit_messages’ admin right in the channel.
  776. Return True on success.
  777. See https://core.telegram.org/bots/api#unpinchatmessage for details.
  778. """
  779. return await self.api_request(
  780. 'unpinChatMessage',
  781. parameters=locals()
  782. )
  783. async def leaveChat(self, chat_id):
  784. """Make the bot leave a group, supergroup or channel.
  785. Return True on success.
  786. See https://core.telegram.org/bots/api#leavechat for details.
  787. """
  788. return await self.api_request(
  789. 'leaveChat',
  790. parameters=locals()
  791. )
  792. async def getChat(self, chat_id):
  793. """Get up to date information about the chat.
  794. Return a Chat object on success.
  795. See https://core.telegram.org/bots/api#getchat for details.
  796. """
  797. return await self.api_request(
  798. 'getChat',
  799. parameters=locals()
  800. )
  801. async def getChatAdministrators(self, chat_id):
  802. """Get a list of administrators in a chat.
  803. On success, return an Array of ChatMember objects that contains
  804. information about all chat administrators except other bots.
  805. If the chat is a group or a supergroup and no administrators were
  806. appointed, only the creator will be returned.
  807. See https://core.telegram.org/bots/api#getchatadministrators
  808. for details.
  809. """
  810. return await self.api_request(
  811. 'getChatAdministrators',
  812. parameters=locals()
  813. )
  814. async def getChatMembersCount(self, chat_id):
  815. """Get the number of members in a chat.
  816. Returns Int on success.
  817. See https://core.telegram.org/bots/api#getchatmemberscount for details.
  818. """
  819. return await self.api_request(
  820. 'getChatMembersCount',
  821. parameters=locals()
  822. )
  823. async def getChatMember(self, chat_id, user_id):
  824. """Get information about a member of a chat.
  825. Returns a ChatMember object on success.
  826. See https://core.telegram.org/bots/api#getchatmember for details.
  827. """
  828. return await self.api_request(
  829. 'getChatMember',
  830. parameters=locals()
  831. )
  832. async def setChatStickerSet(self, chat_id, sticker_set_name):
  833. """Set a new group sticker set for a supergroup.
  834. The bot must be an administrator in the chat for this to work and must
  835. have the appropriate admin rights.
  836. Use the field `can_set_sticker_set` optionally returned in getChat
  837. requests to check if the bot can use this method.
  838. Returns True on success.
  839. See https://core.telegram.org/bots/api#setchatstickerset for details.
  840. """
  841. return await self.api_request(
  842. 'setChatStickerSet',
  843. parameters=locals()
  844. )
  845. async def deleteChatStickerSet(self, chat_id):
  846. """Delete a group sticker set from a supergroup.
  847. The bot must be an administrator in the chat for this to work and must
  848. have the appropriate admin rights.
  849. Use the field `can_set_sticker_set` optionally returned in getChat
  850. requests to check if the bot can use this method.
  851. Returns True on success.
  852. See https://core.telegram.org/bots/api#deletechatstickerset for
  853. details.
  854. """
  855. return await self.api_request(
  856. 'deleteChatStickerSet',
  857. parameters=locals()
  858. )
  859. async def answerCallbackQuery(self, callback_query_id,
  860. text=None,
  861. show_alert=None,
  862. url=None,
  863. cache_time=None):
  864. """Send answers to callback queries sent from inline keyboards.
  865. The answer will be displayed to the user as a notification at the top
  866. of the chat screen or as an alert.
  867. On success, True is returned.
  868. See https://core.telegram.org/bots/api#answercallbackquery for details.
  869. """
  870. return await self.api_request(
  871. 'answerCallbackQuery',
  872. parameters=locals()
  873. )
  874. async def editMessageText(self, text,
  875. chat_id=None, message_id=None,
  876. inline_message_id=None,
  877. parse_mode=None,
  878. disable_web_page_preview=None,
  879. reply_markup=None):
  880. """Edit text and game messages.
  881. On success, if edited message is sent by the bot, the edited Message
  882. is returned, otherwise True is returned.
  883. See https://core.telegram.org/bots/api#editmessagetext for details.
  884. """
  885. return await self.api_request(
  886. 'editMessageText',
  887. parameters=locals()
  888. )
  889. async def editMessageCaption(self,
  890. chat_id=None, message_id=None,
  891. inline_message_id=None,
  892. caption=None,
  893. parse_mode=None,
  894. reply_markup=None):
  895. """Edit captions of messages.
  896. On success, if edited message is sent by the bot, the edited Message is
  897. returned, otherwise True is returned.
  898. See https://core.telegram.org/bots/api#editmessagecaption for details.
  899. """
  900. return await self.api_request(
  901. 'editMessageCaption',
  902. parameters=locals()
  903. )
  904. async def editMessageMedia(self,
  905. chat_id=None, message_id=None,
  906. inline_message_id=None,
  907. media=None,
  908. reply_markup=None):
  909. """Edit animation, audio, document, photo, or video messages.
  910. If a message is a part of a message album, then it can be edited only
  911. to a photo or a video. Otherwise, message type can be changed
  912. arbitrarily.
  913. When inline message is edited, new file can't be uploaded.
  914. Use previously uploaded file via its file_id or specify a URL.
  915. On success, if the edited message was sent by the bot, the edited
  916. Message is returned, otherwise True is returned.
  917. See https://core.telegram.org/bots/api#editmessagemedia for details.
  918. """
  919. return await self.api_request(
  920. 'editMessageMedia',
  921. parameters=locals()
  922. )
  923. async def editMessageReplyMarkup(self,
  924. chat_id=None, message_id=None,
  925. inline_message_id=None,
  926. reply_markup=None):
  927. """Edit only the reply markup of messages.
  928. On success, if edited message is sent by the bot, the edited Message is
  929. returned, otherwise True is returned.
  930. See https://core.telegram.org/bots/api#editmessagereplymarkup for
  931. details.
  932. """
  933. return await self.api_request(
  934. 'editMessageReplyMarkup',
  935. parameters=locals()
  936. )
  937. async def stopPoll(self, chat_id, message_id,
  938. reply_markup=None):
  939. """Stop a poll which was sent by the bot.
  940. On success, the stopped Poll with the final results is returned.
  941. `reply_markup` type may be only `InlineKeyboardMarkup`.
  942. See https://core.telegram.org/bots/api#stoppoll for details.
  943. """
  944. return await self.api_request(
  945. 'stopPoll',
  946. parameters=locals()
  947. )
  948. async def deleteMessage(self, chat_id, message_id):
  949. """Delete a message, including service messages.
  950. - A message can only be deleted if it was sent less than 48 hours
  951. ago.
  952. - Bots can delete outgoing messages in private chats, groups, and
  953. supergroups.
  954. - Bots can delete incoming messages in private chats.
  955. - Bots granted can_post_messages permissions can delete outgoing
  956. messages in channels.
  957. - If the bot is an administrator of a group, it can delete any
  958. message there.
  959. - If the bot has can_delete_messages permission in a supergroup or
  960. a channel, it can delete any message there.
  961. Returns True on success.
  962. See https://core.telegram.org/bots/api#deletemessage for details.
  963. """
  964. return await self.api_request(
  965. 'deleteMessage',
  966. parameters=locals()
  967. )
  968. async def sendSticker(self, chat_id, sticker,
  969. disable_notification=None,
  970. reply_to_message_id=None,
  971. reply_markup=None):
  972. """Send `.webp` stickers.
  973. On success, the sent Message is returned.
  974. See https://core.telegram.org/bots/api#sendsticker for details.
  975. """
  976. return await self.api_request(
  977. 'sendSticker',
  978. parameters=locals()
  979. )
  980. async def getStickerSet(self, name):
  981. """Get a sticker set.
  982. On success, a StickerSet object is returned.
  983. See https://core.telegram.org/bots/api#getstickerset for details.
  984. """
  985. return await self.api_request(
  986. 'getStickerSet',
  987. parameters=locals()
  988. )
  989. async def uploadStickerFile(self, user_id, png_sticker):
  990. """Upload a .png file as a sticker.
  991. Use it later via `createNewStickerSet` and `addStickerToSet` methods
  992. (can be used multiple times).
  993. Return the uploaded File on success.
  994. `png_sticker` must be a *.png image up to 512 kilobytes in size,
  995. dimensions must not exceed 512px, and either width or height must
  996. be exactly 512px.
  997. See https://core.telegram.org/bots/api#uploadstickerfile for details.
  998. """
  999. return await self.api_request(
  1000. 'uploadStickerFile',
  1001. parameters=locals()
  1002. )
  1003. async def createNewStickerSet(self, user_id,
  1004. name, title, png_sticker, emojis,
  1005. contains_masks=None,
  1006. mask_position=None):
  1007. """Create new sticker set owned by a user.
  1008. The bot will be able to edit the created sticker set.
  1009. Returns True on success.
  1010. See https://core.telegram.org/bots/api#createnewstickerset for details.
  1011. """
  1012. return await self.api_request(
  1013. 'createNewStickerSet',
  1014. parameters=locals()
  1015. )
  1016. async def addStickerToSet(self, user_id, name, png_sticker, emojis,
  1017. mask_position=None):
  1018. """Add a new sticker to a set created by the bot.
  1019. Returns True on success.
  1020. See https://core.telegram.org/bots/api#addstickertoset for details.
  1021. """
  1022. return await self.api_request(
  1023. 'addStickerToSet',
  1024. parameters=locals()
  1025. )
  1026. async def setStickerPositionInSet(self, sticker, position):
  1027. """Move a sticker in a set created by the bot to a specific position .
  1028. Position is 0-based.
  1029. Returns True on success.
  1030. See https://core.telegram.org/bots/api#setstickerpositioninset for
  1031. details.
  1032. """
  1033. return await self.api_request(
  1034. 'setStickerPositionInSet',
  1035. parameters=locals()
  1036. )
  1037. async def deleteStickerFromSet(self, sticker):
  1038. """Delete a sticker from a set created by the bot.
  1039. Returns True on success.
  1040. See https://core.telegram.org/bots/api#deletestickerfromset for
  1041. details.
  1042. """
  1043. return await self.api_request(
  1044. 'deleteStickerFromSet',
  1045. parameters=locals()
  1046. )
  1047. async def answerInlineQuery(self, inline_query_id, results,
  1048. cache_time=None,
  1049. is_personal=None,
  1050. next_offset=None,
  1051. switch_pm_text=None,
  1052. switch_pm_parameter=None):
  1053. """Send answers to an inline query.
  1054. On success, True is returned.
  1055. No more than 50 results per query are allowed.
  1056. See https://core.telegram.org/bots/api#answerinlinequery for details.
  1057. """
  1058. return await self.api_request(
  1059. 'answerInlineQuery',
  1060. parameters=locals()
  1061. )
  1062. async def sendInvoice(self, chat_id, title, description, payload,
  1063. provider_token, start_parameter, currency, prices,
  1064. provider_data=None,
  1065. photo_url=None,
  1066. photo_size=None,
  1067. photo_width=None,
  1068. photo_height=None,
  1069. need_name=None,
  1070. need_phone_number=None,
  1071. need_email=None,
  1072. need_shipping_address=None,
  1073. send_phone_number_to_provider=None,
  1074. send_email_to_provider=None,
  1075. is_flexible=None,
  1076. disable_notification=None,
  1077. reply_to_message_id=None,
  1078. reply_markup=None):
  1079. """Send an invoice.
  1080. On success, the sent Message is returned.
  1081. See https://core.telegram.org/bots/api#sendinvoice for details.
  1082. """
  1083. return await self.api_request(
  1084. 'sendInvoice',
  1085. parameters=locals()
  1086. )
  1087. async def answerShippingQuery(self, shipping_query_id, ok,
  1088. shipping_options=None,
  1089. error_message=None):
  1090. """Reply to shipping queries.
  1091. On success, True is returned.
  1092. If you sent an invoice requesting a shipping address and the parameter
  1093. is_flexible was specified, the Bot API will send an Update with a
  1094. shipping_query field to the bot.
  1095. See https://core.telegram.org/bots/api#answershippingquery for details.
  1096. """
  1097. return await self.api_request(
  1098. 'answerShippingQuery',
  1099. parameters=locals()
  1100. )
  1101. async def answerPreCheckoutQuery(self, pre_checkout_query_id, ok,
  1102. error_message=None):
  1103. """Respond to pre-checkout queries.
  1104. Once the user has confirmed their payment and shipping details, the Bot
  1105. API sends the final confirmation in the form of an Update with the
  1106. field pre_checkout_query.
  1107. On success, True is returned.
  1108. Note: The Bot API must receive an answer within 10 seconds after the
  1109. pre-checkout query was sent.
  1110. See https://core.telegram.org/bots/api#answerprecheckoutquery for
  1111. details.
  1112. """
  1113. return await self.api_request(
  1114. 'answerPreCheckoutQuery',
  1115. parameters=locals()
  1116. )
  1117. async def setPassportDataErrors(self, user_id, errors):
  1118. """Refuse a Telegram Passport element with `errors`.
  1119. Inform a user that some of the Telegram Passport elements they provided
  1120. contains errors.
  1121. The user will not be able to re-submit their Passport to you until the
  1122. errors are fixed (the contents of the field for which you returned
  1123. the error must change).
  1124. Returns True on success.
  1125. Use this if the data submitted by the user doesn't satisfy the
  1126. standards your service requires for any reason.
  1127. For example, if a birthday date seems invalid, a submitted document
  1128. is blurry, a scan shows evidence of tampering, etc.
  1129. Supply some details in the error message to make sure the user knows
  1130. how to correct the issues.
  1131. See https://core.telegram.org/bots/api#setpassportdataerrors for
  1132. details.
  1133. """
  1134. return await self.api_request(
  1135. 'setPassportDataErrors',
  1136. parameters=locals()
  1137. )
  1138. async def sendGame(self, chat_id, game_short_name,
  1139. disable_notification=None,
  1140. reply_to_message_id=None,
  1141. reply_markup=None):
  1142. """Send a game.
  1143. On success, the sent Message is returned.
  1144. See https://core.telegram.org/bots/api#sendgame for
  1145. details.
  1146. """
  1147. return await self.api_request(
  1148. 'sendGame',
  1149. parameters=locals()
  1150. )
  1151. async def setGameScore(self, user_id, score,
  1152. force=None,
  1153. disable_edit_message=None,
  1154. chat_id=None, message_id=None,
  1155. inline_message_id=None):
  1156. """Set the score of the specified user in a game.
  1157. On success, if the message was sent by the bot, returns the edited
  1158. Message, otherwise returns True.
  1159. Returns an error, if the new score is not greater than the user's
  1160. current score in the chat and force is False.
  1161. See https://core.telegram.org/bots/api#setgamescore for
  1162. details.
  1163. """
  1164. return await self.api_request(
  1165. 'setGameScore',
  1166. parameters=locals()
  1167. )
  1168. async def getGameHighScores(self, user_id,
  1169. chat_id=None, message_id=None,
  1170. inline_message_id=None):
  1171. """Get data for high score tables.
  1172. Will return the score of the specified user and several of his
  1173. neighbors in a game.
  1174. On success, returns an Array of GameHighScore objects.
  1175. This method will currently return scores for the target user, plus two
  1176. of his closest neighbors on each side. Will also return the top
  1177. three users if the user and his neighbors are not among them.
  1178. Please note that this behavior is subject to change.
  1179. See https://core.telegram.org/bots/api#getgamehighscores for
  1180. details.
  1181. """
  1182. return await self.api_request(
  1183. 'getGameHighScores',
  1184. parameters=locals()
  1185. )
  1186. async def sendDice(self,
  1187. chat_id: Union[int, str] = None,
  1188. emoji: str = None,
  1189. disable_notification: bool = False,
  1190. reply_to_message_id: int = None,
  1191. reply_markup=None):
  1192. """Send a dice.
  1193. Use this method to send a dice, which will have a random value from 1
  1194. to 6.
  1195. On success, the sent Message is returned.
  1196. (Yes, we're aware of the “proper” singular of die. But it's awkward,
  1197. and we decided to help it change. One dice at a time!)
  1198. See https://core.telegram.org/bots/api#senddice for
  1199. details.
  1200. """
  1201. return await self.api_request(
  1202. 'sendDice',
  1203. parameters=locals()
  1204. )
  1205. async def setChatAdministratorCustomTitle(self,
  1206. chat_id: Union[int, str] = None,
  1207. user_id: int = None,
  1208. custom_title: str = None):
  1209. """Set a custom title for an administrator.
  1210. Use this method to set a custom title for an administrator in a
  1211. supergroup promoted by the bot.
  1212. Returns True on success.
  1213. See https://core.telegram.org/bots/api#setchatadministratorcustomtitle
  1214. for details.
  1215. """
  1216. return await self.api_request(
  1217. 'setChatAdministratorCustomTitle',
  1218. parameters=locals()
  1219. )
  1220. async def setChatPermissions(self,
  1221. chat_id: Union[int, str] = None,
  1222. permissions: Union[ChatPermissions,
  1223. dict] = None):
  1224. """Set default chat permissions for all members.
  1225. Use this method to set default chat permissions for all members.
  1226. The bot must be an administrator in the group or a supergroup for this
  1227. to work and must have the can_restrict_members admin rights.
  1228. Returns True on success.
  1229. See https://core.telegram.org/bots/api#setchatpermissions for details.
  1230. """
  1231. return await self.api_request(
  1232. 'setChatPermissions',
  1233. parameters=locals()
  1234. )
  1235. async def setMyCommands(self, commands: List[Command]):
  1236. """Change the list of the bot's commands.
  1237. Use this method to change the list of the bot's commands.
  1238. Returns True on success.
  1239. See https://core.telegram.org/bots/api#setmycommands for details.
  1240. """
  1241. return await self.api_request(
  1242. 'setMyCommands',
  1243. parameters=locals()
  1244. )
  1245. async def getMyCommands(self):
  1246. """Get the current list of the bot's commands.
  1247. Use this method to get the current list of the bot's commands.
  1248. Requires no parameters.
  1249. Returns Array of BotCommand on success.
  1250. See https://core.telegram.org/bots/api#getmycommands for details.
  1251. """
  1252. return await self.api_request(
  1253. 'getMyCommands',
  1254. parameters=locals()
  1255. )
  1256. async def setStickerSetThumb(self,
  1257. name: str = None,
  1258. user_id: int = None,
  1259. thumb=None):
  1260. """Set the thumbnail of a sticker set.
  1261. Use this method to set the thumbnail of a sticker set.
  1262. Animated thumbnails can be set for animated sticker sets only.
  1263. Returns True on success.
  1264. See https://core.telegram.org/bots/api#setstickersetthumb for details.
  1265. """
  1266. return await self.api_request(
  1267. 'setStickerSetThumb',
  1268. parameters=locals()
  1269. )