1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2025-11-16 12:00:18 +00:00

Compare commits

..

35 Commits

Author SHA1 Message Date
d8f830c60f FlowsUpdatesFilter update 2021-08-22 23:14:56 +06:00
226b8dee21 deprecate allSentMessagesFlow and allSentMedaGroupsFlow 2021-08-22 23:13:59 +06:00
a109771d20 update structure schema 2021-08-22 12:10:05 +06:00
c028434f30 update gradle wrapper 2021-08-22 11:09:35 +06:00
d5c6ce32bb fixes in readme :) 2021-08-22 11:02:14 +06:00
d92cac5e07 small updates in readmes 2021-08-22 10:59:01 +06:00
9b21b5290c update dokka 2021-08-22 10:53:12 +06:00
13ca63d27d update dependencies 2021-08-22 10:47:23 +06:00
ad917dda1b start 0.35.6 2021-08-22 10:35:55 +06:00
7b1344e9c8 Merge pull request #440 from InsanusMokrassar/0.35.5
0.35.5
2021-08-13 20:51:02 +06:00
c4fbd2f1c6 revert type of BuiltinMimeTypes 2021-08-13 18:39:46 +06:00
c90bcea42c add additional mime types 2021-08-13 18:39:08 +06:00
e75c93d626 remove mime types from requests 2021-08-13 14:02:39 +06:00
58dcbe8751 StorageFile#asMultipartFile 2021-08-13 11:45:36 +06:00
17806cde25 add calculation of mimed type from TelegramMediaFile when it is MimedFile 2021-08-13 11:43:36 +06:00
f147a3d620 fix of package for AdditionalContentAsStorageFile 2021-08-13 11:41:57 +06:00
9eb6008a73 convertToStorageFile 2021-08-13 11:37:01 +06:00
f7d2c8bbd2 hotfix 2021-08-10 16:54:15 +06:00
f42cf78969 fixes 2021-08-10 16:50:50 +06:00
9a14932511 small improvement of DownloadFileRequestCallFactory 2021-08-10 11:32:22 +06:00
149ecf175b small improvement of DownloadFileChannelRequestCallFactory 2021-08-10 11:29:46 +06:00
2049fea82a new asStorageFile 2021-08-10 11:08:08 +06:00
40d94cca70 improvements in files downloading api 2021-08-10 10:34:59 +06:00
c8ad68ea69 make ByteReadChannelAllocatorSerializer -> ByteReadChannelAllocatorDeserializationStrategy 2021-08-10 10:12:22 +06:00
c66d64adbc renames 2021-08-09 23:24:12 +06:00
b475976ff1 add streaming file downloading feature 2021-08-09 23:22:08 +06:00
ea8db5b851 rename JVM DownloadFile file 2021-08-09 20:01:26 +06:00
af2fabf1ca fix changelog 2021-08-09 19:55:51 +06:00
abc0457a36 files downloading improvements 2021-08-09 19:55:08 +06:00
8dbdbdee13 start 0.35.5 2021-08-09 19:39:03 +06:00
0c31379ff5 Merge pull request #439 from InsanusMokrassar/0.35.4
0.35.4
2021-08-09 14:18:19 +06:00
3b3cf81aaa Update CHANGELOG.md 2021-08-09 12:26:37 +06:00
1642075a75 Update microutils 2021-08-09 12:21:51 +06:00
760c9f2916 start 0.35.4 2021-08-09 12:21:27 +06:00
219238cf19 Merge pull request #436 from InsanusMokrassar/0.35.3
0.35.3
2021-08-08 18:48:45 +06:00
40 changed files with 610 additions and 1359 deletions

View File

@@ -1,5 +1,42 @@
# TelegramBotAPI changelog
## 0.35.6
* `Common`:
* `Version`:
* `Klock`: `2.3.1` -> `2.3.3`
* `MicroUtils`: `0.5.19` -> `0.5.21`
* `Core`:
* All `FlowsUpdatesFilter` flows have been renamed and updated
* `Utils`:
* Extensions `allSentMessagesFlow` and `allSentMediaGroupsFlow` have been deprecated
## 0.35.5
**MIME TYPES FOR REQUESTS HAVE BEEN DEPRECATED DUE TO REDUNDANCY OF MIME TYPES IN FILES SENDING**
* `Core`:
* Several new extensions `ByteReadChannel#asStorageFile` and `ByteReadChannelAllocator#asStorageFile`
* Several new extensions `ByteArray#asMultipartFile`, `ByteReadChannel#asMultipartFile` and
`ByteReadChannelAllocator#asMultipartFile`
* New extension `StorageFile#asMultipartFile`
* `API`:
* New extensions `TelegramBot#downloadFile` for writing of incoming bytes to the file
* New extensions `TelegramBot#downloadFileStream` and `TelegramBot#downloadFileStreamAllocator` for getting of input
streams instead of whole bytes arrays
* Old extensions `TelegramBot#downloadFile` has been replaced to the new package. Migration: replace in your project
`import dev.inmo.tgbotapi.extensions.api.downloadFile` with `import dev.inmo.tgbotapi.extensions.api.files.downloadFile`
* `PathedFile#filename` extension has been deprecated, and new property `PathedFile#fileName` has been included
directly in `PathedFile`
* `Utils`:
* Add several functions `convertToStorageFile` and extensions `TelegramBot#convertToStorageFile`
## 0.35.4 Hotfix
* `Common`:
* `Version`:
* `MicroUtils`: `0.5.18` -> `0.5.19`
## 0.35.3
* `Common`:

View File

