Compare commits

...

193 Commits

Author SHA1 Message Date
0c5186a37d add toggle closing confirmation button 2022-08-15 01:28:59 +06:00
7e9968ced9 add work with alerts in webapp 2022-08-15 01:12:39 +06:00
f1e8ed88a8 Merge pull request #139 from InsanusMokrassar/3.1.0
3.1.0
2022-08-13 16:58:34 +06:00
068dc79ac8 migration onto 3.1.0 and including new example 2022-08-13 14:39:24 +06:00
36273adfd1 Merge pull request #136 from InsanusMokrassar/3.0.0
3.0.0
2022-08-06 08:33:15 +06:00
bca2ae905b Update gradle-wrapper.properties 2022-08-06 08:19:13 +06:00
19a713a3e3 Update gradle.properties 2022-08-06 08:18:55 +06:00
e039f90961 updates according to 3.0.0 2022-08-05 19:45:52 +06:00
21692d16ca fixes in forward chat info bot 2022-08-04 22:32:36 +06:00
d547dce2ab update dependencies 2022-08-04 21:41:55 +06:00
9bfe88a79c Merge pull request #134 from InsanusMokrassar/renovate/telegram_bot_api_version
Update telegram_bot_api_version to v2.2.2
2022-07-31 21:48:05 +06:00
renovate[bot]
bfa327acf3 Update telegram_bot_api_version to v2.2.2 2022-07-31 15:35:38 +00:00
88a031b05a Update gradle.properties 2022-07-22 20:26:06 +06:00
20e942b2ac Merge pull request #133 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.11.13
2022-07-22 20:14:02 +06:00
renovate[bot]
3e20cbd22c Update dependency dev.inmo:micro_utils.ktor.server to v0.11.13 2022-07-22 14:10:56 +00:00
bcd35de038 Merge pull request #131 from InsanusMokrassar/renovate/telegram_bot_api_version
Update telegram_bot_api_version to v2.2.0
2022-07-11 12:05:16 +06:00
renovate[bot]
2aec45d453 Update telegram_bot_api_version to v2.2.0 2022-07-11 06:03:16 +00:00
ee55378e7a Update gradle.properties 2022-07-10 00:34:53 +06:00
b402c7b6e7 Merge pull request #130 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.11.12
2022-07-02 12:07:54 +06:00
renovate[bot]
32b7c7b9a4 Update dependency dev.inmo:micro_utils.ktor.server to v0.11.12 2022-07-02 06:02:52 +00:00
0b2d6b20de Merge pull request #129 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.11.10
2022-06-30 13:50:34 +06:00
renovate[bot]
182ee7a865 Update dependency dev.inmo:micro_utils.ktor.server to v0.11.10 2022-06-30 05:26:51 +00:00
0652a95d11 Merge pull request #128 from InsanusMokrassar/renovate/telegram_bot_api_version
Update telegram_bot_api_version to v2.1.2
2022-06-29 18:41:36 +06:00
renovate[bot]
f6066c60c0 Update telegram_bot_api_version to v2.1.2 2022-06-29 12:41:23 +00:00
2fa340292c Merge pull request #127 from InsanusMokrassar/renovate/ktor_version
Update dependency io.ktor:ktor-server-cio to v2.0.3
2022-06-29 18:41:04 +06:00
7d94007905 Merge pull request #126 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.11.9
2022-06-29 18:40:53 +06:00
renovate[bot]
9638174d48 Update dependency dev.inmo:micro_utils.ktor.server to v0.11.9 2022-06-29 11:53:40 +00:00
renovate[bot]
18bacaea2e Update dependency io.ktor:ktor-server-cio to v2.0.3 2022-06-28 16:35:40 +00:00
0f2b3760dd Merge pull request #125 from InsanusMokrassar/2.1.1
2.1.1
2022-06-26 15:24:30 +06:00
730923f55c actualization 2022-06-26 13:25:26 +06:00
9cf8bd9f28 migration onto 2.1.1 2022-06-26 13:03:52 +06:00
370fa45dba Merge pull request #124 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.11.6
2022-06-24 08:27:13 +06:00
renovate[bot]
72e7a73e40 Update dependency dev.inmo:micro_utils.ktor.server to v0.11.6 2022-06-23 23:54:36 +00:00
10dd9bd851 Merge pull request #123 from InsanusMokrassar/2.1.0
2.1.0
2022-06-22 00:43:36 +06:00
0217f97014 checked 2.1.0 and Bot API 6.1 + update several examples 2022-06-21 19:45:24 +06:00
4ae700b58a Merge pull request #121 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.11.3
2022-06-17 17:44:48 +06:00
renovate[bot]
804fb1e5ee Update dependency dev.inmo:micro_utils.ktor.server to v0.11.3 2022-06-17 11:44:38 +00:00
d443c39813 Merge pull request #122 from InsanusMokrassar/renovate/telegram_bot_api_version
Update telegram_bot_api_version to v2.0.3
2022-06-17 17:43:10 +06:00
renovate[bot]
cd96547d15 Update telegram_bot_api_version to v2.0.3 2022-06-17 11:42:07 +00:00
f107b4144d Update gradle.properties 2022-06-05 21:25:59 +06:00
39f4196b76 Merge pull request #119 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.11.0
2022-06-05 21:25:40 +06:00
Renovate Bot
22b9776c26 Update dependency dev.inmo:micro_utils.ktor.server to v0.11.0 2022-06-05 05:10:25 +00:00
2f8f6f3169 Merge pull request #118 from Akkihi/master
fixing example webapp mobile view with html meta
2022-06-04 16:49:52 +06:00
f2b6a50cb5 fixing example webapp mobile view with html meta 2022-06-04 14:46:28 +04:00
acd602d6fa Merge pull request #116 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.10.8
2022-06-03 10:33:33 +06:00
fdb80bf471 Merge pull request #115 from InsanusMokrassar/renovate/ktor_version
Update dependency io.ktor:ktor-server-cio to v2.0.2
2022-06-03 08:57:38 +06:00
Renovate Bot
78c58db4b7 Update dependency dev.inmo:micro_utils.ktor.server to v0.10.8 2022-06-03 02:57:34 +00:00
edd6399bcc Merge pull request #117 from InsanusMokrassar/renovate/telegram_bot_api_version
Update telegram_bot_api_version to v2.0.1
2022-06-03 08:56:53 +06:00
Renovate Bot
9513e77ba3 Update telegram_bot_api_version to v2.0.1 2022-05-29 20:26:33 +00:00
Renovate Bot
ac75f6487e Update dependency io.ktor:ktor-server-cio to v2.0.2 2022-05-27 18:22:47 +00:00
07750a71c0 Merge pull request #114 from InsanusMokrassar/2.0.0
2.0.0
2022-05-22 14:55:10 +06:00
0bf7e33df3 migration onto 2.0.0 and several improvements 2022-05-22 12:57:53 +06:00
7fb308ea4b Merge pull request #113 from InsanusMokrassar/renovate/telegram_bot_api_version
Update telegram_bot_api_version to v1.1.3
2022-05-19 14:57:05 -04:00
Renovate Bot
75b403ac98 Update telegram_bot_api_version to v1.1.3 2022-05-19 18:56:32 +00:00
5976e37046 Merge pull request #112 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.10.5
2022-05-19 14:56:10 -04:00
Renovate Bot
c8a94496c7 Update dependency dev.inmo:micro_utils.ktor.server to v0.10.5 2022-05-19 17:40:28 +00:00
f6550bd401 Merge pull request #110 from InsanusMokrassar/1.1.2
1.1.2
2022-05-18 10:24:09 -04:00
389d96f323 fix of checkWebAppData method call 2022-05-18 17:46:50 +06:00
803c5fd664 add handling of errors in FSMBot and update up to tgbotapi 1.1.2 2022-05-18 17:46:04 +06:00
b6eb4fe134 Merge pull request #108 from InsanusMokrassar/1.1.1
1.1.1
2022-05-17 16:05:35 -04:00
9a4bd55ef6 update tgbotapi version 2022-05-17 19:55:42 +06:00
4dac411693 add support of data checking in webapp 2022-05-17 18:58:43 +06:00
d386d50f1c Merge pull request #107 from InsanusMokrassar/renovate/telegram_bot_api_version
Update telegram_bot_api_version to v1.1.0
2022-05-14 17:33:30 +06:00
Renovate Bot
1b846a6383 Update telegram_bot_api_version to v1.1.0 2022-05-14 11:33:22 +00:00
568b845890 Merge pull request #106 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.ktor.server to v0.10.4
2022-05-14 17:32:48 +06:00
Renovate Bot
3ebca4a058 Update dependency dev.inmo:micro_utils.ktor.server to v0.10.4 2022-05-12 15:37:39 +00:00
2b9af2f667 Merge pull request #104 from InsanusMokrassar/1.0.0
1.0.0
2022-05-12 17:05:10 +06:00
16410debff decrease xmx 2022-05-12 17:00:22 +06:00
a18f22fe8f update xmx for builds 2022-05-12 16:47:46 +06:00
0489f217b3 update examples 2022-05-11 12:15:18 +06:00
e772cfda3b start migration onto 1.0.0 2022-05-11 02:47:37 +06:00
9d42385662 1.0.0 migration preview 2022-05-11 00:23:14 +06:00
b740203116 0.38.23 2022-05-08 00:41:13 +06:00
149717301d Update gradle.properties 2022-05-05 15:16:24 +06:00
60e72be844 Merge pull request #103 from InsanusMokrassar/0.38.21
0.38.21
2022-05-04 14:54:45 +06:00
831b558724 fixes 2022-05-04 13:27:39 +06:00
df778b4e93 start migration onto 0.38.20 2022-05-04 12:22:49 +06:00
bf0c6497fe Merge pull request #101 from Akkihi/master
sendData does not work with inlineKeyboard
2022-05-03 23:57:07 +06:00
akkkihi
71a047f867 sendData does not work with inlineKeyboard 2022-05-03 17:55:08 +04:00
2ae3e1165d Update gradle.properties 2022-05-03 15:55:27 +06:00
9a5d02512b Update gradle.properties 2022-05-02 14:28:05 +06:00
dd2c528006 Update gradle.properties 2022-05-01 18:42:09 +06:00
1c16a9f868 Create README.md 2022-04-30 08:47:35 +06:00
00c3aba12b Merge pull request #97 from InsanusMokrassar/0.38.16
0.38.16
2022-04-30 08:40:17 +06:00
a547bbce65 Merge branch 'master' into 0.38.16 2022-04-30 08:39:01 +06:00
0b7d8c087f update tgbotapi and add webapps example 2022-04-29 20:57:16 +06:00
8ec282e3d5 Merge pull request #96 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.38.15
2022-04-26 15:48:10 +06:00
Renovate Bot
e8433cd8ac Update dependency dev.inmo:tgbotapi to v0.38.15 2022-04-26 09:46:32 +00:00
222134836a update up to 0.38.13 2022-04-17 00:26:04 +06:00
c18e02dcb3 Merge pull request #94 from InsanusMokrassar/0.38.12
Add keyboards and update tgbotapi up to 0.38.12
2022-04-16 23:52:43 +06:00
f9050061d1 add keyboards and update tgbotapi up to 0.38.12 2022-04-09 12:20:35 +06:00
a3e3f6c22c Update gradle.properties 2022-03-30 07:54:57 +06:00
516cc7bfcb Merge pull request #89 from InsanusMokrassar/0.38.10
Update up to 0.38.10
2022-03-25 21:26:18 +06:00
c707a11b66 update gradle 2022-03-24 16:53:32 +06:00
c6c418c393 update up to 0.38.10 2022-03-24 16:52:13 +06:00
e0795c3c14 update up to 0.38.8 2022-03-21 11:25:59 +06:00
dec55990dc Merge pull request #87 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.38.7
2022-03-12 22:59:42 +06:00
Renovate Bot
169f3f5bd5 Update dependency dev.inmo:tgbotapi to v0.38.7 2022-03-12 16:26:32 +00:00
e175bb6143 Update gradle-wrapper.properties 2022-02-28 09:07:15 +06:00
290d722ae6 Update gradle.properties 2022-02-28 09:06:50 +06:00
9ee85df1ad Merge pull request #85 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.38.6
2022-02-28 09:06:20 +06:00
Renovate Bot
2953c40963 Update dependency dev.inmo:tgbotapi to v0.38.6 2022-02-28 03:04:39 +00:00
512067b056 Merge pull request #84 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.38.5
2022-02-12 12:55:49 +06:00
Renovate Bot
0cb209dc6e Update dependency dev.inmo:tgbotapi to v0.38.5 2022-02-09 11:00:15 +00:00
7cf6814d89 update up to 0.38.4 2022-02-02 13:30:32 +06:00
09e8492439 Merge pull request #82 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.38.3
2022-01-14 23:19:51 +06:00
Renovate Bot
71222f42e5 Update dependency dev.inmo:tgbotapi to v0.38.3 2022-01-14 17:18:46 +00:00
426d649877 Merge pull request #81 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.38.2
2022-01-12 01:26:24 +06:00
Renovate Bot
93faf9654a Update dependency dev.inmo:tgbotapi to v0.38.2 2022-01-11 16:19:57 +00:00
288386e25a Update gradle.properties 2022-01-11 20:19:49 +06:00
99e83589a4 Merge pull request #80 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.38.1
2022-01-07 15:51:02 +06:00
Renovate Bot
fbea95fc0a Update dependency dev.inmo:tgbotapi to v0.38.1 2022-01-07 09:31:59 +00:00
0edaa28151 several small updates 2022-01-02 12:06:32 +06:00
df874b0783 update up to 0.38.0 2022-01-02 01:06:04 +06:00
5f5722398d update up to 0.37.3 2021-12-20 14:13:55 +06:00
cc29ec75ca Merge pull request #76 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.37.1
2021-11-15 09:57:36 +06:00
Renovate Bot
a42173acf6 Update dependency dev.inmo:tgbotapi to v0.37.1 2021-11-14 15:41:13 +00:00
d936bc4643 upgrade up to 0.37.0 2021-11-11 12:34:52 +06:00
1b340d8db5 Merge pull request #74 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.36.1
2021-10-24 11:52:00 +06:00
Renovate Bot
4cd1980778 Update dependency dev.inmo:tgbotapi to v0.36.1 2021-10-24 05:26:22 +00:00
d89202aebb update up to 0.36.0 2021-10-18 20:21:58 +06:00
be2de6e372 Merge pull request #71 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.fsm.common to v0.5.31
2021-10-01 20:30:11 +06:00
Renovate Bot
08796f18e8 Update dependency dev.inmo:micro_utils.fsm.common to v0.5.31 2021-10-01 14:28:11 +00:00
8bd7e116e3 Merge pull request #70 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.fsm.common to v0.5.30
2021-09-25 18:12:40 +06:00
Renovate Bot
39d7a95c95 Update dependency dev.inmo:micro_utils.fsm.common to v0.5.30 2021-09-25 12:11:44 +00:00
526ecac89a Merge pull request #68 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.fsm.common to v0.5.29
2021-09-23 17:35:05 +06:00
Renovate Bot
1e4e246fab Update dependency dev.inmo:micro_utils.fsm.common to v0.5.29 2021-09-23 10:02:04 +00:00
6aa7fe151e update up to 0.35.9 2021-09-21 23:22:13 +06:00
16c27fa493 Merge pull request #67 from InsanusMokrassar/renovate/micro_utils_version
Update dependency dev.inmo:micro_utils.fsm.common to v0.5.26
2021-09-09 17:32:00 +06:00
Renovate Bot
f6a811acca Update dependency dev.inmo:micro_utils.fsm.common to v0.5.26 2021-09-09 11:26:29 +00:00
17c08fc906 Update RandomFileSenderBot.kt 2021-09-09 09:20:17 +06:00
aee0943a5e update dependencies and RandomFileSenderBot example 2021-09-08 23:00:19 +06:00
c07f4f2ed1 Update gradle-wrapper.properties 2021-09-05 09:23:25 +06:00
817acb8faf Update gradle.properties 2021-09-05 09:23:00 +06:00
8b294a0cc0 Merge pull request #66 from InsanusMokrassar/renovate/telegram_bot_api_version
Update dependency dev.inmo:tgbotapi to v0.35.7
2021-09-05 09:22:26 +06:00
Renovate Bot
0139cc5dcc Update dependency dev.inmo:tgbotapi to v0.35.7 2021-09-04 12:47:15 +00:00
6d16508277 small actualizations 2021-08-25 15:58:27 +06:00
ce2051d32d Update gradle.properties 2021-08-25 15:52:00 +06:00
1abbcc8789 Update gradle.properties 2021-08-17 09:23:50 +06:00
c5e05dfce1 Update gradle.properties 2021-08-13 22:24:44 +06:00
c1d7129af8 update dependencies 2021-08-09 17:39:04 +06:00
496fc45d2d tgbotapi -> 0.35.3 2021-08-08 20:32:26 +06:00
cdb634e91a Update gradle-wrapper.properties 2021-07-30 13:14:55 +06:00
9d17311918 Update dependencies 2021-07-30 13:14:14 +06:00
12ef88c757 Merge pull request #56 from InsanusMokrassar/0.35.1
0.35.1
2021-06-30 20:42:03 +06:00
4435fdc80c Merge branch 'master' into 0.35.1 2021-06-30 20:28:22 +06:00
cd9eba0393 Update gradle.properties 2021-06-30 20:25:08 +06:00
ef74b33d68 fix main in FSMBot 2021-06-30 13:50:08 +06:00
522d1b55ba add example with oneof and fsm 2021-06-30 13:12:15 +06:00
d062ab86ae update up to 0.35.1 2021-06-28 01:14:16 +06:00
48292ecf72 Merge pull request #54 from InsanusMokrassar/tgbotapi/0.35.0
tgbotapi 0.35.0
2021-06-13 10:08:19 +06:00
22c0fcb439 Update gradle.properties 2021-06-07 19:34:21 +06:00
c90952d3ca update tgbotapi version 2021-05-06 18:24:31 +06:00
b9e9f981c4 Update up to 0.4.34 2021-04-18 17:26:17 +06:00
11836b1e17 Update gradle-wrapper.properties 2021-04-11 04:07:29 +06:00
d30e673539 Merge pull request #44 from InsanusMokrassar/renovate/dev.inmo-tgbotapi-0.x
Update dependency dev.inmo:tgbotapi to v0.33.3
2021-04-06 22:41:03 +06:00
Renovate Bot
5337f1e4f8 Update dependency dev.inmo:tgbotapi to v0.33.3 2021-04-06 16:35:58 +00:00
26fc3c5924 Update gradle.properties 2021-03-30 22:55:20 +06:00
9e0f43dcc0 update 2021-03-12 15:49:16 +06:00
aa89a289ce Update gradle-wrapper.properties 2021-03-04 15:44:47 +06:00
aeb75d48b9 Update gradle.properties 2021-03-04 15:43:33 +06:00
a67db1c214 Update gradle.properties 2021-02-22 14:42:22 +06:00
3c06da09c2 Update gradle.properties 2021-02-18 16:29:21 +06:00
c15c6d2cf1 Update gradle.properties 2021-02-10 01:19:59 +06:00
febfacc3d5 Update gradle-wrapper.properties 2021-02-10 01:18:49 +06:00
3c71bf287f Merge pull request #34 from InsanusMokrassar/renovate/org.jetbrains.kotlin-kotlin-gradle-plugin-1.x
Update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v1.4.30
2021-02-10 01:18:11 +06:00
6f265640a7 update repositories definition 2021-02-04 15:19:36 +06:00
Renovate Bot
b9e8705b2e Update dependency org.jetbrains.kotlin:kotlin-gradle-plugin to v1.4.30 2021-02-03 16:27:00 +00:00
746f3e8a14 Create build.yml 2021-02-02 20:30:24 +06:00
bd621047ee Merge pull request #32 from InsanusMokrassar/renovate/dev.inmo-tgbotapi-0.x
Update dependency dev.inmo:tgbotapi to v0.32.3
2021-02-02 20:25:11 +06:00
Renovate Bot
98f14faeb2 Update dependency dev.inmo:tgbotapi to v0.32.3 2021-02-02 14:18:38 +00:00
ccb29d6977 update tgbotapi version up to 0.32.1, gradle wrapper and resender bot logic according to update of tgbotapi 2021-02-01 12:57:39 +06:00
f5b526e0c5 update up to tgbotapi 0.31.0 2021-01-18 23:32:47 +06:00
c1cfd05446 Update gradle-wrapper.properties 2021-01-09 15:04:58 +06:00
fb7795414b Merge pull request #27 from InsanusMokrassar/renovate/dev.inmo-tgbotapi-0.x
Update dependency dev.inmo:tgbotapi to v0.30.13
2021-01-09 15:01:15 +06:00
Renovate Bot
5cb998b390 Update dependency dev.inmo:tgbotapi to v0.30.13 2021-01-09 08:46:38 +00:00
6f182c774c update tgbotapi version up to 0.30.12, update of readme 2021-01-06 00:01:41 +06:00
79cc1a7c9a Update tgbotapi 0.30.8 -> 0.30.10 2020-12-09 18:21:48 +06:00
4ce79657ac update kotlin 2020-11-21 20:24:17 +06:00
9a86360682 Merge pull request #18 from InsanusMokrassar/renovate/dev.inmo-tgbotapi-0.x
Update dependency dev.inmo:tgbotapi to v0.30.8
2020-11-21 20:23:02 +06:00
50f8e0df61 update 2020-11-21 20:22:11 +06:00
bb846406da Merge pull request #14 from InsanusMokrassar/renovate/dev.inmo-tgbotapi-0.x
Update dependency dev.inmo:tgbotapi to v0.30.7
2020-11-20 16:42:14 +06:00
6766dc4a8f temporal fix for legacy in resender bot 2020-11-18 12:37:24 +06:00
b440757331 update 2020-11-18 12:35:45 +06:00
Renovate Bot
94bfa67eb3 Update dependency dev.inmo:tgbotapi to v0.30.4 2020-11-13 15:21:18 +00:00
6d066532fb rename forwarder bot 2020-11-02 22:44:15 +06:00
d49ce88a0b update and add SlotMachineDetectorBot 2020-11-02 22:35:28 +06:00
3820e29bf2 update tgbotapi version 2020-11-02 14:39:36 +06:00
7b66c89632 update version of telegram bot api 2020-10-27 16:23:27 +06:00
8f79b9e380 Merge pull request #11 from InsanusMokrassar/0.29.0
0.29.0
2020-10-04 23:50:55 +06:00
358bfdaa05 update hello example 2020-10-04 19:18:16 +06:00
dfae8b7f29 update dependencies 2020-10-04 19:11:48 +06:00
1eb9676c19 migration onto 0.29.0 2020-10-04 17:32:50 +06:00
48 changed files with 1337 additions and 259 deletions

16
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: Build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- name: Build with Gradle
run: ./gradlew build

2
.gitignore vendored
View File

@@ -8,3 +8,5 @@ settings.xml
.gradle/
build/
out/
kotlin-js-store/

View File

@@ -1,11 +0,0 @@
language: java
install: true
os: linux
dist: trusty
jdk: oraclejdk8
script:
- ./gradlew build -s

10
FSMBot/README.md Normal file
View File

@@ -0,0 +1,10 @@
# FSM
This bot contains an example of working with FSM included in project
[MicroUtils](https://github.com/InsanusMokrassar/MicroUtils)
## Launch
```bash
../gradlew run --args="BOT_TOKEN"
```

26
FSMBot/build.gradle Normal file
View File

@@ -0,0 +1,26 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName="SimpleFSMBotKt"
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -0,0 +1,68 @@
import dev.inmo.micro_utils.coroutines.AccumulatorFlow
import dev.inmo.micro_utils.fsm.common.State
import dev.inmo.tgbotapi.extensions.api.send.send
import dev.inmo.tgbotapi.extensions.api.send.sendMessage
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
import dev.inmo.tgbotapi.extensions.utils.extensions.parseCommandsWithParams
import dev.inmo.tgbotapi.extensions.utils.formatting.*
import dev.inmo.tgbotapi.types.ChatId
import dev.inmo.tgbotapi.types.message.abstracts.CommonMessage
import dev.inmo.tgbotapi.types.message.content.TextContent
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.first
sealed interface BotState : State
data class ExpectContentOrStopState(override val context: ChatId, val sourceMessage: CommonMessage<TextContent>) : BotState
data class StopState(override val context: ChatId) : BotState
suspend fun main(args: Array<String>) {
val botToken = args.first()
telegramBotWithBehaviourAndFSMAndStartLongPolling<BotState>(
botToken,
CoroutineScope(Dispatchers.IO),
onStateHandlingErrorHandler = { state, e ->
when (state) {
is ExpectContentOrStopState -> {
println("Thrown error on ExpectContentOrStopState")
}
is StopState -> {
println("Thrown error on StopState")
}
}
e.printStackTrace()
state
}
) {
strictlyOn<ExpectContentOrStopState> {
sendMessage(
it.context,
buildEntities {
+"Send me some content or " + botCommand("stop") + " if you want to stop sending"
}
)
val contentMessage = waitContentMessage().first()
val content = contentMessage.content
when {
content is TextContent && content.parseCommandsWithParams().keys.contains("stop") -> StopState(it.context)
else -> {
execute(content.createResend(it.context))
it
}
}
}
strictlyOn<StopState> {
send(it.context, "You have stopped sending of content")
null
}
command("start") {
startChain(ExpectContentOrStopState(it.chat.id, it))
}
}.second.join()
}

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
@@ -13,12 +13,8 @@ apply plugin: 'application'
mainClassName="FilesLoaderBotKt"
repositories {
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "com.github.insanusmokrassar:TelegramBotAPI:$telegram_bot_api_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -1,14 +1,12 @@
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.downloadFile
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.get.getFileAdditionalInfo
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.telegramBot
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.flatMap
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.safely
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.shortcuts.*
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MediaContent
import com.github.insanusmokrassar.TelegramBotAPI.utils.filenameFromUrl
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import dev.inmo.tgbotapi.extensions.api.files.downloadFile
import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onContentMessage
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onMedia
import dev.inmo.tgbotapi.utils.filenameFromUrl
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import java.io.File
/**
@@ -16,27 +14,20 @@ import java.io.File
*/
suspend fun main(args: Array<String>) {
val botToken = args.first()
val directoryOrFile = args.getOrNull(1) ?.let { File(it) } ?: File("")
val directoryOrFile = args.getOrNull(1) ?.let { File(it) } ?: File("/tmp/")
directoryOrFile.mkdirs()
val bot = telegramBot(botToken)
val scope = CoroutineScope(Dispatchers.Default)
bot.startGettingFlowsUpdatesByLongPolling(scope = scope) {
val flow = merge (
filterContentMessages<MediaContent>(),
mediaGroupMessages().flatMap()
)
flow.onEach {
safely({ it.printStackTrace() }) {
val pathedFile = bot.getFileAdditionalInfo(it.content.media)
File(directoryOrFile, pathedFile.filePath.filenameFromUrl).apply {
createNewFile()
writeBytes(bot.downloadFile(pathedFile))
}
telegramBotWithBehaviourAndLongPolling(botToken, CoroutineScope(Dispatchers.IO)) {
onMedia(initialFilter = null) {
val pathedFile = bot.getFileAdditionalInfo(it.content.media)
val outFile = File(directoryOrFile, pathedFile.filePath.filenameFromUrl)
runCatching {
bot.downloadFile(it.content.media, outFile)
}.onFailure {
it.printStackTrace()
}
}.launchIn(scope)
}
scope.coroutineContext[Job]!!.join()
reply(it, "Saved to ${outFile.absolutePath}")
}
onContentMessage { println(it) }
}.second.join()
}

View File

@@ -0,0 +1,21 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName="ForwardInfoSenderBotKt"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -0,0 +1,48 @@
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onContentMessage
import dev.inmo.tgbotapi.extensions.utils.formatting.*
import dev.inmo.tgbotapi.types.chat.CommonBot
import dev.inmo.tgbotapi.types.chat.CommonUser
import dev.inmo.tgbotapi.types.chat.ExtendedBot
import dev.inmo.tgbotapi.types.message.*
import kotlinx.coroutines.*
/**
* This bot will always return message about forwarder. In cases when sent message was not a forward message it will
* send suitable message
*/
suspend fun main(vararg args: String) {
val botToken = args.first()
telegramBotWithBehaviourAndLongPolling(botToken, CoroutineScope(Dispatchers.IO)) {
onContentMessage {
val toAnswer = buildEntities {
when (val forwardInfo = it.forwardInfo) {
null -> +"There is no forward info"
is ForwardInfo.ByAnonymous -> {
regular("Anonymous user which signed as \"") + code(forwardInfo.senderName) + "\""
}
is ForwardInfo.ByUser -> {
val user = forwardInfo.from
when (user) {
is CommonUser -> {
if (user.isPremium) {
regular("Premium user ")
} else {
regular("User ")
}
}
is CommonBot,
is ExtendedBot -> regular("Bot ")
} + code(user.id.chatId.toString()) + " (${user.firstName} ${user.lastName}: ${user.username ?.username ?: "Without username"})"
}
is ForwardInfo.PublicChat.FromChannel -> regular("Channel (") + code(forwardInfo.channelChat.title) + ")"
is ForwardInfo.PublicChat.FromSupergroup -> regular("Supergroup (") + code(forwardInfo.group.title) + ")"
is ForwardInfo.PublicChat.SentByChannel -> regular("Sent by channel (") + code(forwardInfo.channelChat.title) + ")"
}
}
reply(it, toAnswer)
}
}.second.join()
}

View File

@@ -1,24 +0,0 @@
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName="ForwarderBotKt"
repositories {
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "com.github.insanusmokrassar:TelegramBotAPI:$telegram_bot_api_version"
}

View File

@@ -1,43 +0,0 @@
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.send.sendTextMessage
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.telegramBot
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.formatting.codeMarkdownV2
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.formatting.regularMarkdownV2
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.safely
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.asContentMessagesFlow
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.MarkdownV2
import com.github.insanusmokrassar.TelegramBotAPI.types.message.*
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.PossiblyForwardedMessage
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
/**
* This bot will always return message about forwarder. In cases when sent message was not a forward message it will
* send suitable message
*/
suspend fun main(vararg args: String) {
val botToken = args.first()
val bot = telegramBot(botToken)
val scope = CoroutineScope(Dispatchers.Default)
bot.startGettingFlowsUpdatesByLongPolling(scope = scope) {
messageFlow.asContentMessagesFlow().mapNotNull { it as? PossiblyForwardedMessage }.onEach { message ->
safely({ it.printStackTrace() }) {
val toAnswer = when (val forwardInfo = message.forwardInfo) {
null -> "There is no forward info"
is AnonymousForwardInfo -> "Anonymous user which signed as \"${forwardInfo.senderName.codeMarkdownV2()}\""
is UserForwardInfo -> forwardInfo.from.let { user ->
"User ${user.id.chatId.toString().codeMarkdownV2()} " + "(${user.firstName} ${user.lastName}: ${user.username ?.username ?: "Without username"})".regularMarkdownV2()
}
is ForwardFromChannelInfo -> "Channel (".regularMarkdownV2() + (forwardInfo.channelChat).title.codeMarkdownV2() + ")".regularMarkdownV2()
is ForwardFromSupergroupInfo -> "Supergroup (".regularMarkdownV2() + (forwardInfo.group).title.codeMarkdownV2() + ")".regularMarkdownV2()
}
bot.sendTextMessage(message.chat, toAnswer, MarkdownV2)
}
}.launchIn(scope)
}
scope.coroutineContext[Job]!!.join()
}

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
@@ -13,12 +13,9 @@ apply plugin: 'application'
mainClassName="HelloBotKt"
repositories {
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "com.github.insanusmokrassar:TelegramBotAPI:$telegram_bot_api_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -1,5 +1,5 @@
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.bot.getMe
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.telegramBot
import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.bot.getMe
/**
* This is one of the most easiest bot - it will just print information about itself
@@ -10,4 +10,4 @@ suspend fun main(vararg args: String) {
val bot = telegramBot(botToken)
println(bot.getMe())
}
}

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
@@ -13,12 +13,9 @@ apply plugin: 'application'
mainClassName="HelloBotKt"
repositories {
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "com.github.insanusmokrassar:TelegramBotAPI:$telegram_bot_api_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -1,54 +1,51 @@
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.chat.get.getChat
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.send.sendTextMessage
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.telegramBot
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.formatting.linkMarkdownV2
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.formatting.textMentionMarkdownV2
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.safely
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.MarkdownV2
import com.github.insanusmokrassar.TelegramBotAPI.types.User
import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.*
import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.escapeMarkdownV2Common
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.api.chat.get.getChat
import dev.inmo.tgbotapi.extensions.api.send.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onContentMessage
import dev.inmo.tgbotapi.extensions.utils.formatting.linkMarkdownV2
import dev.inmo.tgbotapi.extensions.utils.formatting.textMentionMarkdownV2
import dev.inmo.tgbotapi.types.chat.*
import dev.inmo.tgbotapi.types.chat.GroupChat
import dev.inmo.tgbotapi.types.chat.PrivateChat
import dev.inmo.tgbotapi.types.chat.SupergroupChat
import dev.inmo.tgbotapi.types.message.MarkdownV2
import dev.inmo.tgbotapi.utils.PreviewFeature
import dev.inmo.tgbotapi.utils.extensions.escapeMarkdownV2Common
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
/**
* The main purpose of this bot is just to answer "Oh, hi, " and add user mention here
*/
@OptIn(PreviewFeature::class)
suspend fun main(vararg args: String) {
val botToken = args.first()
val bot = telegramBot(botToken)
val scope = CoroutineScope(Dispatchers.Default)
bot.startGettingFlowsUpdatesByLongPolling(scope = scope) {
messageFlow.onEach {
safely {
val chat = it.data.chat
val message = "Oh, hi, " + when (chat) {
is PrivateChat -> "${chat.firstName} ${chat.lastName}".textMentionMarkdownV2(chat.id)
is User -> "${chat.firstName} ${chat.lastName}".textMentionMarkdownV2(chat.id)
is SupergroupChat -> (chat.username ?.username ?: bot.getChat(chat).inviteLink) ?.let {
chat.title.linkMarkdownV2(it)
} ?: chat.title
is GroupChat -> bot.getChat(chat).inviteLink ?.let {
chat.title.linkMarkdownV2(it)
} ?: chat.title
else -> "Unknown :(".escapeMarkdownV2Common()
}
bot.sendTextMessage(chat, message, MarkdownV2)
telegramBotWithBehaviourAndLongPolling(botToken, CoroutineScope(Dispatchers.IO)) {
onContentMessage { message ->
val chat = message.chat
if (chat is ChannelChat) {
val answer = "Hi everybody in this channel \"${chat.title}\""
send(chat, answer, MarkdownV2)
return@onContentMessage
}
}.launchIn(scope)
channelPostFlow.onEach {
safely {
val chat = it.data.chat
val message = "Hi everybody in this channel \"${(chat as ChannelChat).title}\""
bot.sendTextMessage(chat, message, MarkdownV2)
val answerText = "Oh, hi, " + when (chat) {
is User -> "${chat.firstName} ${chat.lastName}".textMentionMarkdownV2(chat.id)
is PrivateChat -> "${chat.firstName} ${chat.lastName}".textMentionMarkdownV2(chat.id)
is SupergroupChat -> (chat.username ?.username ?: getChat(chat).inviteLink) ?.let {
chat.title.linkMarkdownV2(it)
} ?: chat.title
is GroupChat -> bot.getChat(chat).inviteLink ?.let {
chat.title.linkMarkdownV2(it)
} ?: chat.title
else -> "Unknown :(".escapeMarkdownV2Common()
}
}.launchIn(scope)
}
scope.coroutineContext[Job]!!.join()
}
reply(
message,
answerText,
MarkdownV2
)
}
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) { println(it) }
}.second.join()
}

View File

@@ -0,0 +1,32 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id "org.jetbrains.kotlin.multiplatform"
}
kotlin {
jvm()
js(IR) {
browser()
binaries.executable()
}
sourceSets {
commonMain {
dependencies {
implementation kotlin('stdlib')
api "dev.inmo:tgbotapi:$telegram_bot_api_version"
}
}
}
}

View File

@@ -0,0 +1,126 @@
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.answers.answer
import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
import dev.inmo.tgbotapi.extensions.api.edit.edit
import dev.inmo.tgbotapi.extensions.api.send.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
import dev.inmo.tgbotapi.extensions.utils.formatting.botCommand
import dev.inmo.tgbotapi.extensions.utils.formatting.buildEntities
import dev.inmo.tgbotapi.extensions.utils.types.buttons.*
import dev.inmo.tgbotapi.extensions.utils.withContent
import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.types.message.content.TextContent
import kotlinx.coroutines.*
private const val nextPageData = "next"
private const val previousPageData = "previous"
fun String.parsePageAndCount(): Pair<Int, Int>? {
val (pageString, countString) = split(" ").takeIf { it.count() > 1 } ?: return null
return Pair(
pageString.toIntOrNull() ?: return null,
countString.toIntOrNull() ?: return null
)
}
fun InlineKeyboardBuilder.includePageButtons(page: Int, count: Int) {
val numericButtons = listOfNotNull(
page - 1,
page,
page + 1,
)
row {
val numbersRange = 1 .. count
numericButtons.forEach {
if (it in numbersRange) {
dataButton(it.toString(), "$it $count")
}
}
}
row {
if (page - 1 > 2) {
dataButton("<<", "1 $count")
}
if (page - 1 > 1) {
dataButton("<", "${page - 2} $count")
}
if (page + 1 < count) {
dataButton(">", "${page + 2} $count")
}
if (page + 2 < count) {
dataButton(">>", "$count $count")
}
}
}
suspend fun activateKeyboardsBot(
token: String,
print: (Any) -> Unit
) {
val bot = telegramBot(token)
print(bot.getMe())
bot.buildBehaviourWithLongPolling(CoroutineScope(currentCoroutineContext() + SupervisorJob())) {
onCommandWithArgs("inline") { message, args ->
val numberOfPages = args.firstOrNull() ?.toIntOrNull() ?: 10
reply(
message,
"Your inline keyboard with $numberOfPages pages",
replyMarkup = inlineKeyboard {
row {
includePageButtons(1, numberOfPages)
}
}
)
}
onMessageDataCallbackQuery {
val (page, count) = it.data.parsePageAndCount() ?: it.let {
answer(it, "Unsupported data :(")
return@onMessageDataCallbackQuery
}
val text = "This is $page of $count"
edit(
it.message.withContent<TextContent>() ?: it.let {
answer(it, "Unsupported message type :(")
return@onMessageDataCallbackQuery
},
text,
replyMarkup = inlineKeyboard {
row {
includePageButtons(page, count)
}
}
)
answer(it)
}
onUnhandledCommand {
reply(
it,
buildEntities {
+"Use " + botCommand("inline") + " to get pagination inline keyboard"
},
replyMarkup = replyKeyboard(resizeKeyboard = true, oneTimeKeyboard = true) {
row {
simpleButton("/inline")
}
}
)
}
setMyCommands(BotCommand("inline", "Creates message with pagination inline keyboard"))
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) {
println(it)
}
}.join()
}

View File

@@ -0,0 +1,32 @@
import kotlinx.browser.document
import kotlinx.coroutines.*
import org.w3c.dom.*
private val scope = CoroutineScope(Dispatchers.Default)
fun main() {
document.addEventListener(
"DOMContentLoaded",
{
val botsContainer = document.getElementById("bots_container") ?: return@addEventListener
(document.getElementById("bot_token_form") as? HTMLFormElement) ?.onsubmit = {
(document.getElementById("bot_token") as? HTMLInputElement) ?.value ?.let { token ->
val botContainer = document.createElement("div") as HTMLDivElement
botsContainer.append(botContainer)
val infoDiv = document.createElement("div") as HTMLDivElement
botContainer.append(infoDiv)
scope.launch {
activateKeyboardsBot(token) {
infoDiv.innerHTML = it.toString()
}
}
}
false
}
}
)
}

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Keyboards bot</title>
</head>
<body>
<form id="bot_token_form">
<input type="text" id="bot_token">
<input type="submit" value="Start bot">
</form>
<div id="start_offer">Type your bot token to the input above to start its work</div>
<script type="text/javascript" src="KeyboardsBotLib.js"></script>
<div id="bots_container"></div>
</body>
</html>

View File

@@ -0,0 +1,21 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName="KeyboardsBotJvmKt"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation project(":KeyboardsBot:KeyboardsBotLib")
}

View File

@@ -0,0 +1,10 @@
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
suspend fun main(args: Array<String>) {
withContext(Dispatchers.IO) { // IO for inheriting of it in side of activateKeyboardsBot
activateKeyboardsBot(args.first()) {
println(it)
}
}
}

View File

@@ -1,2 +1,32 @@
# TelegramBotAPI-examples
This repository contains several examples of simple bots which are using TelegramBotAPI
## How to use this repository
This repository contains several important things:
* Example subprojects
* Commits
* Structure
### Example subproject
Each example subproject contains information about how to run this example and what is it
doing. Usually, it is some simple thing like sending "hello" message to the user which
wrote to the bot.
### Commits
Commits can contains some things like migration onto new version (especially it is actual
for major version changes), updates according to the new features in versions and
different other things which usually more important in context of history or changes
between library version
### Structure
Structure of this repository fully representative (it is the reason why this repo
contains multiplatform subprojects) and you can use it as some template (but I am strongly
recommend you to use my
[TelegramBot template](https://github.com/InsanusMokrassar/TelegramBotAPI-bot_template) or
[Multiplatform Project template](https://github.com/InsanusMokrassar/KotlinMultiplatformProjectTemplate))

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
@@ -13,12 +13,9 @@ apply plugin: 'application'
mainClassName="RandomFileSenderBotKt"
repositories {
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "com.github.insanusmokrassar:TelegramBotAPI:$telegram_bot_api_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -1,22 +1,29 @@
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.bot.getMe
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.bot.setMyCommands
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.send.media.sendDocument
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.send.sendTextMessage
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.telegramBot
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.safely
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.filterExactCommands
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.toInputFile
import com.github.insanusmokrassar.TelegramBotAPI.types.BotCommand
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import dev.inmo.micro_utils.common.filesize
import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
import dev.inmo.tgbotapi.extensions.api.send.*
import dev.inmo.tgbotapi.extensions.api.send.media.sendDocument
import dev.inmo.tgbotapi.extensions.api.send.media.sendDocumentsGroup
import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviourWithLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommandWithArgs
import dev.inmo.tgbotapi.requests.abstracts.asMultipartFile
import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.types.chat.Chat
import dev.inmo.tgbotapi.types.files.DocumentFile
import dev.inmo.tgbotapi.types.media.TelegramMediaDocument
import dev.inmo.tgbotapi.types.mediaCountInMediaGroup
import java.io.File
private const val command = "send_file"
/**
* This bot will send files inside of working directory OR from directory in the second argument
* This bot will send files inside of working directory OR from directory in the second argument.
* You may send /send_file command to this bot to get random file from the directory OR
* `/send_file $number` when you want to receive required number of files. For example,
* /send_file and `/send_file 1` will have the same effect - bot will send one random file.
* But if you will send `/send_file 5` it will choose 5 random files and send them as group
*/
suspend fun main(args: Array<String>) {
val botToken = args.first()
@@ -26,32 +33,63 @@ suspend fun main(args: Array<String>) {
if (currentRoot.isFile) {
return currentRoot
} else {
return pickFile(currentRoot.listFiles() ?.random() ?: return null)
return pickFile(currentRoot.listFiles() ?.takeIf { it.isNotEmpty() } ?.random() ?: return null)
}
}
suspend fun TelegramBot.sendFiles(chat: Chat, files: List<File>) {
when (files.size) {
1 -> sendDocument(
chat.id,
files.first().asMultipartFile(),
protectContent = true
)
else -> sendDocumentsGroup(
chat,
files.map { TelegramMediaDocument(it.asMultipartFile()) },
protectContent = true
)
}
}
val bot = telegramBot(botToken)
val scope = CoroutineScope(Dispatchers.Default)
bot.startGettingFlowsUpdatesByLongPolling(scope = scope) {
messageFlow.filterExactCommands(Regex(command)).onEach { message ->
safely {
pickFile() ?.let {
bot.sendDocument(
message.chat.id,
it.toInputFile()
)
} ?: bot.sendTextMessage(message.chat.id, "Nothing selected :(")
bot.buildBehaviourWithLongPolling (defaultExceptionsHandler = { it.printStackTrace() }) {
onCommandWithArgs(command) { message, args ->
withUploadDocumentAction(message.chat) {
val count = args.firstOrNull() ?.toIntOrNull() ?: 1
var sent = false
var left = count
val chosen = mutableListOf<File>()
while (left > 0) {
val picked = pickFile() ?.takeIf { it.filesize > 0 } ?: continue
chosen.add(picked)
left--
if (chosen.size >= mediaCountInMediaGroup.last) {
sendFiles(message.chat, chosen)
chosen.clear()
sent = true
}
}
if (chosen.isNotEmpty()) {
sendFiles(message.chat, chosen)
sent = true
}
if (!sent) {
reply(message, "Nothing selected :(")
}
}
}.launchIn(scope)
}
}
safely {
bot.setMyCommands(
setMyCommands(
BotCommand(command, "Send some random file in picker directory")
)
println(bot.getMe())
}
scope.coroutineContext[Job]!!.join()
println(getMe())
}.join()
}

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
@@ -9,15 +9,13 @@ buildscript {
}
plugins {
id "org.jetbrains.kotlin.multiplatform" version "$kotlin_version"
id "org.jetbrains.kotlin.multiplatform"
}
repositories {
jcenter()
}
kotlin {
jvm()
// js(LEGACY) {
js(IR) {
browser()
binaries.executable()
@@ -28,7 +26,7 @@ kotlin {
dependencies {
implementation kotlin('stdlib')
api "com.github.insanusmokrassar:TelegramBotAPI:$telegram_bot_api_version"
api "dev.inmo:tgbotapi:$telegram_bot_api_version"
}
}
}

View File

@@ -1,14 +1,14 @@
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.bot.getMe
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.send.media.sendMediaGroup
import com.github.insanusmokrassar.TelegramBotAPI.extensions.api.telegramBot
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.safely
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.shortcuts.*
import com.github.insanusmokrassar.TelegramBotAPI.extensions.utils.updates.retrieving.startGettingFlowsUpdatesByLongPolling
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MediaGroupContent
import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MessageContent
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.send.*
import dev.inmo.tgbotapi.extensions.api.send.media.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.CommonMessageFilterExcludeMediaGroups
import dev.inmo.tgbotapi.extensions.behaviour_builder.filters.MessageFilterByChat
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
import dev.inmo.tgbotapi.extensions.utils.shortcuts.*
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
suspend fun activateResenderBot(
token: String,
@@ -18,26 +18,39 @@ suspend fun activateResenderBot(
print(bot.getMe())
supervisorScope {
val scope = this
bot.startGettingFlowsUpdatesByLongPolling {
filterContentMessages<MessageContent>(scope).onEach {
it.content.createResends(it.chat.id, replyToMessageId = it.messageId).forEach {
bot.executeUnsafe(it) {
it.forEach(print)
} ?.also {
print(it)
}
bot.buildBehaviourWithLongPolling(CoroutineScope(currentCoroutineContext() + SupervisorJob())) {
onContentMessage(
initialFilter = CommonMessageFilterExcludeMediaGroups,
subcontextUpdatesFilter = MessageFilterByChat
) {
val chat = it.chat
withTypingAction(chat) {
executeUnsafe(it.content.createResend(chat.id, replyToMessageId = it.messageId)) {
it.forEach(print)
}
}.launchIn(scope)
mediaGroupMessages(scope).onEach {
safely({ print(it.stackTraceToString()) }) {
println(it.chat)
bot.execute(it.createResend(it.chat ?: return@safely, replyTo = it.first().messageId)).also {
print(it)
}
}
}.launchIn(scope)
}
}
}
onVisualGallery {
val chat = it.chat ?: return@onVisualGallery
withUploadPhotoAction(chat) {
send(chat, it.map { it.content.toMediaGroupMemberTelegramMedia() })
}
}
onPlaylist {
val chat = it.chat ?: return@onPlaylist
withUploadDocumentAction(chat) {
send(chat, it.map { it.content.toMediaGroupMemberTelegramMedia() })
}
}
onDocumentsGroup {
val chat = it.chat ?: return@onDocumentsGroup
withUploadDocumentAction(chat) {
send(chat, it.map { it.content.toMediaGroupMemberTelegramMedia() })
}
}
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) {
println(it)
}
}.join()
}

View File

@@ -1,6 +1,6 @@
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
@@ -13,12 +13,9 @@ apply plugin: 'application'
mainClassName="ResenderBotJvmKt"
repositories {
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation project(":ResenderBot:ResenderBotLib")
}

View File

@@ -0,0 +1,9 @@
# SlotMachineDetectorBot
This bot must reply with information about slot machine answer
## Launch
```bash
../gradlew run --args="BOT_TOKEN"
```

View File

@@ -0,0 +1,21 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName="SlotMachineDetectorBotKt"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
}

View File

@@ -0,0 +1,26 @@
import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviourWithLongPolling
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onDice
import dev.inmo.tgbotapi.extensions.utils.*
import dev.inmo.tgbotapi.types.dice.SlotMachineDiceAnimationType
import kotlinx.coroutines.*
suspend fun main(args: Array<String>) {
val bot = telegramBot(args.first())
bot.buildBehaviourWithLongPolling(scope = CoroutineScope(Dispatchers.IO)) {
onDice {
val content = it.content
val dice = content.dice
val diceType = dice.animationType
if (diceType == SlotMachineDiceAnimationType) {
val result = dice.calculateSlotMachineResult() ?: return@onDice
reply(it, "${result.leftReel}|${result.centerReel}|${result.rightReel}")
} else {
reply(it, "There is no slot machine dice in message")
}
}
}.join()
}

View File

@@ -0,0 +1,33 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id "org.jetbrains.kotlin.multiplatform"
}
kotlin {
jvm()
// js(LEGACY) {
js(IR) {
browser()
binaries.executable()
}
sourceSets {
commonMain {
dependencies {
implementation kotlin('stdlib')
api "dev.inmo:tgbotapi:$telegram_bot_api_version"
}
}
}
}

View File

@@ -0,0 +1,71 @@
import dev.inmo.micro_utils.coroutines.defaultSafelyWithoutExceptionHandler
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.get.getCustomEmojiStickerOrNull
import dev.inmo.tgbotapi.extensions.api.get.getStickerSet
import dev.inmo.tgbotapi.extensions.api.send.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
import dev.inmo.tgbotapi.extensions.utils.formatting.*
import dev.inmo.tgbotapi.types.StickerType
import dev.inmo.tgbotapi.types.message.textsources.*
import dev.inmo.tgbotapi.types.stickers.StickerSet
import kotlinx.coroutines.*
fun StickerSet.buildInfo() = buildEntities {
bold("StickerSet name: ") + "${name}\n"
bold("StickerSet title: ") + "${title}\n"
bold(
when (stickerType) {
StickerType.CustomEmoji -> "Custom emoji"
StickerType.Mask -> "Mask"
StickerType.Regular -> "Regular"
is StickerType.Unknown -> "Unknown type \"${stickerType.type}\""
}
) + " sticker set with title " + bold(title) + " and name " + bold(name)
}
suspend fun activateStickerInfoBot(
token: String,
print: (Any) -> Unit
) {
val bot = telegramBot(token)
print(bot.getMe())
defaultSafelyWithoutExceptionHandler = {
it.printStackTrace()
}
bot.buildBehaviourWithLongPolling(CoroutineScope(currentCoroutineContext() + SupervisorJob())) {
onText {
withTypingAction(it.chat) {
it.content.textSources.mapNotNull {
if (it is CustomEmojiTextSource) {
getCustomEmojiStickerOrNull(it.customEmojiId) ?.stickerSetName
} else {
null
}
}.distinct().map {
getStickerSet(it)
}.distinct().flatMap {
it.buildInfo() + regular("\n")
}.separateForText().map { entities ->
reply(it, entities)
}
}
}
onSticker {
val stickerSetInfo = getStickerSet(it.content.media)
reply(
it,
stickerSetInfo.buildInfo()
)
}
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) {
println(it)
}
}.join()
}

View File

@@ -0,0 +1,32 @@
import kotlinx.browser.document
import kotlinx.coroutines.*
import org.w3c.dom.*
private val scope = CoroutineScope(Dispatchers.Default)
fun main() {
document.addEventListener(
"DOMContentLoaded",
{
val botsContainer = document.getElementById("bots_container") ?: return@addEventListener
(document.getElementById("bot_token_form") as? HTMLFormElement) ?.onsubmit = {
(document.getElementById("bot_token") as? HTMLInputElement) ?.value ?.let { token ->
val botContainer = document.createElement("div") as HTMLDivElement
botsContainer.append(botContainer)
val infoDiv = document.createElement("div") as HTMLDivElement
botContainer.append(infoDiv)
scope.launch {
activateStickerInfoBot(token) {
infoDiv.innerHTML = it.toString()
}
}
}
false
}
}
)
}

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Resender bot</title>
</head>
<body>
<form id="bot_token_form">
<input type="text" id="bot_token">
<input type="submit" value="Start bot">
</form>
<div id="start_offer">Type your bot token to the input above to start its work</div>
<script type="text/javascript" src="StickerInfoBotLib.js"></script>
<div id="bots_container"></div>
</body>
</html>

View File

@@ -0,0 +1,21 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName="StickerInfoBotJvmKt"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation project(":StickerInfoBot:StickerInfoBotLib")
}

View File

@@ -0,0 +1,5 @@
suspend fun main(args: Array<String>) {
activateStickerInfoBot(args.first()) {
println(it)
}
}

17
WebApp/README.md Normal file
View File

@@ -0,0 +1,17 @@
# WebApp
Here you may find simple example of `WebApp`. For work of this example you will need one of two things:
* Your own domain with SSL (letsencrypt is okay)
* Test account in telegram
What is there in this module:
* JVM part of this example is a server with simple static webapp sharing and bot which just gives the webapp button to open webapp
* JS part is the WebApp with one button and reacting to chaged user theme and app viewport
## How to run
```kotlin
./gradlew run --args="TOKEN WEB_APP_ADDRESS"
```

57
WebApp/build.gradle Normal file
View File

@@ -0,0 +1,57 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "org.jetbrains.kotlin.plugin.serialization"
}
apply plugin: 'application'
kotlin {
jvm()
js(IR) {
browser()
binaries.executable()
}
sourceSets {
commonMain {
dependencies {
implementation kotlin('stdlib')
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$serialization_version"
}
}
jsMain {
dependencies {
implementation "dev.inmo:tgbotapi.webapps:$telegram_bot_api_version"
}
}
jvmMain {
dependencies {
implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
implementation "dev.inmo:micro_utils.ktor.server:$micro_utils_version"
implementation "io.ktor:ktor-server-cio:$ktor_version"
}
}
}
}
application {
mainClassName = "WebAppServerKt"
}
tasks.getByName("compileKotlinJvm")
.dependsOn(jsBrowserDistribution)
tasks.getByName("compileKotlinJvm").configure {
mustRunAfter jsBrowserDistribution
}

View File

@@ -0,0 +1,7 @@
import kotlinx.serialization.Serializable
@Serializable
data class WebAppDataWrapper(
val data: String,
val hash: String
)

View File

@@ -0,0 +1,180 @@
import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions
import dev.inmo.tgbotapi.types.webAppQueryIdField
import dev.inmo.tgbotapi.webapps.*
import dev.inmo.tgbotapi.webapps.haptic.HapticFeedbackStyle
import dev.inmo.tgbotapi.webapps.haptic.HapticFeedbackType
import dev.inmo.tgbotapi.webapps.popup.*
import io.ktor.client.HttpClient
import io.ktor.client.request.*
import io.ktor.client.statement.bodyAsText
import io.ktor.http.*
import io.ktor.http.content.TextContent
import kotlinx.browser.document
import kotlinx.browser.window
import kotlinx.coroutines.*
import kotlinx.dom.appendElement
import kotlinx.dom.appendText
import kotlinx.serialization.json.Json
import org.w3c.dom.HTMLElement
fun HTMLElement.log(text: String) {
appendText(text)
appendElement("p", {})
}
fun main() {
console.log("Web app started")
val client = HttpClient()
val baseUrl = window.location.origin.removeSuffix("/")
window.onload = {
val scope = CoroutineScope(Dispatchers.Default)
runCatching {
scope.launchSafelyWithoutExceptions {
val response = client.post("$baseUrl/check") {
setBody(
Json { }.encodeToString(
WebAppDataWrapper.serializer(),
WebAppDataWrapper(webApp.initData, webApp.initDataUnsafe.hash)
)
)
}
val dataIsSafe = response.bodyAsText().toBoolean()
document.body ?.log(
if (dataIsSafe) {
"Data is safe"
} else {
"Data is unsafe"
}
)
document.body ?.log(
webApp.initDataUnsafe.chat.toString()
)
}
document.body ?.appendElement("button") {
addEventListener("click", {
scope.launchSafelyWithoutExceptions {
handleResult({ "Clicked" }) {
client.post("${window.location.origin.removeSuffix("/")}/inline") {
parameter(webAppQueryIdField, it)
setBody(TextContent("Clicked", ContentType.Text.Plain))
document.body ?.log(url.build().toString())
}.coroutineContext.job.join()
}
}
})
appendText("Example button")
} ?: window.alert("Unable to load body")
document.body ?.appendElement("p", {})
document.body ?.appendText("Alerts:")
document.body ?.appendElement("button") {
addEventListener("click", {
webApp.showPopup(
PopupParams(
"It is sample title of default button",
"It is sample message of default button",
DefaultPopupButton("default", "Default button"),
OkPopupButton("ok"),
DestructivePopupButton("destructive", "Destructive button")
)
) {
document.body ?.log(
when (it) {
"default" -> "You have clicked default button in popup"
"ok" -> "You have clicked ok button in popup"
"destructive" -> "You have clicked destructive button in popup"
else -> "I can't imagine where you take button with id $it"
}
)
}
})
appendText("Popup")
} ?: window.alert("Unable to load body")
document.body ?.appendElement("button") {
addEventListener("click", {
webApp.showAlert(
"This is alert message"
) {
document.body ?.log(
"You have closed alert"
)
}
})
appendText("Alert")
} ?: window.alert("Unable to load body")
document.body ?.appendElement("button") {
addEventListener("click", {
webApp.showConfirm(
"This is confirm message"
) {
document.body ?.log(
"You have pressed \"${if (it) "Ok" else "Cancel"}\" in confirm"
)
}
})
appendText("Confirm")
} ?: window.alert("Unable to load body")
document.body ?.appendElement("p", {})
document.body ?.appendElement("button") {
fun updateText() {
textContent = if (webApp.isClosingConfirmationEnabled) {
"Disable closing confirmation"
} else {
"Enable closing confirmation"
}
}
addEventListener("click", {
webApp.toggleClosingConfirmation()
updateText()
})
updateText()
} ?: window.alert("Unable to load body")
document.body ?.appendElement("p", {})
webApp.apply {
onThemeChanged {
document.body ?.log("Theme changed: ${webApp.themeParams}")
}
onViewportChanged {
document.body ?.log("Viewport changed: ${it.isStateStable}")
}
backButton.apply {
onClick {
document.body ?.log("Back button clicked")
hapticFeedback.impactOccurred(
HapticFeedbackStyle.Heavy
)
}
show()
}
mainButton.apply {
setText("Main button")
onClick {
document.body ?.log("Main button clicked")
hapticFeedback.notificationOccurred(
HapticFeedbackType.Success
)
}
show()
}
onSettingsButtonClicked {
document.body ?.log("Settings button clicked")
}
}
webApp.ready()
}.onFailure {
window.alert(it.stackTraceToString())
}
}
}

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="format-detection" content="telephone=no"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="HandheldFriendly" content="True"/>
<meta name="robots" content="noindex,nofollow"/>
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<title>Web App Example</title>
</head>
<body>
<script type="application/javascript" src="https://telegram.org/js/telegram-web-app.js"></script>
<script type="application/javascript" src="WebApp.js"></script>
</body>
</html>

View File

@@ -0,0 +1,122 @@
import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
import dev.inmo.micro_utils.ktor.server.createKtorServer
import dev.inmo.tgbotapi.extensions.api.answers.answer
import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
import dev.inmo.tgbotapi.extensions.api.send.*
import dev.inmo.tgbotapi.extensions.api.telegramBot
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.*
import dev.inmo.tgbotapi.extensions.utils.formatting.botCommand
import dev.inmo.tgbotapi.extensions.utils.formatting.buildEntities
import dev.inmo.tgbotapi.extensions.utils.types.buttons.*
import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.types.InlineQueries.InlineQueryResult.InlineQueryResultArticle
import dev.inmo.tgbotapi.types.InlineQueries.InputMessageContent.InputTextMessageContent
import dev.inmo.tgbotapi.types.webAppQueryIdField
import dev.inmo.tgbotapi.types.webapps.WebAppInfo
import dev.inmo.tgbotapi.utils.PreviewFeature
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import io.ktor.http.*
import io.ktor.server.application.call
import io.ktor.server.http.content.*
import io.ktor.server.request.receiveText
import io.ktor.server.response.respond
import io.ktor.server.routing.post
import io.ktor.server.routing.routing
import kotlinx.coroutines.Dispatchers
import kotlinx.serialization.json.Json
import java.io.File
import java.nio.charset.Charset
/**
* Accepts two parameters:
*
* * Telegram Token
* * URL where will be placed
*
* Will start the server to share the static (index.html and WebApp.js) on 0.0.0.0:8080
*/
@OptIn(PreviewFeature::class)
suspend fun main(vararg args: String) {
val telegramBotAPIUrlsKeeper = TelegramAPIUrlsKeeper(
args.first(),
testServer = args.any { it == "testServer" }
)
val bot = telegramBot(telegramBotAPIUrlsKeeper)
createKtorServer(
"0.0.0.0",
8080,
additionalEngineEnvironmentConfigurator = {
parentCoroutineContext += Dispatchers.IO
}
) {
routing {
static {
files(File("WebApp/build/distributions"))
default("WebApp/build/distributions/index.html")
}
post("inline") {
val requestBody = call.receiveText()
val queryId = call.parameters[webAppQueryIdField] ?: error("$webAppQueryIdField should be presented")
bot.answer(queryId, InlineQueryResultArticle(queryId, "Result", InputTextMessageContent(requestBody)))
call.respond(HttpStatusCode.OK)
}
post("check") {
val requestBody = call.receiveText()
val webAppCheckData = Json { }.decodeFromString(WebAppDataWrapper.serializer(), requestBody)
val isSafe = telegramBotAPIUrlsKeeper.checkWebAppData(webAppCheckData.data, webAppCheckData.hash)
call.respond(HttpStatusCode.OK, isSafe.toString())
}
}
}.start(false)
bot.buildBehaviourWithLongPolling(
defaultExceptionsHandler = { it.printStackTrace() }
) {
onCommand("reply_markup") {
reply(
it,
"Button",
replyMarkup = replyKeyboard(resizeKeyboard = true, oneTimeKeyboard = true) {
row {
webAppButton("Open WebApp", WebAppInfo(args[1]))
}
}
)
}
onCommand("inline") {
reply(
it,
"Button",
replyMarkup = inlineKeyboard {
row {
webAppButton("Open WebApp", WebAppInfo(args[1]))
}
}
)
}
onUnhandledCommand {
reply(
it,
buildEntities {
+"Use " + botCommand("inline") + " to get inline web app button\n"
+"Use " + botCommand("reply_markup") + " to get reply markup web app button\n"
}
)
}
setMyCommands(
BotCommand("reply_markup", "Use to get reply markup keyboard with web app trigger"),
BotCommand("inline", "Use to get inline keyboard with web app trigger"),
)
allUpdatesFlow.subscribeSafelyWithoutExceptions(this) {
println(it)
}
println(getMe())
}.join()
}

View File

@@ -1,5 +1,26 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
}
}
allprojects {
repositories {
mavenLocal()
mavenCentral()
if (project.hasProperty("GITHUB_USER") && project.hasProperty("GITHUB_TOKEN")) {
maven {
url "https://maven.pkg.github.com/InsanusMokrassar/TelegramBotAPI"
credentials {
username = project.getProperty("GITHUB_USER")
password = project.getProperty("GITHUB_TOKEN")
}
}
}
}
}
}

View File

@@ -1,5 +1,11 @@
kotlin.code.style=official
org.gradle.parallel=true
# Due to parallel compilation project require next amount of memory on full build
org.gradle.jvmargs=-Xmx768m
kotlin_version=1.4.10
telegram_bot_api_version=0.28.5
kotlin_version=1.7.10
telegram_bot_api_version=3.1.1
micro_utils_version=0.12.1
serialization_version=1.4.0-RC
ktor_version=2.1.0

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-6.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip

View File

@@ -1,7 +1,24 @@
include ":ForwarderBot"
include ":ForwardInfoSenderBot"
include ":RandomFileSenderBot"
include ":HelloBot"
include ":GetMeBot"
include ":FilesLoaderBot"
include ":ResenderBot:ResenderBotLib"
include ":ResenderBot:jvm_launcher"
include ":KeyboardsBot:KeyboardsBotLib"
include ":KeyboardsBot:jvm_launcher"
include ":StickerInfoBot:StickerInfoBotLib"
include ":StickerInfoBot:jvm_launcher"
include ":SlotMachineDetectorBot"
include ":WebApp"
include ":FSMBot"