@@ -2,6 +2,15 @@
# TelegramBotAPI
- [TelegramBotAPI](#telegrambotapi)
* [Examples](#examples)
+ [Most common example](#most-common-example)
+ [Handling only last messages](#handling-only-last-messages)
+ [Build a little bit more complex behaviour](#build-a-little-bit-more-complex-behaviour)
+ [More examples](#more-examples)
<small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with markdown-toc</a></i></small>
Hello! This is a set of libraries for working with Telegram Bot API.
| Common info | [![Awesome Kotlin Badge](https://kotlin.link/awesome-kotlin.svg)](https://github.com/KotlinBy/awesome-kotlin) [![Build Status](https://github.com/InsanusMokrassar/TelegramBotAPI/workflows/Build/badge.svg)](https://github.com/InsanusMokrassar/TelegramBotAPI/actions) [Small survey](https://forms.gle/2Hex2ynbHWHhi1KY7)|

1
TelegramBotAPI.drawio Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,311 +0,0 @@
<?xml version="1.0"?>
<minder version="1.11.3">
<theme name="default" label="Default" index="-1"/>
<styles>
<style level="0" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<style level="1" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<style level="2" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<style level="3" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<style level="4" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<style level="5" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<style level="6" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<style level="7" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<style level="8" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<style level="9" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<style level="10" isset="true" branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="200" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true" connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
</styles>
<drawarea x="-950.47548925255796" y="-49.650554065281653" scale="0.5"/>
<images/>
<nodes>
<node id="0" posx="1378.798161778599" posy="159.04571601189673" width="472" height="168" side="top" fold="false" treesize="743" layout="Downwards" group="false">
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="439" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<nodename posx="1394.798161778599" posy="175.04571601189673" maxwidth="488.96484375">
<text data="tgbotapi.core&#10;&#10;Root project with API. It is not recommended to use its requests directly and better to use at least tgbotapi.extensions.api"/>
</nodename>
<nodenote></nodenote>
<nodes>
<node id="1" posx="1411.798161778599" posy="427.04571601189673" width="406" height="145" side="bottom" fold="false" treesize="743" color="#68b723" colorroot="true" layout="Downwards" group="false">
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="none" nodewidth="394" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<nodename posx="1427.798161778599" posy="443.04571601189673" maxwidth="419.451171875">
<text data="TelegramBotAPI extensions&#10;&#10;Family of projects which are fully based on TelegramBotAPI and extend its functionality"/>
</nodename>
<nodenote></nodenote>
<nodes>
<node id="2" posx="1247.298161778599" posy="672.04571601189673" width="296" height="191" side="bottom" fold="false" treesize="296" color="#68b723" colorroot="true" layout="Downwards" group="false">
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="203" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<nodename posx="1263.298161778599" posy="688.04571601189673" maxwidth="295.90315755208337">
<text data="tgbotapi.extensions.api&#10;&#10;Extensions project for make requests more look like in the Telegram Bot API and give opportunity to use it's easier"/>
</nodename>
<nodenote></nodenote>
</node>
<node id="3" posx="1609.298161778599" posy="672.04571601189673" width="307" height="168" side="bottom" fold="false" treesize="439" color="#68b723" colorroot="true" layout="Downwards" group="false">
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="286" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<nodename posx="1625.298161778599" posy="688.04571601189673" maxwidth="299.252197265625">
<text data="tgbotapi.extensions.utils&#10;&#10;Extensions project with utils things which will make easier different operations"/>
</nodename>
<nodenote></nodenote>
<nodes>
<node id="4" posx="1543.298161778599" posy="940.04571601189673" width="439" height="122" side="bottom" fold="false" treesize="439" color="#68b723" colorroot="false" layout="Downwards" group="false">
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="387" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<nodename posx="1559.298161778599" posy="956.04571601189673" maxwidth="408.97932942708348">
<text data="tgbotapi.extensions.behaviour_builder&#10;&#10;Extension project for building bot behaviour via special dsl"/>
</nodename>
<nodenote></nodenote>
</node>
</nodes>
</node>
</nodes>
</node>
</nodes>
</node>
<node id="5" posx="1391.8445078072455" posy="1155.6062730594231" width="461" height="236" side="bottom" fold="false" treesize="461" layout="Downwards" group="false">
<style branchmargin="100" linktype="curved" linkwidth="5" linkarrow="true" linkdash="solid" nodeborder="bracket" nodewidth="430" nodeborderwidth="3" nodefill="false" nodemargin="11" nodepadding="5" nodefont="Roboto Mono 14" nodemarkup="true"/>
<nodename posx="1407.8445078072455" posy="1171.6062730594231" maxwidth="453.885498046875">
<text data="tgbotapi&#10;&#10;Here included all available TelegramBotAPI libraries:&#13;&#10;&#13;&#10;* tgbotapi.core&#13;&#10;* tgbotapi.extensions.api&#13;&#10;* tgbotapi.extensions.utils&#10;* tgbotapi.extensions.behaviour_builder">
<color>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="67" end="68" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="84" end="85" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="111" end="112" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
<range start="139" end="140" extra="rgb(255,0,0)"/>
</color>
</text>
</nodename>
<nodenote></nodenote>
</node>
</nodes>
<groups/>
<connections>
<connection from_id="2" to_id="5" drag_x="1475.8213347929195" drag_y="1014.8259945356604" color="#777777">
<style connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<title></title>
<note></note>
</connection>
<connection from_id="4" to_id="5" drag_x="1691.5447998046875" drag_y="1107.00439453125" color="#777777">
<style connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<title></title>
<note></note>
</connection>
<connection from_id="3" to_id="5" drag_x="1483.48876953125" drag_y="896.18115234375">
<style connectiondash="dotted" connectionlwidth="2" connectionarrow="fromto" connectionpadding="3" connectionfont="Sans 10" connectiontwidth="100"/>
<title></title>
<note></note>
</connection>
</connections>
<stickers/>
</minder>

View File

@@ -1,3 +1,3 @@
dokka_version=1.4.32
dokka_version=1.5.0
org.gradle.jvmargs=-Xmx1024m

View File

@@ -8,15 +8,15 @@ kotlin.incremental.js=true
kotlin_version=1.5.21
kotlin_coroutines_version=1.5.1
kotlin_serialisation_runtime_version=1.2.2
klock_version=2.3.1
klock_version=2.3.3
uuid_version=0.3.0
ktor_version=1.6.2
micro_utils_version=0.5.18
micro_utils_version=0.5.21
javax_activation_version=1.1.1
library_group=dev.inmo
library_version=0.35.3
library_version=0.35.6
github_release_plugin_version=2.2.12

View File

@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@@ -2,6 +2,20 @@
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.core)
- [TelegramBotAPI Core](#telegrambotapi-core)
* [What is it?](#what-is-it-)
* [Compatibility](#compatibility)
* [How to implement library?](#how-to-implement-library-)
+ [Maven](#maven)
+ [Gradle](#gradle)
* [How to work with library?](#how-to-work-with-library-)
+ [Types](#types)
+ [Requests](#requests)
+ [RequestsExecutor](#requestsexecutor)
+ [Passport](#passport)
<small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with markdown-toc</a></i></small>
## What is it?
Library for Object-Oriented and type-safe work with Telegram Bot API. Most part of some specific solves or unuseful

View File

@@ -42,6 +42,14 @@ inline fun telegramBot(
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), builder)
@RiskFeature
fun createTelegramBotDefaultKtorCallRequestsFactories() = listOf(
SimpleRequestCallFactory(),
MultipartRequestCallFactory(),
DownloadFileRequestCallFactory,
DownloadFileChannelRequestCallFactory
)
class KtorRequestsExecutor(
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
client: HttpClient = HttpClient(),
@@ -52,7 +60,7 @@ class KtorRequestsExecutor(
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
private val callsFactories: List<KtorCallFactory> = callsFactories.run {
if (!excludeDefaultFactories) {
this + listOf(SimpleRequestCallFactory(), MultipartRequestCallFactory(), DownloadFileRequestCallFactory)
this + createTelegramBotDefaultKtorCallRequestsFactories()
} else {
this
}

View File

@@ -0,0 +1,39 @@
package dev.inmo.tgbotapi.bot.Ktor.base
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory
import dev.inmo.tgbotapi.requests.DownloadFileStream
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.utils.ByteReadChannelAllocator
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import io.ktor.client.HttpClient
import io.ktor.client.call.receive
import io.ktor.client.request.get
import io.ktor.client.statement.HttpStatement
import io.ktor.utils.io.*
import kotlinx.coroutines.*
import kotlinx.serialization.json.Json
import kotlin.coroutines.coroutineContext
object DownloadFileChannelRequestCallFactory : KtorCallFactory {
override suspend fun <T : Any> makeCall(
client: HttpClient,
urlsKeeper: TelegramAPIUrlsKeeper,
request: Request<T>,
jsonFormatter: Json
): T? = (request as? DownloadFileStream) ?.let {
val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath)
ByteReadChannelAllocator {
val scope = CoroutineScope(coroutineContext)
val outChannel = ByteChannel()
scope.launchSafelyWithoutExceptions {
client.get<HttpStatement>(fullUrl).execute { httpResponse ->
val channel: ByteReadChannel = httpResponse.receive()
channel.copyAndClose(outChannel)
}
}
outChannel
} as T
}
}

View File

@@ -16,9 +16,9 @@ object DownloadFileRequestCallFactory : KtorCallFactory {
request: Request<T>,
jsonFormatter: Json
): T? = (request as? DownloadFile) ?.let {
val fullUrl = "${urlsKeeper.fileBaseUrl}/${it.filePath}"
val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath)
return safely {
safely {
@Suppress("UNCHECKED_CAST")
client.get<ByteArray>(fullUrl) as T // always ByteArray
}

View File

@@ -24,7 +24,6 @@ class MultipartRequestCallFactory : AbstractRequestCallFactory() {
is MultipartFile -> appendInput(
key,
Headers.build {
append(HttpHeaders.ContentType, value.mimeType)
append(HttpHeaders.ContentDisposition, "filename=${value.fileId}")
},
block = value.file::input

View File

@@ -0,0 +1,15 @@
package dev.inmo.tgbotapi.requests
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.utils.ByteReadChannelAllocator
import dev.inmo.tgbotapi.utils.ByteReadChannelAllocatorDeserializationStrategy
import kotlinx.serialization.DeserializationStrategy
class DownloadFileStream(
val filePath: String
) : Request<ByteReadChannelAllocator> {
override fun method(): String = filePath
override val resultDeserializer: DeserializationStrategy<ByteReadChannelAllocator>
get() = ByteReadChannelAllocatorDeserializationStrategy
}

View File

@@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.requests.abstracts
import dev.inmo.tgbotapi.utils.RiskFeature
import dev.inmo.tgbotapi.utils.StorageFile
import dev.inmo.tgbotapi.utils.*
import io.ktor.utils.io.ByteReadChannel
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.*
@@ -42,12 +42,36 @@ object InputFileSerializer : KSerializer<InputFile> {
// TODO:: add checks for files size
/**
* Contains info about file for sending
*
* @see asMultipartFile
*/
@Serializable(InputFileSerializer::class)
data class MultipartFile (
val file: StorageFile,
val mimeType: String = file.storageFileInfo.contentType,
val filename: String = file.storageFileInfo.fileName
) : InputFile() {
override val fileId: String = file.storageFileInfo.generateCustomName()
@Deprecated("This constructor is redundant. Use constructor without mime type")
constructor(file: StorageFile, mimeType: String, filename: String): this(file, filename)
}
@Suppress("NOTHING_TO_INLINE", "unused")
inline fun StorageFile.asMultipartFile() = MultipartFile(this)
@Deprecated("This method is redundant. Use asMultipartFile without mime type")
@Suppress("NOTHING_TO_INLINE", "unused")
inline fun ByteArray.asMultipartFile(
fileName: String,
mimeType: MimeType
) = MultipartFile(asStorageFile(fileName))
@Suppress("NOTHING_TO_INLINE", "unused")
suspend inline fun ByteReadChannel.asMultipartFile(
fileName: String
) = MultipartFile(asStorageFile(fileName))
@Suppress("NOTHING_TO_INLINE", "unused")
suspend inline fun ByteReadChannelAllocator.asMultipartFile(
fileName: String
) = this.invoke().asMultipartFile(fileName)

View File

@@ -5,8 +5,7 @@ import dev.inmo.tgbotapi.types.FileUniqueId
import dev.inmo.tgbotapi.types.fileUniqueIdField
import dev.inmo.tgbotapi.types.files.abstracts.*
import dev.inmo.tgbotapi.utils.*
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.*
@Serializable
data class PathedFile(
@@ -18,8 +17,14 @@ data class PathedFile(
val filePath: String,
@SerialName(fileSizeField)
override val fileSize: Long? = null
): TelegramMediaFile
): TelegramMediaFile {
@Transient
val fileName: FileName by lazy(LazyThreadSafetyMode.PUBLICATION) {
filePath.filenameFromUrl
}
}
@Deprecated("Use fileName property instead", ReplaceWith("fileName"))
val PathedFile.filename: FileName
get() = filePath.filenameFromUrl
fun TelegramAPIUrlsKeeper.resolveFileURL(file: PathedFile): String = "$fileBaseUrl/${file.filePath}"

View File

@@ -14,24 +14,79 @@ interface FlowsUpdatesFilter : UpdatesFilter {
val allUpdatesFlow: Flow<Update>
val allUpdatesWithoutMediaGroupsGroupingFlow: Flow<Update>
val messagesFlow: Flow<MessageUpdate>
val messageMediaGroupsFlow: Flow<MessageMediaGroupUpdate>
val editedMessagesFlow: Flow<EditMessageUpdate>
val editedMessageMediaGroupsFlow: Flow<EditMessageMediaGroupUpdate>
val channelPostsFlow: Flow<ChannelPostUpdate>
val channelPostMediaGroupsFlow: Flow<ChannelPostMediaGroupUpdate>
val editedChannelPostsFlow: Flow<EditChannelPostUpdate>
val editedChannelPostMediaGroupsFlow: Flow<EditChannelPostMediaGroupUpdate>
val chosenInlineResultsFlow: Flow<ChosenInlineResultUpdate>
val inlineQueriesFlow: Flow<InlineQueryUpdate>
val callbackQueriesFlow: Flow<CallbackQueryUpdate>
val shippingQueriesFlow: Flow<ShippingQueryUpdate>
val preCheckoutQueriesFlow: Flow<PreCheckoutQueryUpdate>
val pollsFlow: Flow<PollUpdate>
val pollAnswersFlow: Flow<PollAnswerUpdate>
val chatMemberUpdatesFlow: Flow<CommonChatMemberUpdatedUpdate>
val myChatMemberUpdatesFlow: Flow<MyChatMemberUpdatedUpdate>
val unknownUpdatesFlow: Flow<UnknownUpdate>
@Deprecated("Renamed", ReplaceWith("messagesFlow"))
val messageFlow: Flow<MessageUpdate>
get() = messagesFlow
@Deprecated("Renamed", ReplaceWith("messageMediaGroupsFlow"))
val messageMediaGroupFlow: Flow<MessageMediaGroupUpdate>
get() = messageMediaGroupsFlow
@Deprecated("Renamed", ReplaceWith("editedMessagesFlow"))
val editedMessageFlow: Flow<EditMessageUpdate>
get() = editedMessagesFlow
@Deprecated("Renamed", ReplaceWith("editedMessageMediaGroupsFlow"))
val editedMessageMediaGroupFlow: Flow<EditMessageMediaGroupUpdate>
get() = editedMessageMediaGroupsFlow
@Deprecated("Renamed", ReplaceWith("channelPostsFlow"))
val channelPostFlow: Flow<ChannelPostUpdate>
get() = channelPostsFlow
@Deprecated("Renamed", ReplaceWith("channelPostMediaGroupsFlow"))
val channelPostMediaGroupFlow: Flow<ChannelPostMediaGroupUpdate>
get() = channelPostMediaGroupsFlow
@Deprecated("Renamed", ReplaceWith("editedChannelPostsFlow"))
val editedChannelPostFlow: Flow<EditChannelPostUpdate>
get() = editedChannelPostsFlow
@Deprecated("Renamed", ReplaceWith("editedChannelPostMediaGroupsFlow"))
val editedChannelPostMediaGroupFlow: Flow<EditChannelPostMediaGroupUpdate>
get() = editedChannelPostMediaGroupsFlow
@Deprecated("Renamed", ReplaceWith("chosenInlineResultsFlow"))
val chosenInlineResultFlow: Flow<ChosenInlineResultUpdate>
get() = chosenInlineResultsFlow
@Deprecated("Renamed", ReplaceWith("inlineQueriesFlow"))
val inlineQueryFlow: Flow<InlineQueryUpdate>
get() = inlineQueriesFlow
@Deprecated("Renamed", ReplaceWith("callbackQueriesFlow"))
val callbackQueryFlow: Flow<CallbackQueryUpdate>
get() = callbackQueriesFlow
@Deprecated("Renamed", ReplaceWith("shippingQueriesFlow"))
val shippingQueryFlow: Flow<ShippingQueryUpdate>
get() = shippingQueriesFlow
@Deprecated("Renamed", ReplaceWith("preCheckoutQueriesFlow"))
val preCheckoutQueryFlow: Flow<PreCheckoutQueryUpdate>
get() = preCheckoutQueriesFlow
@Deprecated("Renamed", ReplaceWith("pollsFlow"))
val pollFlow: Flow<PollUpdate>
get() = pollsFlow
@Deprecated("Renamed", ReplaceWith("pollAnswersFlow"))
val pollAnswerFlow: Flow<PollAnswerUpdate>
get() = pollAnswersFlow
@Deprecated("Renamed", ReplaceWith("chatMemberUpdatesFlow"))
val chatMemberUpdatedFlow: Flow<CommonChatMemberUpdatedUpdate>
get() = chatMemberUpdatesFlow
@Deprecated("Renamed", ReplaceWith("myChatMemberUpdatesFlow"))
val myChatMemberUpdatedFlow: Flow<MyChatMemberUpdatedUpdate>
get() = myChatMemberUpdatesFlow
@Deprecated("Renamed", ReplaceWith("unknownUpdatesFlow"))
val unknownUpdateTypeFlow: Flow<UnknownUpdate>
get() = unknownUpdatesFlow
}
/**
@@ -63,22 +118,22 @@ class DefaultFlowsUpdatesFilter(
updatesSharedFlow.emit(it)
}
override val messageFlow: Flow<MessageUpdate> = allUpdatesFlow.filterIsInstance()
override val messageMediaGroupFlow: Flow<MessageMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
override val editedMessageFlow: Flow<EditMessageUpdate> = allUpdatesFlow.filterIsInstance()
override val editedMessageMediaGroupFlow: Flow<EditMessageMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
override val channelPostFlow: Flow<ChannelPostUpdate> = allUpdatesFlow.filterIsInstance()
override val channelPostMediaGroupFlow: Flow<ChannelPostMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
override val editedChannelPostFlow: Flow<EditChannelPostUpdate> = allUpdatesFlow.filterIsInstance()
override val editedChannelPostMediaGroupFlow: Flow<EditChannelPostMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
override val chosenInlineResultFlow: Flow<ChosenInlineResultUpdate> = allUpdatesFlow.filterIsInstance()
override val inlineQueryFlow: Flow<InlineQueryUpdate> = allUpdatesFlow.filterIsInstance()
override val callbackQueryFlow: Flow<CallbackQueryUpdate> = allUpdatesFlow.filterIsInstance()
override val shippingQueryFlow: Flow<ShippingQueryUpdate> = allUpdatesFlow.filterIsInstance()
override val preCheckoutQueryFlow: Flow<PreCheckoutQueryUpdate> = allUpdatesFlow.filterIsInstance()
override val pollFlow: Flow<PollUpdate> = allUpdatesFlow.filterIsInstance()
override val pollAnswerFlow: Flow<PollAnswerUpdate> = allUpdatesFlow.filterIsInstance()
override val chatMemberUpdatedFlow: Flow<CommonChatMemberUpdatedUpdate> = allUpdatesFlow.filterIsInstance()
override val myChatMemberUpdatedFlow: Flow<MyChatMemberUpdatedUpdate> = allUpdatesFlow.filterIsInstance()
override val unknownUpdateTypeFlow: Flow<UnknownUpdate> = allUpdatesFlow.filterIsInstance()
override val messagesFlow: Flow<MessageUpdate> = allUpdatesFlow.filterIsInstance()
override val messageMediaGroupsFlow: Flow<MessageMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
override val editedMessagesFlow: Flow<EditMessageUpdate> = allUpdatesFlow.filterIsInstance()
override val editedMessageMediaGroupsFlow: Flow<EditMessageMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
override val channelPostsFlow: Flow<ChannelPostUpdate> = allUpdatesFlow.filterIsInstance()
override val channelPostMediaGroupsFlow: Flow<ChannelPostMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
override val editedChannelPostsFlow: Flow<EditChannelPostUpdate> = allUpdatesFlow.filterIsInstance()
override val editedChannelPostMediaGroupsFlow: Flow<EditChannelPostMediaGroupUpdate> = allUpdatesFlow.filterIsInstance()
override val chosenInlineResultsFlow: Flow<ChosenInlineResultUpdate> = allUpdatesFlow.filterIsInstance()
override val inlineQueriesFlow: Flow<InlineQueryUpdate> = allUpdatesFlow.filterIsInstance()
override val callbackQueriesFlow: Flow<CallbackQueryUpdate> = allUpdatesFlow.filterIsInstance()
override val shippingQueriesFlow: Flow<ShippingQueryUpdate> = allUpdatesFlow.filterIsInstance()
override val preCheckoutQueriesFlow: Flow<PreCheckoutQueryUpdate> = allUpdatesFlow.filterIsInstance()
override val pollsFlow: Flow<PollUpdate> = allUpdatesFlow.filterIsInstance()
override val pollAnswersFlow: Flow<PollAnswerUpdate> = allUpdatesFlow.filterIsInstance()
override val chatMemberUpdatesFlow: Flow<CommonChatMemberUpdatedUpdate> = allUpdatesFlow.filterIsInstance()
override val myChatMemberUpdatesFlow: Flow<MyChatMemberUpdatedUpdate> = allUpdatesFlow.filterIsInstance()
override val unknownUpdatesFlow: Flow<UnknownUpdate> = allUpdatesFlow.filterIsInstance()
}

View File

@@ -8,4 +8,11 @@ object BuiltinMimeTypes {
object Video {
val MP4 = buildMimeType("video/mp4")
}
object Text {
val Html = buildMimeType("text/html")
}
object Application {
val Zip = buildMimeType("application/zip")
val Pdf = buildMimeType("application/pdf")
}
}

View File

@@ -0,0 +1,22 @@
package dev.inmo.tgbotapi.utils
import dev.inmo.micro_utils.common.ByteArrayAllocatorSerializer
import io.ktor.utils.io.ByteReadChannel
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
fun interface ByteReadChannelAllocator {
suspend operator fun invoke(): ByteReadChannel
}
object ByteReadChannelAllocatorDeserializationStrategy : DeserializationStrategy<ByteReadChannelAllocator> {
override val descriptor: SerialDescriptor = ByteArrayAllocatorSerializer.descriptor
override fun deserialize(decoder: Decoder): ByteReadChannelAllocator {
val byteArrayAllocator = ByteArrayAllocatorSerializer.deserialize(decoder)
return ByteReadChannelAllocator { ByteReadChannel(byteArrayAllocator()) }
}
}

View File

@@ -0,0 +1,6 @@
package dev.inmo.tgbotapi.utils
import io.ktor.utils.io.ByteReadChannel
import io.ktor.utils.io.core.Input
expect suspend fun ByteReadChannel.asInput(): Input

View File

@@ -1,6 +1,7 @@
package dev.inmo.tgbotapi.utils
import com.benasher44.uuid.uuid4
import io.ktor.utils.io.*
import io.ktor.utils.io.core.ByteReadPacket
import io.ktor.utils.io.core.Input
import kotlinx.serialization.Serializable
@@ -13,9 +14,14 @@ import kotlinx.serialization.Serializable
*/
@Serializable
data class StorageFileInfo(
val contentType: String,
val fileName: String
) {
@Deprecated("This constructor is redundant. Use constructor without mime type")
constructor(
contentType: String,
fileName: String
): this(fileName)
/**
* This methods is required for random generation of name for keeping warranties about unique file name
*/
@@ -39,19 +45,55 @@ data class StorageFile(
get() = inputSource()
}
@Deprecated("This constructor is redundant. Use constructor without mime type")
@Suppress("NOTHING_TO_INLINE")
inline fun StorageFile(
fileName: String,
bytes: ByteArray,
mimeType: MimeType
) = StorageFile(
StorageFileInfo(mimeType.raw, fileName)
StorageFileInfo(fileName)
) {
ByteReadPacket(bytes)
}
/**
*
*/
@Suppress("NOTHING_TO_INLINE")
inline fun StorageFile(
fileName: String,
bytes: ByteArray
) = StorageFile(
StorageFileInfo(fileName)
) {
ByteReadPacket(bytes)
}
@Suppress("NOTHING_TO_INLINE")
suspend inline fun StorageFile(
fileName: String,
byteReadChannel: ByteReadChannel
) = StorageFile(
StorageFileInfo(fileName),
byteReadChannel.asInput().let { { it } }
)
@Suppress("NOTHING_TO_INLINE", "unused")
inline fun ByteArray.asStorageFile(fileName: String, mimeType: MimeType) = StorageFile(fileName, this, mimeType)
inline fun ByteArray.asStorageFile(
fileName: String
) = StorageFile(fileName, this)
@Deprecated("This constructor is redundant. Use constructor without mime type")
@Suppress("NOTHING_TO_INLINE", "unused")
inline fun ByteArray.asStorageFile(
fileName: String,
mimeType: MimeType
) = asStorageFile(fileName)
@Suppress("NOTHING_TO_INLINE", "unused")
suspend inline fun ByteReadChannel.asStorageFile(
fileName: String
) = StorageFile(fileName, this)
@Suppress("NOTHING_TO_INLINE", "unused")
suspend inline fun ByteReadChannelAllocator.asStorageFile(
fileName: String
) = this.invoke().asStorageFile(fileName)

View File

@@ -26,4 +26,6 @@ class TelegramAPIUrlsKeeper(
commonAPIUrl = "$correctedHost/bot$token"
fileBaseUrl = "$correctedHost/file/bot$token"
}
fun createFileLinkUrl(filePath: String) = "${fileBaseUrl}/$filePath"
}

View File

@@ -0,0 +1,8 @@
package dev.inmo.tgbotapi.utils
import io.ktor.util.toByteArray
import io.ktor.utils.io.ByteReadChannel
import io.ktor.utils.io.core.ByteReadPacket
import io.ktor.utils.io.core.Input
actual suspend fun ByteReadChannel.asInput(): Input = ByteReadPacket(toByteArray())

View File

@@ -7,10 +7,7 @@ import java.nio.file.Files
fun StorageFile(
file: File
) = StorageFile(
StorageFileInfo(
Files.probeContentType(file.toPath()),
file.name
)
StorageFileInfo(file.name)
) {
file.inputStream().asInput()
}

View File

@@ -0,0 +1,10 @@
package dev.inmo.tgbotapi.utils
import io.ktor.utils.io.ByteReadChannel
import io.ktor.utils.io.core.Input
import io.ktor.utils.io.jvm.javaio.toInputStream
import io.ktor.utils.io.streams.asInput
import kotlinx.coroutines.job
import kotlin.coroutines.coroutineContext
actual suspend fun ByteReadChannel.asInput(): Input = toInputStream(coroutineContext.job).asInput()

View File

@@ -1,8 +1,19 @@
# TelegramBotAPI extensions
[![Download](https://api.bintray.com/packages/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.api/images/download.svg) ](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.api/_latestVersion)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.api/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.api)
- [TelegramBotAPI extensions](#telegrambotapi-extensions)
* [What is it?](#what-is-it)
* [Compatibility](#compatibility)
* [How to implement library?](#how-to-implement-library)
+ [Maven](#maven)
+ [Gradle](#gradle)
* [Example of usage and comparison with `TelegramBotAPI`](#example-of-usage-and-comparison-with-telegrambotapi)
* [Updates](#updates)
+ [Alternative way](#alternative-way)
<small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with markdown-toc</a></i></small>
## What is it?
It is wrapper library for [TelegramBotAPI Core](../tgbotapi.core/README.md). Here you can find extensions for

View File

@@ -1,39 +1,33 @@
package dev.inmo.tgbotapi.extensions.api
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
import dev.inmo.tgbotapi.requests.DownloadFile
import dev.inmo.tgbotapi.extensions.api.files.downloadFile
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.types.files.PathedFile
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile"))
suspend fun TelegramBot.downloadFile(
filePath: String
): ByteArray = execute(
DownloadFile(filePath)
)
): ByteArray = downloadFile(filePath)
@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile"))
suspend fun TelegramBot.downloadFile(
pathedFile: PathedFile
): ByteArray = execute(
DownloadFile(pathedFile.filePath)
)
): ByteArray = downloadFile(pathedFile)
@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile"))
suspend fun TelegramBot.downloadFile(
fileId: FileId
): ByteArray = downloadFile(
getFileAdditionalInfo(fileId)
)
): ByteArray = downloadFile(fileId)
@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile"))
suspend fun TelegramBot.downloadFile(
file: TelegramMediaFile
): ByteArray = downloadFile(
getFileAdditionalInfo(file)
)
): ByteArray = downloadFile(file)
@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile"))
suspend fun TelegramBot.downloadFile(
file: MediaContent
): ByteArray = downloadFile(
getFileAdditionalInfo(file.media)
)
): ByteArray = downloadFile(file)

View File

@@ -21,6 +21,10 @@ import kotlinx.coroutines.launch
import kotlin.math.ceil
val defaultLivePeriodDelayMillis = (livePeriodLimit.last - 60L) * 1000L
/**
* @see startLiveLocation
*/
class LiveLocationProvider internal constructor(
private val requestsExecutor: TelegramBot,
scope: CoroutineScope,

View File

@@ -0,0 +1,39 @@
package dev.inmo.tgbotapi.extensions.api.files
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
import dev.inmo.tgbotapi.requests.DownloadFile
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.types.files.PathedFile
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
suspend fun TelegramBot.downloadFile(
filePath: String
): ByteArray = execute(
DownloadFile(filePath)
)
suspend fun TelegramBot.downloadFile(
pathedFile: PathedFile
): ByteArray = downloadFile(
pathedFile.filePath
)
suspend fun TelegramBot.downloadFile(
fileId: FileId
): ByteArray = downloadFile(
getFileAdditionalInfo(fileId)
)
suspend fun TelegramBot.downloadFile(
file: TelegramMediaFile
): ByteArray = downloadFile(
getFileAdditionalInfo(file)
)
suspend fun TelegramBot.downloadFile(
file: MediaContent
): ByteArray = downloadFile(
getFileAdditionalInfo(file.media)
)

View File

@@ -0,0 +1,29 @@
package dev.inmo.tgbotapi.extensions.api.files
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
import dev.inmo.tgbotapi.requests.DownloadFileStream
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.types.files.PathedFile
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
suspend fun TelegramBot.downloadFileStream(
filePath: String
) = downloadFileStreamAllocator(filePath).invoke()
suspend fun TelegramBot.downloadFileStream(
pathedFile: PathedFile
) = downloadFileStream(pathedFile.filePath)
suspend fun TelegramBot.downloadFileStream(
fileId: FileId
) = downloadFileStream(getFileAdditionalInfo(fileId))
suspend fun TelegramBot.downloadFileStream(
file: TelegramMediaFile
) = downloadFileStream(getFileAdditionalInfo(file))
suspend fun TelegramBot.downloadFileStream(
file: MediaContent
) = downloadFileStream(getFileAdditionalInfo(file.media))

View File

@@ -0,0 +1,29 @@
package dev.inmo.tgbotapi.extensions.api.files
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
import dev.inmo.tgbotapi.requests.DownloadFileStream
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.types.files.PathedFile
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
suspend fun TelegramBot.downloadFileStreamAllocator(
filePath: String
) = execute(DownloadFileStream(filePath))
suspend fun TelegramBot.downloadFileStreamAllocator(
pathedFile: PathedFile
) = downloadFileStreamAllocator(pathedFile.filePath)
suspend fun TelegramBot.downloadFileStreamAllocator(
fileId: FileId
) = downloadFileStreamAllocator(getFileAdditionalInfo(fileId))
suspend fun TelegramBot.downloadFileStreamAllocator(
file: TelegramMediaFile
) = downloadFileStreamAllocator(getFileAdditionalInfo(file))
suspend fun TelegramBot.downloadFileStreamAllocator(
file: MediaContent
) = downloadFileStreamAllocator(getFileAdditionalInfo(file.media))

View File

@@ -4,6 +4,7 @@ import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.requests.get.GetFile
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
suspend fun TelegramBot.getFileAdditionalInfo(
fileId: FileId
@@ -14,3 +15,7 @@ suspend fun TelegramBot.getFileAdditionalInfo(
suspend fun TelegramBot.getFileAdditionalInfo(
file: TelegramMediaFile
) = getFileAdditionalInfo(file.fileId)
suspend fun TelegramBot.getFileAdditionalInfo(
content: MediaContent
) = getFileAdditionalInfo(content.media)

View File

@@ -0,0 +1,64 @@
package dev.inmo.tgbotapi.extensions.api.files
import dev.inmo.micro_utils.coroutines.doOutsideOfCoroutine
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.types.files.PathedFile
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
import io.ktor.util.cio.use
import io.ktor.util.cio.writeChannel
import io.ktor.utils.io.copyTo
import kotlinx.coroutines.job
import java.io.File
import kotlin.coroutines.coroutineContext
suspend fun TelegramBot.downloadFile(
filePath: String,
destFile: File
): File {
val readChannel = downloadFileStream(filePath)
destFile.deleteRecursively()
destFile.parentFile.mkdirs()
doOutsideOfCoroutine { destFile.createNewFile() }
destFile.writeChannel(coroutineContext.job).use {
readChannel.copyTo(this)
}
return destFile
}
suspend fun TelegramBot.downloadFile(
pathedFile: PathedFile,
destFile: File
) = downloadFile(
pathedFile.filePath,
destFile
)
suspend fun TelegramBot.downloadFile(
fileId: FileId,
destFile: File
) = downloadFile(
getFileAdditionalInfo(fileId),
destFile
)
suspend fun TelegramBot.downloadFile(
file: TelegramMediaFile,
destFile: File
): File = downloadFile(
getFileAdditionalInfo(file),
destFile
)
suspend fun TelegramBot.downloadFile(
file: MediaContent,
destFile: File
) = downloadFile(
getFileAdditionalInfo(file.media),
destFile
)

View File

@@ -1,5 +1,16 @@
# TelegramBotAPI Behaviour Builder Extensions
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.behaviour_builder/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.behaviour_builder)
- [TelegramBotAPI Behaviour Builder Extensions](#telegrambotapi-behaviour-builder-extensions)
* [What is it?](#what-is-it)
* [Triggers](#triggers)
* [Waiters](#waiters)
<small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with markdown-toc</a></i></small>
## What is it?
This extension was created to make it more simple to build bot steps handling. Usually, you must use something like:
```kotlin

View File

@@ -1,5 +1,6 @@
# TelegramBotAPI Util Extensions
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.utils/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.utils)
- [TelegramBotAPI Util Extensions](#telegrambotapi-util-extensions)
* [What is it?](#what-is-it)
@@ -9,7 +10,7 @@
* [How to use?](#how-to-use)
+ [Updates](#updates)
- [Long polling](#long-polling)
- [WebHooks (currently JVM-only)](#webhooks--currently-jvm-only)
- [WebHooks (currently JVM-only)](#webhooks-currently-jvm-only)
+ [Filters](#filters)
- [Sent messages](#sent-messages)
* [Common messages](#common-messages)
@@ -19,9 +20,6 @@
<small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with markdown-toc</a></i></small>
[![Download](https://api.bintray.com/packages/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.utils/images/download.svg) ](https://bintray.com/insanusmokrassar/TelegramBotAPI/tgbotapi.extensions.utils/_latestVersion)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.utils/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/tgbotapi.extensions.utils)
## What is it?
It is wrapper library for [TelegramBotAPI Core](../tgbotapi.core/README.md). Currently, this library contains some usefull filters for commands, updates types and different others.

View File

@@ -6,14 +6,16 @@ import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.merge
@Deprecated("Will be removed soon", ReplaceWith("messagesFlow + channelPostsFlow"))
val FlowsUpdatesFilter.allSentMessagesFlow: Flow<BaseSentMessageUpdate>
get() = merge(
messageFlow,
channelPostFlow
messagesFlow,
channelPostsFlow
)
@Deprecated("Will be removed soon", ReplaceWith("messageMediaGroupsFlow + channelPostMediaGroupsFlow"))
val FlowsUpdatesFilter.allSentMediaGroupsFlow: Flow<SentMediaGroupUpdate>
get() = merge(
messageMediaGroupFlow,
channelPostMediaGroupFlow
messageMediaGroupsFlow,
channelPostMediaGroupsFlow
)

View File

@@ -14,21 +14,21 @@ import kotlinx.coroutines.flow.mapNotNull
@RiskFeature("Use with caution")
inline fun FlowsUpdatesFilter.events(): Flow<ChatEventMessage<*>> {
return channelPostFlow.mapNotNull { it.data as? ChatEventMessage<*> } + messageFlow.mapNotNull { it.data as? ChatEventMessage<*> }
return channelPostsFlow.mapNotNull { it.data as? ChatEventMessage<*> } + messagesFlow.mapNotNull { it.data as? ChatEventMessage<*> }
}
@RiskFeature("Use with caution")
inline fun FlowsUpdatesFilter.channelEvents(): Flow<ChannelEventMessage<*>> = channelPostFlow.mapNotNull {
inline fun FlowsUpdatesFilter.channelEvents(): Flow<ChannelEventMessage<*>> = channelPostsFlow.mapNotNull {
it.data as? ChannelEventMessage<*>
}
@RiskFeature("Use with caution")
inline fun FlowsUpdatesFilter.groupEvents(): Flow<GroupEventMessage<*>> = messageFlow.mapNotNull {
inline fun FlowsUpdatesFilter.groupEvents(): Flow<GroupEventMessage<*>> = messagesFlow.mapNotNull {
it.data as? GroupEventMessage<*>
}
@RiskFeature("Use with caution")
inline fun FlowsUpdatesFilter.supergroupEvents(): Flow<SupergroupEventMessage<*>> = messageFlow.mapNotNull {
inline fun FlowsUpdatesFilter.supergroupEvents(): Flow<SupergroupEventMessage<*>> = messagesFlow.mapNotNull {
it.data as? SupergroupEventMessage<*>
}

View File

@@ -47,8 +47,8 @@ inline fun <reified T : MediaGroupContent> Flow<SentMediaGroupUpdate>.filterMedi
/**
* @param scopeToIncludeChannels This parameter is required when you want to include [textMessages] for channels too.
* In this case will be created new channel which will aggregate messages from [FlowsUpdatesFilter.messageFlow] and
* [FlowsUpdatesFilter.channelPostFlow]. In case it is null will be used [Flow]s mapping
* In this case will be created new channel which will aggregate messages from [FlowsUpdatesFilter.messagesFlow] and
* [FlowsUpdatesFilter.channelPostsFlow]. In case it is null will be used [Flow]s mapping
*/
@Suppress("UNCHECKED_CAST")
@RiskFeature(lowLevelRiskFeatureMessage)
@@ -58,16 +58,16 @@ inline fun <reified T: MessageContent> FlowsUpdatesFilter.filterContentMessages(
return (scopeToIncludeChannels ?.let { scope ->
aggregateFlows(
scope,
messageFlow,
channelPostFlow
messagesFlow,
channelPostsFlow
)
} ?: messageFlow).filterContentMessages()
} ?: messagesFlow).filterContentMessages()
}
/**
* @param scopeToIncludeChannels This parameter is required when you want to include [SentMediaGroupUpdate] for channels
* too. In this case will be created new channel which will aggregate messages from [FlowsUpdatesFilter.messageFlow] and
* [FlowsUpdatesFilter.channelPostFlow]. In case it is null will be used [Flow]s mapping
* too. In this case will be created new channel which will aggregate messages from [FlowsUpdatesFilter.messagesFlow] and
* [FlowsUpdatesFilter.channelPostsFlow]. In case it is null will be used [Flow]s mapping
*/
@Suppress("UNCHECKED_CAST")
@RiskFeature(lowLevelRiskFeatureMessage)
@@ -77,10 +77,10 @@ inline fun <reified T: MediaGroupContent> FlowsUpdatesFilter.filterMediaGroupMes
return (scopeToIncludeChannels ?.let { scope ->
aggregateFlows(
scope,
messageMediaGroupFlow,
channelPostMediaGroupFlow
messageMediaGroupsFlow,
channelPostMediaGroupsFlow
)
} ?: messageMediaGroupFlow).filterMediaGroupMessages()
} ?: messageMediaGroupsFlow).filterMediaGroupMessages()
}
fun FlowsUpdatesFilter.sentMessages(

View File

@@ -0,0 +1,38 @@
package dev.inmo.tgbotapi.extensions.utils.types.files
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.requests.DownloadFileStream
import dev.inmo.tgbotapi.requests.abstracts.FileId
import dev.inmo.tgbotapi.requests.get.GetFile
import dev.inmo.tgbotapi.types.files.PathedFile
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
import dev.inmo.tgbotapi.utils.*
suspend fun convertToStorageFile(
downloadStreamAllocator: ByteReadChannelAllocator,
pathedFile: PathedFile
): StorageFile {
return downloadStreamAllocator.asStorageFile(
pathedFile.fileName
)
}
suspend fun TelegramBot.convertToStorageFile(
pathedFile: PathedFile
): StorageFile = convertToStorageFile(
execute(DownloadFileStream(pathedFile.filePath)),
pathedFile
)
suspend fun TelegramBot.convertToStorageFile(
fileId: FileId
): StorageFile = convertToStorageFile(execute(GetFile(fileId)))
suspend fun TelegramBot.convertToStorageFile(
file: TelegramMediaFile
): StorageFile = convertToStorageFile(file.fileId)
suspend fun TelegramBot.convertToStorageFile(
content: MediaContent
): StorageFile = convertToStorageFile(content.media)

View File

@@ -9,6 +9,7 @@ fun PathedFile.asStream(
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
): InputStream = URL(this.fullUrl(telegramAPIUrlsKeeper)).openStream()
@Deprecated("This api will be removed soon. Use `downloadFile` instead")
fun PathedFile.asFile(
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
dest: File = File.createTempFile(this.fileUniqueId, this.filename),
@@ -22,6 +23,7 @@ fun PathedFile.asFile(
return dest
}
@Deprecated("This api will be removed soon. Use `downloadFile` instead")
fun PathedFile.asBytes(
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
): ByteArray = this.asStream(telegramAPIUrlsKeeper)