Compare commits

...

319 Commits

Author SHA1 Message Date
8bd80c1c0c
Merge pull request #97 from InsanusMokrassar/8.3.0
8.3.0
2024-04-23 18:50:57 +06:00
2234ffd55d update gradle wrapper 2024-04-23 18:44:51 +06:00
1a9d8b0d5e update dependencies 2024-04-23 18:44:26 +06:00
e00f40d06a start 8.3.0 2024-04-23 18:37:33 +06:00
9883d2b3b1
Merge pull request #96 from InsanusMokrassar/8.2.0
8.2.0
2024-02-18 21:34:04 +06:00
bdfd3b816c update dependencies 2024-02-18 21:31:45 +06:00
dd37ae0f2f start 8.2.0 2024-02-18 21:27:22 +06:00
8efe977e76
Merge pull request #95 from InsanusMokrassar/8.1.1
8.1.1
2024-02-10 23:45:26 +06:00
8290a68654 update dependencies 2024-02-10 23:44:52 +06:00
493a18a0f7 start 8.1.1 2024-02-10 23:41:36 +06:00
36608937af
Merge pull request #94 from InsanusMokrassar/8.1.0
8.1.0
2024-01-14 18:42:36 +06:00
1b1b069d93 integrate startup launcher 2024-01-14 18:33:41 +06:00
37b5b8e867 start 8.1.0 2024-01-14 18:21:26 +06:00
468310c819
Merge pull request #93 from InsanusMokrassar/8.0.0
8.0.0
2024-01-12 20:28:24 +06:00
0d27a4f6f7 update dependencies 2024-01-12 20:12:58 +06:00
f9d131866f start 8.0.0 2024-01-12 20:11:29 +06:00
451b2bbc39
Merge pull request #92 from InsanusMokrassar/7.4.2
7.4.2
2023-12-24 23:25:42 +06:00
d51e2d8e7c fix of #90 and #91 2023-12-24 23:24:04 +06:00
6c45a8c848 update dependencies 2023-12-24 23:17:29 +06:00
8a7e05580d start 7.4.2 2023-12-24 23:14:24 +06:00
8b78f2901f
Merge pull request #89 from InsanusMokrassar/7.4.1
7.4.1
2023-12-10 14:47:39 +06:00
cad8743ced update dependencies and fill changelog 2023-12-10 14:46:13 +06:00
8f827e9f79 start 7.4.1 2023-12-10 14:34:52 +06:00
28039df992
Merge pull request #88 from InsanusMokrassar/7.4.0
7.4.0
2023-11-26 20:56:04 +06:00
18019c37ea remove expicit KSLog dependency 2023-11-26 19:29:29 +06:00
8a84f65a12
Update CHANGELOG.md 2023-11-26 19:02:00 +06:00
49f30ab939
Update libs.versions.toml 2023-11-26 18:52:26 +06:00
8a15deceb8
Update gradle.properties 2023-11-26 18:49:43 +06:00
ea3273c4cf
Merge pull request #87 from InsanusMokrassar/7.3.0
7.3.0
2023-11-06 15:17:37 +06:00
439972e783 update dependencies 2023-11-05 20:52:30 +06:00
08907291c5 update dependencies 2023-11-05 19:34:43 +06:00
0f4819a83d start 7.3.0 2023-11-05 19:14:12 +06:00
7abdf18491
Merge pull request #86 from InsanusMokrassar/7.2.3
7.2.3
2023-10-11 15:31:46 +06:00
98a91ea357 update dependencies 2023-10-11 15:29:44 +06:00
934f603a8a 7.2.3 2023-10-11 15:23:23 +06:00
76e9cdae8d
Merge pull request #85 from InsanusMokrassar/7.2.2
7.2.2
2023-10-01 15:59:58 +06:00
fbe166f2b4 get back koin dependency 2023-10-01 15:55:33 +06:00
30cf190461 conflicts resolvers customization 2023-10-01 15:28:00 +06:00
9d72d79321 start 7.2.2 2023-09-30 17:43:46 +06:00
33057dd2cb
Merge pull request #84 from InsanusMokrassar/7.2.1
7.2.1
2023-09-29 22:58:51 +06:00
e1bb8e9799 update dependencies 2023-09-29 22:48:57 +06:00
fd5e979f11 start 7.2.1 2023-09-29 22:42:45 +06:00
20e1f042f1
Merge pull request #83 from InsanusMokrassar/7.2.0
7.2.0
2023-09-26 01:01:08 +06:00
0e65a425c3
Update CHANGELOG.md 2023-09-26 00:57:08 +06:00
517ab1e1a4
Update libs.versions.toml 2023-09-26 00:56:20 +06:00
977cf32669 update dependencies 2023-09-26 00:21:31 +06:00
5bd1916fb5 start 7.2.0 2023-09-26 00:11:41 +06:00
8c22b418f8
Merge pull request #82 from InsanusMokrassar/7.1.0
7.1.0
2023-08-20 14:41:16 +06:00
3663f987bc update dependencies 2023-08-20 14:38:05 +06:00
93d15af80d start 7.1.0 2023-08-20 14:35:29 +06:00
27c5f379a4
Merge pull request #81 from InsanusMokrassar/7.0.0
7.0.0
2023-07-01 16:20:14 +06:00
ae7a7b84ac fill changelog 2023-07-01 16:01:25 +06:00
5b98aef237 update dependencies 2023-07-01 15:52:08 +06:00
3755972394 start 7.0.0 2023-07-01 15:50:20 +06:00
5d5312c66f
Merge pull request #80 from InsanusMokrassar/6.1.0
6.1.0
2023-06-19 23:27:16 +06:00
f79fef3dae update dependencies 2023-06-19 22:53:17 +06:00
2c8dc80eae start 6.1.0 2023-06-19 22:28:52 +06:00
a2a2fe7ef4
Merge pull request #79 from InsanusMokrassar/6.0.1
6.0.1
2023-06-03 21:36:06 +06:00
34cadab809
Update CHANGELOG.md 2023-06-03 01:06:41 +06:00
784e041519
Update libs.versions.toml 2023-06-03 01:01:57 +06:00
4784f05c8e
Update gradle.properties 2023-06-03 01:00:18 +06:00
e89b0a6ba2
Merge pull request #78 from InsanusMokrassar/6.0.0
6.0.0
2023-05-31 07:11:04 +06:00
b48d278446
Update CHANGELOG.md 2023-05-31 07:09:31 +06:00
072a64362d
Update libs.versions.toml 2023-05-31 07:09:05 +06:00
7715f519e3 update dependencies 2023-05-28 20:54:39 +06:00
7982f27217 start 6.0.0 2023-05-28 20:53:32 +06:00
eeb3ae1dbe
Merge pull request #77 from InsanusMokrassar/5.1.3
5.1.3
2023-05-20 12:43:54 +06:00
8a73fda6fa
Update libs.versions.toml 2023-05-20 01:35:52 +06:00
05e94249af
Update CHANGELOG.md 2023-05-20 01:35:36 +06:00
74c36c66f1
Update libs.versions.toml 2023-05-20 01:34:26 +06:00
5153f732ce
start 5.1.3 2023-05-20 01:33:49 +06:00
fb23e9be79
Merge pull request #76 from InsanusMokrassar/5.1.2
5.1.2
2023-05-06 13:53:17 +06:00
292640b465 update dependencies 2023-05-06 13:32:05 +06:00
a863d91bab start 5.1.2 2023-05-06 13:31:15 +06:00
d1064bb9cd
Merge pull request #75 from InsanusMokrassar/5.1.1
5.1.1
2023-05-02 10:13:37 +06:00
a9c3b937e7
Update CHANGELOG.md 2023-05-02 10:12:52 +06:00
6757354652
Update libs.versions.toml 2023-05-02 01:52:23 +06:00
c65efb6ffb
Update gradle.properties 2023-05-02 01:51:11 +06:00
f9cc279854
Merge pull request #74 from InsanusMokrassar/5.1.0
5.1.0
2023-04-22 21:29:28 +06:00
b2d00cb5ae
Update CHANGELOG.md 2023-04-22 21:24:18 +06:00
782721751a
Update libs.versions.toml 2023-04-22 21:12:16 +06:00
01086766ba
Update gradle.properties 2023-04-22 21:10:47 +06:00
bf0a6ab659
Merge pull request #73 from InsanusMokrassar/5.0.2
5.0.2
2023-04-20 00:20:43 +06:00
a3e6f8a6b5 update dependencies 2023-04-20 00:18:24 +06:00
cd9ba5dc19 start 5.0.2 2023-04-20 00:15:37 +06:00
8e0d35a80d
Merge pull request #72 from InsanusMokrassar/5.0.1
5.0.1
2023-03-16 20:29:57 +06:00
a49fb60555
Update CHANGELOG.md 2023-03-16 19:56:01 +06:00
ec26179d2a
Update libs.versions.toml 2023-03-16 19:55:28 +06:00
daed26cba6
Update gradle.properties 2023-03-16 19:54:56 +06:00
7c820b70ac
Merge pull request #71 from InsanusMokrassar/5.0.0
5.0.0
2023-03-12 00:07:27 +06:00
edb15f11db
Update CHANGELOG.md 2023-03-12 00:06:55 +06:00
18000429b0
Update libs.versions.toml 2023-03-11 23:58:27 +06:00
d975e61966
start 2023-03-11 23:56:26 +06:00
663e00cad6
Merge pull request #70 from InsanusMokrassar/4.1.0
4.1.0
2023-03-08 22:27:47 +06:00
6725193545
Update CHANGELOG.md 2023-03-08 22:26:50 +06:00
ccfd91b1ac
Update libs.versions.toml 2023-03-08 17:17:36 +06:00
c8b69d641f
start 4.1.0 2023-03-08 17:16:31 +06:00
7af11fc427
Merge pull request #69 from InsanusMokrassar/4.0.3
4.0.3
2023-03-02 23:48:27 +06:00
59b91fc1ff
Update CHANGELOG.md 2023-03-02 22:03:01 +06:00
4293096ed2
Update libs.versions.toml 2023-03-02 22:02:22 +06:00
42dd98426c
start 4.0.3 2023-03-02 22:01:45 +06:00
744520c73f
Merge pull request #68 from InsanusMokrassar/4.0.2
4.0.2
2023-03-01 15:45:17 +06:00
1b8ae09866
Update CHANGELOG.md 2023-03-01 15:36:55 +06:00
3027e39665
Update libs.versions.toml 2023-03-01 15:35:32 +06:00
b77fe446f8
start 4.0.2 2023-03-01 15:34:46 +06:00
bc11d7508f
Merge pull request #67 from InsanusMokrassar/4.0.1
4.0.1
2023-02-28 21:08:39 +06:00
cd9af3c216
Update CHANGELOG.md 2023-02-28 20:05:35 +06:00
c60face0e6
Update libs.versions.toml 2023-02-28 20:01:47 +06:00
334ca1a184
start 4.0.1 2023-02-28 20:00:54 +06:00
b7bb6f10a9
Merge pull request #66 from InsanusMokrassar/4.0.0
4.0.0
2023-02-28 13:56:58 +06:00
7b14343cc5 update gradle wrapper 2023-02-28 11:41:29 +06:00
62c1f87e95
Update libs.versions.toml 2023-02-27 23:49:19 +06:00
317f15bbb8
start 4.0.0 2023-02-27 23:47:53 +06:00
34c0c05715
Merge pull request #65 from InsanusMokrassar/3.5.0
3.5.0
2023-02-17 15:58:32 +06:00
d23bde75b5 update dependencies 2023-02-17 14:08:36 +06:00
46e48efe52 start 3.5.0 2023-02-17 14:07:28 +06:00
1bf59c20d4
Merge pull request #64 from InsanusMokrassar/3.4.1
3.4.1
2023-02-12 01:35:21 +06:00
3592a5907c setupBotPlugin now works synchronously 2023-02-12 01:29:45 +06:00
328a8b215c start 3.4.1 2023-02-12 01:28:35 +06:00
57ba6411e4
Merge pull request #63 from InsanusMokrassar/3.4.0
3.4.0
2023-02-06 15:27:10 +06:00
4d53d2dc63 update dependencies 2023-02-06 14:12:23 +06:00
2671794f22 start 3.4.0 2023-02-06 14:10:34 +06:00
9eff09ca68
Merge pull request #62 from InsanusMokrassar/3.3.1
3.3.1
2023-01-19 00:23:12 +06:00
7f1d972105
Update CHANGELOG.md 2023-01-19 00:22:25 +06:00
d05413a54e
Update libs.versions.toml 2023-01-19 00:15:29 +06:00
2342bd9a38
Update gradle.properties 2023-01-19 00:02:22 +06:00
c9a6df5614
Merge pull request #61 from InsanusMokrassar/3.3.0
3.3.0
2023-01-01 02:28:52 +06:00
295f1ce7ab
Update CHANGELOG.md 2023-01-01 02:27:56 +06:00
4ca97546b5
Update libs.versions.toml 2023-01-01 02:26:42 +06:00
166dc4b729
Update gradle.properties 2023-01-01 02:25:30 +06:00
f09929648e
Merge pull request #60 from InsanusMokrassar/3.2.3
3.2.3
2022-12-28 12:41:51 +06:00
7d906e0c9c
Update CHANGELOG.md 2022-12-28 09:27:55 +06:00
dc32a4eb7f
Update libs.versions.toml 2022-12-28 09:27:38 +06:00
5b5f95e0ec
start 3.2.3 2022-12-28 09:27:04 +06:00
a0fd9012d2
Merge pull request #59 from InsanusMokrassar/3.2.2
3.2.2
2022-12-20 09:19:12 +06:00
14910ed568
Update CHANGELOG.md 2022-12-20 09:18:51 +06:00
ccc936f821
Update libs.versions.toml 2022-12-20 09:15:56 +06:00
877e693eb3
start 3.2.2 2022-12-20 09:13:35 +06:00
9f3634f2ec
Merge pull request #58 from InsanusMokrassar/3.2.1
3.2.1
2022-12-08 11:05:38 +06:00
08d905805a
Update CHANGELOG.md 2022-12-08 10:47:08 +06:00
92cf2167cd
Update libs.versions.toml 2022-12-08 10:46:17 +06:00
3d6a208aa8
Update gradle.properties 2022-12-08 10:45:10 +06:00
6e61f364da
Merge pull request #57 from InsanusMokrassar/3.2.0
3.2.0
2022-12-05 16:31:11 +06:00
399fcb8466 update dependencies 2022-12-05 15:45:55 +06:00
477d83e31b start 3.2.0 2022-12-05 15:31:19 +06:00
e761f84023
Merge pull request #56 from InsanusMokrassar/3.1.4
3.1.4
2022-11-28 18:12:36 +06:00
caca21fac9
Update CHANGELOG.md 2022-11-28 16:30:45 +06:00
4f2934fbae
Update libs.versions.toml 2022-11-28 16:29:59 +06:00
8c3c52c92b
Update gradle.properties 2022-11-28 16:29:11 +06:00
779b56394a
Merge pull request #55 from InsanusMokrassar/3.1.3
3.1.3
2022-11-17 13:17:49 +06:00
3b11cdc2c6 update tgbotapi 2022-11-17 13:01:08 +06:00
1a823cda6f add own repo 2022-11-17 13:00:19 +06:00
6a29264caf start 3.1.3 2022-11-17 12:59:39 +06:00
4d32de8c2f add gitea publication 2022-11-17 11:29:02 +06:00
f7cce657a8
Merge pull request #54 from InsanusMokrassar/3.1.2
3.1.2
2022-11-15 17:31:44 +06:00
a4ca827a5c
Update CHANGELOG.md 2022-11-15 11:28:43 +06:00
224107e35e
Update libs.versions.toml 2022-11-15 09:58:30 +06:00
9efebd027d
Update gradle.properties 2022-11-15 09:57:22 +06:00
841156e8b5
Merge pull request #53 from InsanusMokrassar/3.1.1
3.1.1
2022-11-15 02:16:21 +06:00
ab4d06a44c
Update CHANGELOG.md 2022-11-15 02:15:06 +06:00
0766bf7d76
Update libs.versions.toml 2022-11-15 00:17:22 +06:00
f7c7e338e2
Update gradle.properties 2022-11-15 00:15:56 +06:00
6a4fed07ee
Merge pull request #52 from InsanusMokrassar/3.1.0
3.1.0
2022-11-10 20:57:02 +06:00
88f5fbfd18
Update HelloPlugin.kt 2022-11-10 20:54:34 +06:00
f644817c04
Update HelloPlugin.kt 2022-11-10 20:53:12 +06:00
8a8eb3c3b7
Update CHANGELOG.md 2022-11-10 20:28:26 +06:00
8cb68495c9
Update libs.versions.toml 2022-11-10 20:26:28 +06:00
6f2c922edf
start 3.1.0 2022-11-10 20:23:23 +06:00
5895335031
Merge pull request #51 from InsanusMokrassar/3.0.0
3.0.0
2022-11-09 01:14:24 +06:00
5f25250bcc
Update CHANGELOG.md 2022-11-09 01:12:55 +06:00
f0d2a6d39d
Update libs.versions.toml 2022-11-09 00:47:23 +06:00
3e4dc1fdb0
Update gradle.properties 2022-11-09 00:45:08 +06:00
55012eacec
Merge pull request #50 from InsanusMokrassar/2.4.1
2.4.1
2022-11-03 12:41:13 +06:00
c64314fa11 update changelog 2022-11-03 12:24:42 +06:00
f0b7ae7325 update dependencies 2022-11-03 12:17:05 +06:00
4ade949593 start 2.4.1 2022-11-03 12:14:58 +06:00
2a9342e4c7
Merge pull request #49 from InsanusMokrassar/2.4.0
2.4.0
2022-10-22 22:04:32 +06:00
7d57ceafaa update dependencies 2022-10-22 21:58:33 +06:00
823a53d5aa start 2.4.0 2022-10-22 21:53:19 +06:00
c1889ceff0
Merge pull request #48 from InsanusMokrassar/2.3.4
2.3.4
2022-10-02 01:27:59 +06:00
40c4ae128f update dependencies 2022-10-01 03:00:29 +06:00
0f59009300 start 2.3.4 2022-10-01 00:32:21 +06:00
a273f1117f
Merge pull request #47 from InsanusMokrassar/2.3.3
2.3.3
2022-09-19 20:44:51 +06:00
c8bb5e1195
Update CHANGELOG.md 2022-09-19 16:08:11 +06:00
fbd98d67a9
Update libs.versions.toml 2022-09-19 16:06:00 +06:00
2350555fbb
start 2.3.3 2022-09-19 16:04:44 +06:00
4130f98caa
Merge pull request #46 from InsanusMokrassar/2.3.2
2.3.2
2022-09-15 20:12:43 +06:00
f8161c34a7 update dependencies 2022-09-15 20:07:23 +06:00
6fe333e437 start 2.3.2 2022-09-15 20:05:31 +06:00
5806fa1c31
Merge pull request #45 from InsanusMokrassar/2.3.1
2.3.1
2022-09-09 13:44:37 +06:00
2ff712327f
Update CHANGELOG.md 2022-09-09 04:22:56 +06:00
72e8e35e3f
Update libs.versions.toml 2022-09-09 04:20:09 +06:00
030f9546f2
Update gradle.properties 2022-09-09 04:18:05 +06:00
1b3c479766
Merge pull request #44 from InsanusMokrassar/2.3.0
2.3.0
2022-09-04 16:10:09 +06:00
dcfb66ef6c fixes 2022-09-04 15:57:40 +06:00
763718716d improve reconnect feature 2022-09-04 15:07:30 +06:00
dfbc7be6f2 add option waitForConnection in database config 2022-09-04 14:37:44 +06:00
ab0578b312 start 2.3.0 2022-09-04 14:31:46 +06:00
7b502e073d
Merge pull request #43 from InsanusMokrassar/2.2.0
2.2.0
2022-08-27 13:47:59 +06:00
137a6c1c26 update dependencies 2022-08-27 13:45:26 +06:00
74f1ad496e start 2.2.0 2022-08-27 13:43:51 +06:00
e4a1e1f0be
Merge pull request #42 from InsanusMokrassar/2.1.1
2.1.1
2022-08-20 22:30:51 +06:00
7286cf401b make it possible to get bot from DI 2022-08-20 22:10:08 +06:00
cdf94ec2eb start 2.1.1 2022-08-20 22:08:13 +06:00
5bfabfa284
Merge pull request #41 from InsanusMokrassar/2.1.0
2.1.0
2022-08-18 12:43:39 +06:00
ec2852beb0 complete with including of FSM 2022-08-18 12:42:34 +06:00
6c2cfbf06f a little upgrade of hello plugin 2022-08-18 12:27:11 +06:00
caa028b799
Update CHANGELOG.md 2022-08-17 09:55:54 +06:00
53667fa8b8
Update libs.versions.toml 2022-08-16 00:50:12 +06:00
81ca68dc06
Update CHANGELOG.md 2022-08-14 00:10:45 +06:00
6f74e6b4cb fill readme + rename fallback state handler 2022-08-13 20:37:17 +06:00
7dad3581f1 fixes/fill of docs 2022-08-13 20:30:10 +06:00
751e9aa66c remove redundant modules 2022-08-13 20:09:21 +06:00
08b797bbc2 start integration FSM oriented plagubot version 2022-08-13 18:30:33 +06:00
fa00d11a39 update gradle wrapper 2022-08-13 18:09:38 +06:00
1ba3953dfa update dependencies 2022-08-13 18:09:19 +06:00
af86a64a48 start 2.1.0 2022-08-13 18:08:00 +06:00
60fe1b5df9
Update CHANGELOG.md 2022-08-06 01:10:41 +06:00
c50b35c66b
Merge pull request #39 from InsanusMokrassar/2.0.0
2.0.0
2022-08-06 01:10:14 +06:00
b309d6c946
Update libs.versions.toml 2022-08-06 00:42:58 +06:00
4f2b0aa40c
Update libs.versions.toml 2022-08-05 22:52:59 +06:00
2d38292b55
Update CHANGELOG.md 2022-08-05 22:11:37 +06:00
e177f3e47a
Update libs.versions.toml 2022-08-05 22:08:01 +06:00
2872395045
start 2.0.0 2022-08-05 22:06:39 +06:00
e49302b750
Merge pull request #38 from InsanusMokrassar/1.4.1
1.4.1
2022-08-03 09:20:34 +06:00
60dac2067a
Update CHANGELOG.md 2022-08-03 09:20:10 +06:00
fc1888923f
Update libs.versions.toml 2022-08-01 09:33:27 +06:00
703d3b1d64
Update gradle.properties 2022-08-01 09:32:21 +06:00
34383c1f82
Merge pull request #37 from InsanusMokrassar/1.4.0
1.4.0
2022-07-30 20:32:21 +06:00
9ec5303aed
Update CHANGELOG.md 2022-07-30 18:29:45 +06:00
351f6e59e1
Update libs.versions.toml 2022-07-30 18:29:26 +06:00
d4bc89eb2f start 1.4.0 and update kslog 2022-07-30 15:27:28 +06:00
00b8197b71
Merge pull request #36 from InsanusMokrassar/1.3.1
1.3.1
2022-07-22 21:11:52 +06:00
a090b4f13f
Update CHANGELOG.md 2022-07-22 21:10:05 +06:00
b377b5ed4f
Update dependencies 2022-07-22 20:03:24 +06:00
dde3317323
start 1.3.1 2022-07-22 20:02:33 +06:00
40de085f26
Merge pull request #35 from InsanusMokrassar/1.3.0
1.3.0
2022-07-11 12:32:34 +06:00
ce5b98d6c8 update kotlin 2022-07-11 12:27:55 +06:00
058c239690 start 1.3.0 2022-07-11 12:17:08 +06:00
43d49ac3cd
Update CHANGELOG.md 2022-07-10 00:21:27 +06:00
b0fbcfd54f
Merge pull request #34 from InsanusMokrassar/1.2.3
1.2.3
2022-07-10 00:20:53 +06:00
8f726cee82 start 1.2.3 and update tgbotapi 2022-07-09 23:11:29 +06:00
998968a9c1
Update github_release.gradle 2022-07-09 09:47:34 +06:00
d8d1860c5a
Merge pull request #33 from InsanusMokrassar/1.2.2
1.2.2
2022-07-09 09:44:56 +06:00
7ffd5a1433 update dependencies 2022-07-09 00:12:24 +06:00
05e2ec1c0d start 1.2.2 2022-07-09 00:07:07 +06:00
819ed7720a
Merge pull request #32 from InsanusMokrassar/1.2.1
1.2.1
2022-06-26 15:15:38 +06:00
c99e4ee188
Update CHANGELOG.md 2022-06-26 14:46:09 +06:00
a408cc5099
Update CHANGELOG.md 2022-06-26 14:45:55 +06:00
f1d3f48a6b
Update libs.versions.toml 2022-06-26 14:44:13 +06:00
2777a260ae
Update gradle.properties 2022-06-26 14:42:44 +06:00
155b9865a8
Merge pull request #31 from InsanusMokrassar/1.2.0
1.2.0
2022-06-22 09:05:33 +06:00
ecc17e50b9 update dependencies 2022-06-21 23:54:25 +06:00
ffafee3f43 start 1.2.0 2022-06-21 23:53:38 +06:00
b99bb9ee64
Merge pull request #30 from InsanusMokrassar/1.1.2
1.1.2
2022-06-20 20:59:53 +06:00
0dff596926 update dependencies and optimize imports 2022-06-20 20:58:38 +06:00
e0a19bb5e5 start 1.1.2 + add opportunity to load object plugins 2022-06-20 20:52:42 +06:00
5ec1c8c55f
Merge pull request #29 from InsanusMokrassar/1.1.1
1.1.1
2022-06-11 19:20:33 +06:00
37fd9f39d3 fixes in logging 2022-06-11 19:19:19 +06:00
f9f56f6afb update dependencies and add logging 2022-06-11 19:15:09 +06:00
343c26a7f1 start 1.1.1 2022-06-08 17:14:50 +06:00
1b5361eb28 change version in properties 2022-06-08 17:13:46 +06:00
511ec904e9 start 1.1.0 and update tgbotapi 2022-06-08 17:13:46 +06:00
a3f59087e0 updates in dependencies and update bot setup logic 2022-06-08 17:13:46 +06:00
492c04e25f start 1.0.1 2022-06-08 17:13:46 +06:00
6b017c129f remove redundant config test and update build workflow 2022-06-08 17:13:46 +06:00
93829d3e0d add logging inside of plagubot 2022-06-08 17:13:46 +06:00
a5e7ac180d fill changelog 2022-06-08 17:13:46 +06:00
77ba1d686c complete 1.0.0 2022-06-08 17:13:46 +06:00
dec27b1c34 temporal progress 2022-06-08 17:13:46 +06:00
11c5a38b72 start migration 2022-06-08 17:13:46 +06:00
9521217765 start 1.0.0 2022-06-08 17:13:46 +06:00
4df6eafe6a
Update CHANGELOG.md 2022-02-02 13:37:33 +06:00
3876262a7b
Update gradle.properties 2022-02-02 13:36:59 +06:00
b10a00ca0d
Update README.md 2022-01-06 12:46:23 +06:00
e6765b6c25
Merge pull request #24 from InsanusMokrassar/0.5.0
0.5.0
2022-01-04 17:41:05 +06:00
2fde3206e7 update changelog 2022-01-02 12:42:41 +06:00
4113fb2cc1 update dependencies 2022-01-02 12:41:15 +06:00
79ddfaf9bd start 0.5.0 2022-01-02 12:34:12 +06:00
8ae85ecc6e
Merge pull request #23 from InsanusMokrassar/0.4.1
0.4.1
2021-11-12 17:38:41 +06:00
9d25b4b071 0.4.1 2021-11-12 17:38:18 +06:00
6d00bb6242
Merge pull request #22 from InsanusMokrassar/0.4.0
0.4.0
2021-11-12 15:33:37 +06:00
d7638d620f 0.4.0 2021-11-12 14:05:42 +06:00
8885047409 start 0.4.0 2021-11-12 13:38:19 +06:00
f09f13c13d
Merge pull request #21 from InsanusMokrassar/0.3.2
0.3.2
2021-09-22 20:34:34 +06:00
8853af9a26
Update CHANGELOG.md 2021-09-22 20:34:03 +06:00
ab98b59633
Update dependencies 2021-09-22 20:30:52 +06:00
d88cf0c911
Update gradle.properties 2021-09-22 20:29:28 +06:00
5145b22dd5
Merge pull request #20 from InsanusMokrassar/0.3.1
0.3.1
2021-07-02 11:19:27 +06:00
90dd06db6d update dependencies 2021-07-01 22:44:01 +06:00
4e9b8349eb start 0.3.1 2021-07-01 22:38:54 +06:00
466e531faf
Merge pull request #19 from InsanusMokrassar/0.3.0
0.3.0
2021-06-07 19:38:43 +06:00
8bf42e6fca
Update CHANGELOG.md 2021-06-07 19:35:46 +06:00
a42bb91121
Update gradle.properties 2021-06-07 19:35:29 +06:00
fae2dca3d3 update changelog 2021-06-05 16:16:40 +06:00
a0d1bd2d54 update mircoutils and exposed 2021-06-05 15:25:17 +06:00
14e6c0c67d update versions 2021-06-04 12:12:58 +06:00
5a116d512a migration onto 0.3.0 2021-06-04 12:09:06 +06:00
3ba965f162 PluginsHolder, new Config deserialization and PlaguBot as correctly serializable/deserializable 2021-05-09 12:37:28 +06:00
aa8dc1af57 start 0.2.2 2021-05-08 21:35:53 +06:00
e83af6ba9f
Merge pull request #17 from InsanusMokrassar/0.2.1
0.2.1
2021-05-06 03:01:26 +06:00
83c5c30555 update dependencies 2021-05-05 19:45:49 +06:00
2740ba690b start 0.2.1 2021-05-05 19:43:06 +06:00
9c681e25d2
Merge pull request #16 from InsanusMokrassar/0.2.0
0.2.0
2021-04-30 01:44:46 +06:00
d799845bea
Update CHANGELOG.md 2021-04-30 01:44:24 +06:00
1f45b80b54
Update gradle.properties 2021-04-30 01:42:22 +06:00
9dabad898a
Merge pull request #15 from InsanusMokrassar/0.1.9
0.1.9
2021-04-25 10:55:56 +06:00
3a718f8652
Update gradle.properties 2021-04-25 09:45:47 +06:00
6f70c9eab3
Update CHANGELOG.md 2021-04-25 09:41:36 +06:00
ca98c74952
start 0.1.9 2021-04-25 09:35:35 +06:00
4fd6922864
Merge pull request #14 from InsanusMokrassar/0.1.8
0.1.8
2021-04-05 21:27:52 +06:00
1b700857fa update dependencies 2021-04-05 21:27:16 +06:00
64f35ab233 start 0.1.8 2021-04-05 21:26:46 +06:00
f7207688e4
Merge pull request #13 from InsanusMokrassar/0.1.7
0.1.7
2021-04-03 23:02:17 +06:00
d94df49795 optimize imports 2021-04-03 22:07:43 +06:00
1ffb7a1999 update of versions 2021-04-03 22:05:18 +06:00
8444172e44 PlaguBot class 2021-04-03 22:04:18 +06:00
15109391b1 start 0.1.7 2021-04-03 16:04:18 +06:00
175715d769
Merge pull request #12 from InsanusMokrassar/0.1.6
0.1.6
2021-03-30 15:26:06 +06:00
33 changed files with 1190 additions and 415 deletions

0
.fleet/settings.json Normal file
View File

View File

@ -8,9 +8,9 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Set up JDK 1.8
- name: Set up JDK 17
uses: actions/setup-java@v1
with:
java-version: 1.8
java-version: 17
- name: Build with Gradle
run: ./gradlew build

2
.gitignore vendored
View File

@ -10,5 +10,7 @@ build/
out/
local.properties
local.*
local.*/
config.json
secret.gradle

View File

@ -1,5 +1,579 @@
# Changelog
## 8.3.0
* `Versions`:
* `Serialization`: `1.6.3`
* `MicroUtils`: `0.20.45`
* `tgbotapi`: `12.0.1`
* `Exposed`: `0.49.0`
* `SQLite`: `3.45.3.0`
* `Koin`: `3.5.6`
## 8.2.0
* `Versions`:
* `Coroutines`: `1.8.0`
* `tgbotapi`: `10.1.0`
* `MicroUtils`: `0.20.35`
## 8.1.1
* `Versions`:
* `tgbotapi`: `10.0.1`
* `MicroUtils`: `0.20.32`
* `Exposed`: `0.47.0`
## 8.1.0
* Integrate `dev.inmo:micro_utils.startup` into project
## 8.0.0
* `Versions`:
* `tgbotapi`: `10.0.0`
* `MicroUtils`: `0.20.26`
* `Exposed`: `0.46.0`
## 7.4.2
* `Versions`:
* `Kotlin`: `1.9.22`
* `tgbotapi`: `9.4.3`
* `MicroUtils`: `0.20.23`
* `Koin`: `3.5.7`
## 7.4.1
* `Versions`:
* `Serialization`: `1.6.2`
* `tgbotapi`: `9.4.2`
* `Exposed`: `0.45.0`
* `SQLite`: `3.44.1.0`
* `MicroUtils`: `0.20.19`
* `uuid`: `0.8.2`
* `ktor`: `2.3.7`
## 7.3.0
* `Versions`:
* `Kotlin`: `1.9.21`
* `Serialization`: `1.6.1`
* `tgbotapi`: `9.4.1`
* `ktor`: `2.3.6`
* `KSLog`: Removed explicit dependency, now it is declared in tgbotapi
* `MicroUtils`: `0.20.15`
## 7.2.3
* `Versions`:
* `tgbotapi`: `9.2.2`
* `exposed`: `0.44.0`
* `koin`: `3.5.0`
* `ktor`: `2.3.5`
## 7.2.2
* `Bot`:
* Now you may customize both `onStart` and `onUpdate` conflicts resolvers
## 7.2.1
* `Versions`:
* `tgbotapi`: `9.2.1`
* `ktor`: `2.3.4`
## 7.2.0
* `Version`:
* `tgbotapi`: `9.2.0`
* `kslog`: `1.1.2`
* `sqlite`: `3.43.0.0`
## 7.1.0
* `Version`:
* `microutils`: `0.19.9`
* `tgbotapi`: `9.1.0`
* `ktor`: `2.3.3`
* `coroutines`: `1.7.3`
* `koin`: `3.4.3`
## 7.0.0
* `Version`:
* `microutils`: `0.19.7`
* `tgbotapi`: `9.0.0`
* `ktor`: `2.3.2`
* `coroutines`: `1.7.2`
## 6.1.0
* `Version`:
* `kotlin`: `1.8.22`
* `microutils`: `0.19.4`
* `tgbotapi`: `8.1.0`
* `koin`: `3.4.2`
* `sqlite`: `3.42.0.0`
## 6.0.1
* `Version`:
* `microutils`: `0.19.2`
* `tgbotapi`: `8.0.1`
* `uuid`: `0.7.1`
* `ktor`: `2.3.1`
* `koin`: `3.4.1`
## 6.0.0
* `Versions`:
* `microutils`: `0.19.1`
* `tgbotapi`: `8.0.0`
* `klock`: `4.0.3`
## 5.1.3
* `Versions`:
* `serialization`: `1.5.1`
* `microutils`: `0.18.4`
* `tgbotapi`: `7.1.3`
## 5.1.2
* `Versions`:
* `microutils`: `0.18.1`
* `tgbotapi`: `7.1.2`
## 5.1.1
* `Versions`:
* `kotlin`: `1.8.21`
* `microutils`: `0.18.0`
* `tgbotapi`: `7.1.1`
## 5.1.0
* `Versions`:
* `tgbotapi`: `7.1.0`
* `sqlite`: `3.41.2.1`
## 5.0.2
* `Versions`:
* `kotlin`: `1.8.20`
* `microutils`: `0.17.8`
* `tgbotapi`: `7.0.2`
* `kslog`: `1.1.1`
* `ktor`: `2.3.0`
* `koin`: `3.4.0`
## 5.0.1
* `Versions`:
* `tgbotapi`: `7.0.1`
## 5.0.0
* `Versions`:
* `tgbotapi`: `7.0.0`
* `microutils`: `0.17.5`
## 4.1.0
* `Versions`:
* `tgbotapi`: `6.1.0`
* `microutils`: `0.17.3`
## 4.0.3
* `Versions`:
* `tgbotapi`: `6.0.3`
* `microutils`: `0.17.2`
## 4.0.2
* `Versions`:
* `tgbotapi`: `6.0.2`
## 4.0.1
* `Versions`:
* `tgbotapi`: `6.0.1`
* `microutils`: `17.0.1`
* `ktor`: `2.2.4`
## 4.0.0
* `Versions`:
* `kotlin`: `1.8.10`
* `tgbotapi`: `6.0.0`
* `microutils`: `0.17.0`
## 3.5.0
* `Versions`:
* `tgbotapi`: `5.2.0`
* `microutils`: `0.16.10`
* `koin`: `3.3.2`
## 3.4.1
* `setupBotPlugin` now works synchronously
## 3.4.0
* `Versions`:
* `tgbotapi`: `5.1.0`
* `microutils`: `0.16.8`
* `ktor`: `2.2.3`
## 3.3.1
* `Versions`:
* `tgbotapi`: `5.0.1`
* `microutils`: `0.16.6`
* `ktor`: `2.2.2`
## 3.3.0
* `Versions`:
* `tgbotapi`: `5.0.0`
## 3.2.3
* `Versions`:
* `tgbotapi`: `4.2.3`
* `microutils`: `0.16.4`
## 3.2.2
* `Versions`:
* `tgbotapi`: `4.2.2`
* `microutils`: `0.16.2`
## 3.2.1
* `Versions`:
* `tgbotapi`: `4.2.1`
* `microutils`: `0.16.0`
* `ktor`: `2.2.1`
## 3.2.0
* `Versions`:
* `kotlin`: `1.7.22`
* `tgbotapi`: `4.2.0`
* `microutils`: `0.15.0`
* `kslog`: `0.5.4`
* `sqlite`: `3.40.0.0`
## 3.1.4
* `Versions`:
* `tgbotapi`: `4.1.3`
* `microutils`: `0.14.4`
## 3.1.3
* `Versions`:
* `tgbotapi`: `4.1.2`
## 3.1.2
* `Versions`:
* `microutils`: `0.14.2`
* `exposed`: `0.41.1`
## 3.1.1
* `Versions`:
* `tgbotapi`: `4.1.1`
## 3.1.0
* `Versions`:
* `kotlin`: `1.7.21`
* `microutils`: `0.14.1`
* `tgbotapi`: `4.1.0`
* `klock`: `3.4.0`
* `uuid`: `0.6.0`
## 3.0.0
* `Versions`:
* `microutils`: `0.14.0`
* `tgbotapi`: `4.0.0`
* `kslog`: `0.5.3`
* `exposed`: `0.40.1`
* `klock`: `3.3.1`
## 2.4.1
* `Versions`:
* `microutils`: `0.13.2`
* `tgbotapi`: `3.3.1`
* `klock`: `3.3.0`
* `ktor`: `2.1.3`
* `koin`: `3.2.2`
## 2.4.0
* `Versions`:
* `kotlin`: `1.7.20`
* `serialization`: `1.4.1`
* `tgbotapi`: `3.3.0`
* `microutils`: `0.13.1`
* `klock`: `3.2.0`
* `ktor`: `2.1.2`
## 2.3.4
* `Versions`:
* `tgbotapi`: `3.2.7`
* `microutils`: `0.12.16`
## 2.3.3
* `Versions`:
* `tgbotapi`: `3.2.6`
* `sqlite`: `3.39.3.0`
## 2.3.2
* `Versions`:
* `tgbotapi`: `3.2.3`
* `microutils`: `0.12.13`
* `kslog`: `0.5.2`
## 2.3.1
* `Versions`:
* `klock`: `3.1.0`
* `tgbotapi`: `3.2.1`
* `microutils`: `0.12.11`
* `ktor`: `2.1.1`
## 2.3.0
* `Bot`:
* Add option `reconnectOptions` in database config
## 2.2.0
* `Versions`:
* `serialization`: `1.4.0`
* `tgbotapi`: `3.2.0`
* `microutils`: `0.12.4`
* `kslog`: `0.5.1`
## 2.1.1
* `Bot`:
* Now it is possible to get bot from `koin`
## 2.1.0
* `Versions`:
* `tgbotapi`: `3.1.1`
* `ktor`: `2.1.0`
* `microutils`: `0.12.1`
* `Plugins`:
* New fum of `Plugin` with `BehaviourContextWithFSM` receiver
* `Bot`:
* Now bot uses `buildBehaviourWithFSM` to be able to setup bot with FSM
## 2.0.0
* `Versions`:
* `kotlin`: `1.7.10`
* `serialization`: `1.4.0-RC`
* `tgbotapi`: `3.0.2`
* `kslog`: `0.5.0`
* `uuid`: `0.5.0`
* `exposed`: `0.39.2`
* `microutils`: `0.12.0`
## 1.4.1
* `Versions`:
* `tgbotapi`: `2.2.2`
* `kslog`: `0.4.2`
## 1.4.0
* `Versions`:
* `kslog`: `0.4.1`
## 1.3.1
* `Versions`:
* `tgbotapi`: `2.2.1`
* `microutils`: `0.11.13`
## 1.3.0
* `Versions`
* `tgbotapi`: `2.2.0`
## 1.2.3
* `Versions`
* `tgbotapi`: `2.1.3`
## 1.2.2
* `Versions`
* `tgbotapi`: `2.1.2`
* `microutils`: `0.11.12`
* `coroutines`: `1.6.3`
* `ktor`: `2.0.3`
## 1.2.1
* `Versions`
* `tgbotapi`: `2.1.1`
* `microutils`: `0.11.6`
* `kslog`: `0.3.2`
## 1.2.0
* `Versions`
* `tgbotapi`: `2.1.0`
## 1.1.2
* `Versions`
* `tgbotapi`: `2.0.3`
* `microutils`: `0.11.3`
* `kslog`: `0.3.1`
* `Plugin`:
* Now it is possible to use `object`s of plugins instead of classes
## 1.1.1
* `Versions`
* `coroutines`: `1.6.2`
* `tgbotapi`: `2.0.2`
* `microutils`: `0.11.0`
* `ktor`: `2.0.2`
* `uuid`: `0.4.1`
## 1.1.0
* `Versions`
* `tgbotapi`: `2.0.0`
* `microutils`: `0.10.5`
* `Plugin`:
* All plugins will be loaded in parallel
## 1.0.0
* `Versions`
* `kotlin`: `1.6.21`
* `coroutines`: `1.6.1`
* `serialization`: `1.3.3`
* `exposed`: `0.38.2`
* `tgbotapi`: `1.1.0`
* `microutils`: `0.10.4`
* `Common`:
* ___ALL THE SDI/KLASSINDEX FUNCTIONALITY HAS BEEN REMOVED___
* `Plugin`:
* Now plugins must have empty constructor
* Now plugins may provide realization of two methods: `setupDI` and `setupBotPlugin`
* `PlaguBot`:
* `Config` now is simple serializable `data class`
* `PlaguBot` now is more simple as a plugin
## 0.5.1
* `Versions`
* `tgbotapi`: `0.38.4`
* `microutils`: `0.9.5`
## 0.5.0
* `Versions`
* `kotlin`: `1.6.10`
* `coroutines`: `1.6.0`
* `serialization`: `1.3.2`
* `exposed`: `0.37.2`
* `tgbotapi`: `0.38.0`
* `microutils`: `0.9.0`
## 0.4.1
Temporal update for compatibility with java 1.8
## 0.3.2
* `Versions`
* `kotlin`: `1.5.20` -> `1.5.31`
* `coroutines`: `1.5.0` -> `1.5.2`
* `serialization`: `1.2.1` -> `1.2.2`
* `exposed`: `0.32.1` -> `0.34.2`
* `tgbotapi`: `0.35.1` -> `0.35.9`
* `microutils`: `0.5.15` -> `0.5.28`
## 0.3.1
* `Versions`
* `kotlin`: `1.5.10` -> `1.5.20`
* `tgbotapi`: `0.35.0` -> `0.35.1`
* `microutils`: `0.5.7` -> `0.5.15`
## 0.3.0
* `Versions`
* `kotlin`: `1.4.32` -> `1.5.10`
* `coroutines`: `1.4.3` -> `1.5.0`
* `serialization`: `1.1.0` -> `1.2.1`
* `exposed`: `0.31.1` -> `0.32.1`
* `sdi`: `0.4.1` -> `0.5.0`
* `tgbotapi`: `0.34.1` -> `0.35.0`
* `microutils`: `0.4.36` -> `0.5.7`
* `Bot`
* Add plugin `PluginsHolder`
* Rewrite mechanism of `Config` working
* `PlaguBot` now is correctly serializable/deserializable
## 0.2.1
* `Versions`
* `tgbotapi`: `0.33.4` -> `0.34.0`
* `sqlite`: `3.30.1` -> `3.34.0`
## 0.2.0
* `Versions`
* `tgbotapi`: `0.33.4` -> `0.34.0`
* `exposed`: `0.30.2` -> `0.31.1`
## 0.1.9
* `Versions`
* `tgbotapi`: `0.33.3` -> `0.33.4`
* `microutils`: `0.4.33` -> `0.4.36`
* `exposed`: `0.30.1` -> `0.30.2`
## 0.1.8
* `Versions`
* `tgbotapi`: `0.33.2` -> `0.33.3`
* `microutils`: `0.4.32` -> `0.4.33`
## 0.1.7
* `Versions`
* `exposed`: `0.29.1` -> `0.30.1`
* `tgbotapi`: `0.33.1` -> `0.33.2`
* `microutils`: `0.4.31` -> `0.4.32`
* `PlaguBot`
* New class `PlaguBot` (😊)
* `initPlaguBot` is deprecated
* New shortcut for params - `plagubot`. `PlaguBot` class can be put inside other plagubot
for additional opportunities
## 0.1.6
* `Versions`

View File

@ -11,8 +11,33 @@ You can create your bot using
| Template: | [![Use template](badges/use_template.svg)](https://github.com/InsanusMokrassar/PlaguBotPluginTemplate/generate) |
|-----------|-----------------------------------------------------------------------------------------------------------------|
| Bot version: | [![Download](https://api.bintray.com/packages/insanusmokrassar/PlaguBot/plagubot.bot/images/download.svg)](https://bintray.com/insanusmokrassar/PlaguBot/plagubot.bot/_latestVersion) |
| Plugin version: | [![Download](https://api.bintray.com/packages/insanusmokrassar/PlaguBot/plagubot.plugin/images/download.svg)](https://bintray.com/insanusmokrassar/PlaguBot/plagubot.plugin/_latestVersion) |
| Bot version: | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/plagubot.bot/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/plagubot.bot) |
| Plugin version: | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/plagubot.plugin/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/plagubot.plugin) |
That is a set of libraries for plagubots. Look at the
[PlaguBot Plugin template](https://insanusmokrassar.github.io/PlaguBotPluginTemplate/) to find how to create your bot.
### Technical help
In this bot has been used variant with FSM. That means that you may use all the [Behaviour Builder with FSM](https://bookstack.inmo.dev/books/telegrambotapi/page/behaviour-builder-with-fsm) functionality. In case you wish to setup states repo, you should use the next code in the `setupDI` of your plugin:
```kotlin
single<StatesManager<State>> {
// setup your manager and return here
// Default is:
DefaultStatesManager(
InMemoryDefaultStatesManagerRepo()
)
}
```
Besides, you may setup handling errors lambda in the same function:
```kotlin
single<StateHandlingErrorHandler<State>> {
{ state, e ->
logger.eS(e) { "Unable to handle state $state" } // logging by default
null // you should return new state or null, default callback will return null
}
}
```

View File

@ -1,8 +1,8 @@
plugins {
id 'org.jetbrains.kotlin.jvm'
id "org.jetbrains.kotlin.plugin.serialization"
id "org.jetbrains.kotlin.kapt"
id 'application'
id "com.google.devtools.ksp"
}
project.group="$group"
@ -11,21 +11,20 @@ project.version="$version"
apply from: "publish.gradle"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
api "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_runtime_version"
api "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
api "org.jetbrains.exposed:exposed-jdbc:$kotlin_exposed_version"
implementation libs.kt.stdlib
api libs.kt.coroutines
api libs.kt.serialization
api libs.jb.exposed.jdbc
api "dev.inmo:tgbotapi:$tgbotapi_version"
api "dev.inmo:sdi:$sdi_version"
api "dev.inmo:micro_utils.repos.exposed:$microutils_version"
api libs.tgbotapi
api libs.tgbotapi.behaviourBuilder.fsm
api libs.microutils.repos.exposed
api libs.microutils.koin
api libs.microutils.startup.launcher
api "com.github.matfax.klassindex:library:$klassindex_version"
kapt "com.github.matfax.klassindex:processor:$klassindex_version"
api "org.xerial:sqlite-jdbc:$sqlite_version"
api libs.sqlite
testImplementation "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
testImplementation libs.kt.test.junit
api project(":plagubot.plugin")
}
@ -34,10 +33,11 @@ application {
mainClassName = 'dev.inmo.plagubot.AppKt'
}
kapt {
arguments {
arg("com.github.matfax.klassindex.IndexSubclasses", "dev.inmo.plagubot.Plugin")
arg("com.github.matfax.klassindex.IndexAnnotated", "dev.inmo.sdi.SDIIncluded")
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
ksp { // this generator do not require any arguments and we should left `ksp` empty
}

View File

@ -1 +0,0 @@
{"bintrayConfig":{"repo":"PlaguBot","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/PlaguBot","autoPublish":true,"overridePublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/PlaguBot/LICENSE"}],"mavenConfig":{"name":"PlaguBot Bot","description":"Base PlaguBot project","url":"https://github.com/InsanusMokrassar/PlaguBot","vcsUrl":"ssh://git@github.com/InsanusMokrassar/PlaguBot.git","includeGpgSigning":true,"publishToMavenCentral":true,"developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"}]},"type":"JVM"}

View File

@ -1,14 +1,12 @@
apply plugin: 'maven-publish'
apply plugin: 'signing'
task javadocJar(type: Jar) {
from javadoc
classifier = 'javadoc'
archiveClassifier = 'javadoc'
}
task sourcesJar(type: Jar) {
from sourceSets.main.allSource
classifier = 'sources'
archiveClassifier = 'sources'
}
publishing {
@ -50,33 +48,71 @@ publishing {
}
}
repositories {
repositories {
if ((project.hasProperty('INMONEXUS_USER') || System.getenv('INMONEXUS_USER') != null) && (project.hasProperty('INMONEXUS_PASSWORD') || System.getenv('INMONEXUS_PASSWORD') != null)) {
maven {
name = "bintray"
url = uri("https://api.bintray.com/maven/${project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')}/PlaguBot/${project.name}/;publish=1;override=1")
name = "InmoNexus"
url = uri("https://nexus.inmo.dev/repository/maven-releases/")
credentials {
username = project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')
password = project.hasProperty('BINTRAY_KEY') ? project.property('BINTRAY_KEY') : System.getenv('BINTRAY_KEY')
username = project.hasProperty('INMONEXUS_USER') ? project.property('INMONEXUS_USER') : System.getenv('INMONEXUS_USER')
password = project.hasProperty('INMONEXUS_PASSWORD') ? project.property('INMONEXUS_PASSWORD') : System.getenv('INMONEXUS_PASSWORD')
}
}
}
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
maven {
name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
}
}
}
}
}
}
}
signing {
useGpgCmd()
sign publishing.publications
if (project.hasProperty("signing.gnupg.keyName")) {
apply plugin: 'signing'
signing {
useGpgCmd()
sign publishing.publications
}
task signAll {
tasks.withType(Sign).forEach {
dependsOn(it)
}
}
// Workaround to make android sign operations depend on signing tasks
project.getTasks().withType(AbstractPublishToMaven.class).configureEach {
def signingTasks = project.getTasks().withType(Sign.class)
mustRunAfter(signingTasks)
}
// Workaround to make test tasks use sign
project.getTasks().withType(Sign.class).configureEach { signTask ->
def withoutSign = (signTask.name.startsWith("sign") ? signTask.name.minus("sign") : signTask.name)
def pubName = withoutSign.endsWith("Publication") ? withoutSign.substring(0, withoutSign.length() - "Publication".length()) : withoutSign
// These tasks only exist for native targets, hence findByName() to avoid trying to find them for other targets
// Task ':linkDebugTest<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
def debugTestTask = tasks.findByName("linkDebugTest$pubName")
if (debugTestTask != null) {
signTask.mustRunAfter(debugTestTask)
}
// Task ':compileTestKotlin<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
def testTask = tasks.findByName("compileTestKotlin$pubName")
if (testTask != null) {
signTask.mustRunAfter(testTask)
}
}
}

1
bot/publish.kpsb Normal file
View File

@ -0,0 +1 @@
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/PlaguBot/LICENSE"}],"mavenConfig":{"name":"PlaguBot Bot","description":"Base PlaguBot project","url":"https://github.com/InsanusMokrassar/PlaguBot","vcsUrl":"ssh://git@github.com/InsanusMokrassar/PlaguBot.git","developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"InmoNexus","url":"https://nexus.inmo.dev/repository/maven-releases/"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}},"type":"JVM"}

View File

@ -1,48 +1,25 @@
package dev.inmo.plagubot
import dev.inmo.micro_utils.coroutines.safelyWithoutExceptions
import dev.inmo.plagubot.config.*
import dev.inmo.plagubot.config.configJsonFormat
import dev.inmo.tgbotapi.bot.Ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.bot.setMyCommands
import dev.inmo.tgbotapi.extensions.behaviour_builder.buildBehaviour
import dev.inmo.tgbotapi.types.botCommandsLimit
import kotlinx.coroutines.*
import dev.inmo.kslog.common.KSLog
import dev.inmo.kslog.common.i
import dev.inmo.plagubot.config.Config
import dev.inmo.plagubot.config.defaultJsonFormat
import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.json.jsonObject
import java.io.File
suspend inline fun initPlaguBot(
config: Config,
scope: CoroutineScope = CoroutineScope(Dispatchers.Default)
): Job {
val bot = telegramBot(config.botToken)
val paramsMap = config.params ?.toMap() ?: emptyMap()
val database = config.params ?.database ?: config.database.database
return bot.buildBehaviour(scope) {
val commands = config.plugins.flatMap {
it.apply { invoke(database, paramsMap) }
it.getCommands()
}.let {
val futureUnavailable = it.drop(botCommandsLimit.last)
if (futureUnavailable.isNotEmpty()) {
println("Next commands are out of range in setting command request and will be unavailable from autocompleting: ${futureUnavailable}")
}
it.take(botCommandsLimit.last)
}
safelyWithoutExceptions { setMyCommands(commands) }
}
}
/**
* This method by default expects one argument in [args] field: path to config
*/
@InternalSerializationApi
suspend fun main(args: Array<String>) {
KSLog.default = KSLog("PlaguBot")
val (configPath) = args
val file = File(configPath)
val config = configJsonFormat.decodeFromString(ConfigSerializer, file.readText())
KSLog.i("Start read config from ${file.absolutePath}")
val json = defaultJsonFormat.parseToJsonElement(file.readText()).jsonObject
val config = defaultJsonFormat.decodeFromJsonElement(Config.serializer(), json)
KSLog.i("Config has been read")
val scope = CoroutineScope(Dispatchers.Default)
initPlaguBot(config, scope).join()
PlaguBot(json, config).start().join()
}

View File

@ -1,16 +1,68 @@
package dev.inmo.plagubot
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.kslog.common.*
import dev.inmo.micro_utils.fsm.common.State
import dev.inmo.plagubot.HelloPlugin.setupBotPlugin
import dev.inmo.tgbotapi.extensions.api.bot.getMe
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.api.send.sendMessage
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitText
import dev.inmo.tgbotapi.extensions.behaviour_builder.expectations.waitTextMessage
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onUnhandledCommand
import dev.inmo.tgbotapi.types.IdChatIdentifier
import kotlinx.coroutines.flow.first
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import org.jetbrains.exposed.sql.Database
import org.koin.core.Koin
import org.koin.core.module.Module
@Serializable
@SerialName("Hello")
data class HelloPlugin(
val parameter: String
) : Plugin {
override suspend fun BehaviourContext.invoke(database: Database) {
println(parameter)
object HelloPlugin : Plugin {
@Serializable
data class HelloPluginConfig(
val print: String
)
override fun Module.setupDI(database: Database, params: JsonObject) {
single {
get<Json>().decodeFromJsonElement(HelloPluginConfig.serializer(), params["helloPlugin"] ?: return@single null)
}
}
private sealed interface InternalFSMState : State {
override val context: IdChatIdentifier
data class DidntSaidHello(override val context: IdChatIdentifier) : InternalFSMState
data class SaidHelloOnce(override val context: IdChatIdentifier) : InternalFSMState
}
override suspend fun startPlugin(koin: Koin) {
super.startPlugin(koin)
logger.i { "This logic called BEFORE the bot will be started and setup" }
}
override suspend fun BehaviourContextWithFSM<State>.setupBotPlugin(koin: Koin) {
val toPrint = koin.getOrNull<HelloPluginConfig>() ?.print ?: "Hello :)"
logger.d { toPrint }
logger.dS { getMe().toString() }
onCommand("hello_world") {
startChain(InternalFSMState.DidntSaidHello(it.chat.id))
}
strictlyOn { state: InternalFSMState.DidntSaidHello ->
sendMessage(state.context, toPrint)
InternalFSMState.SaidHelloOnce(state.context)
}
strictlyOn { state: InternalFSMState.SaidHelloOnce ->
val message = waitTextMessage().first()
reply(message, "Sorry, I can answer only this: $toPrint")
InternalFSMState.SaidHelloOnce(state.context)
}
}
}

View File

@ -0,0 +1,16 @@
package dev.inmo.plagubot
import dev.inmo.micro_utils.fsm.common.State
fun interface OnStartContextsConflictResolver {
/**
* @param old Old state which is currently placed on the [State.context]
* @param new New state pretend to replace [old] one
* @return Should return:
*
* * Null in case when current realization unable to resolve conflict
* * False when current realization knows that [new] [State] must **not** replace [old] one
* * True when current realization knows that [new] [State] must replace [old] one
*/
suspend operator fun invoke(old: State, new: State): Boolean?
}

View File

@ -0,0 +1,20 @@
package dev.inmo.plagubot
import dev.inmo.micro_utils.fsm.common.State
fun interface OnUpdateContextsConflictResolver {
/**
* This method will be called when [sourceStateWithOldContext] [State.context] and [newStateWithNewContext] are not equal and currently there is
* launched [currentStateOnNewContext] state on the chain with [State.context] from [currentStateOnNewContext]
*
* @param sourceStateWithOldContext Old state where from [newStateWithNewContext] came
* @param newStateWithNewContext New state with changing [State.context] (it is different with [sourceStateWithOldContext] [State.context])
* @param currentStateOnNewContext State which is currently running on [newStateWithNewContext] [State.context]
* @return Should return:
*
* * Null in case when current realization unable to resolve conflict
* * False when [currentStateOnNewContext] **should not** be stopped in favor to [newStateWithNewContext]
* * True when [currentStateOnNewContext] **should** be stopped in favor to [newStateWithNewContext]
*/
suspend operator fun invoke(sourceStateWithOldContext: State, newStateWithNewContext: State, currentStateOnNewContext: State): Boolean?
}

View File

@ -0,0 +1,162 @@
package dev.inmo.plagubot
import dev.inmo.kslog.common.*
import dev.inmo.micro_utils.common.Warning
import dev.inmo.micro_utils.coroutines.runCatchingSafely
import dev.inmo.micro_utils.fsm.common.State
import dev.inmo.micro_utils.fsm.common.StatesManager
import dev.inmo.micro_utils.fsm.common.managers.*
import dev.inmo.micro_utils.koin.getAllDistinct
import dev.inmo.plagubot.config.*
import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutorBuilder
import dev.inmo.tgbotapi.bot.ktor.telegramBot
import dev.inmo.tgbotapi.extensions.api.webhook.deleteWebhook
import dev.inmo.tgbotapi.extensions.behaviour_builder.*
import dev.inmo.tgbotapi.extensions.utils.updates.retrieving.startGettingOfUpdatesByLongPolling
import kotlinx.coroutines.*
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import kotlinx.serialization.json.JsonObject
import org.jetbrains.exposed.sql.Database
import org.koin.core.Koin
import org.koin.core.KoinApplication
import org.koin.core.context.GlobalContext
import org.koin.core.module.Module
import org.koin.core.scope.Scope
import org.koin.dsl.module
val Scope.plagubot: PlaguBot
get() = get()
val Koin.plagubot: PlaguBot
get() = get()
@OptIn(Warning::class)
@Serializable
data class PlaguBot(
private val json: JsonObject,
private val config: Config
) : Plugin {
@Transient
private val bot = telegramBot(
token = config.botToken,
apiUrl = config.botApiServer
) {
setupBotClient()
}
override fun KtorRequestsExecutorBuilder.setupBotClient() {
config.botPlugins.forEach {
with(it) {
setupBotClient()
}
}
}
override fun Module.setupDI(config: JsonObject) {
single { this@PlaguBot.config }
single { this@PlaguBot.config.plugins }
single { this@PlaguBot.config.databaseConfig }
single { this@PlaguBot.config.databaseConfig.database }
single { defaultJsonFormat }
single { this@PlaguBot }
single { bot }
}
override fun Module.setupDI(database: Database, params: JsonObject) {
setupDI(params)
includes(
config.botPlugins.mapNotNull {
runCatching {
module {
with(it) {
setupDI(database, params)
}
}
}.onFailure { e ->
logger.w(e) { "Unable to load DI part of $it" }
}.getOrNull()
}
)
}
override suspend fun startPlugin(koin: Koin) {
super.startPlugin(koin)
config.plugins.forEach { plugin ->
runCatchingSafely {
logger.i { "Starting of $plugin common logic" }
with(plugin) {
startPlugin(koin)
}
}.onFailure { e ->
logger.w(e) { "Unable to load common logic of $plugin" }
}.onSuccess {
logger.i { "Complete loading of $plugin common logic" }
}
}
}
override suspend fun BehaviourContextWithFSM<State>.setupBotPlugin(koin: Koin) {
config.botPlugins.forEach { plugin ->
runCatchingSafely {
logger.i("Start loading of $plugin")
with(plugin) {
setupBotPlugin(koin)
}
}.onFailure { e ->
logger.w("Unable to load bot part of $plugin", e)
}.onSuccess {
logger.i("Complete loading of $plugin")
}
}
}
/**
* This method will create an [Job] which will be the main [Job] of ran instance
*/
suspend fun start(
scope: CoroutineScope = CoroutineScope(Dispatchers.IO)
): Job {
logger.i("Start initialization")
val koinApp = KoinApplication.init()
koinApp.modules(
module {
setupDI(config.databaseConfig.database, json)
}
)
logger.i("Modules loaded. Starting koin")
GlobalContext.startKoin(koinApp)
logger.i("Koin started. Starting plugins common logic")
startPlugin(koinApp.koin)
logger.i("Plugins common logic started. Starting setup of bot logic part")
lateinit var behaviourContext: BehaviourContext
val onStartContextsConflictResolver by lazy { koinApp.koin.getAllDistinct<OnStartContextsConflictResolver>() }
val onUpdateContextsConflictResolver by lazy { koinApp.koin.getAllDistinct<OnUpdateContextsConflictResolver>() }
bot.buildBehaviourWithFSM(
scope = scope,
defaultExceptionsHandler = {
logger.e("Something went wrong", it)
},
statesManager = koinApp.koin.getOrNull<StatesManager<State>>() ?: DefaultStatesManager(
koinApp.koin.getOrNull<DefaultStatesManagerRepo<State>>() ?: InMemoryDefaultStatesManagerRepo<State>(),
onStartContextsConflictResolver = { old, new -> onStartContextsConflictResolver.firstNotNullOfOrNull { it(old, new) } ?: false },
onUpdateContextsConflictResolver = { old, new, currentNew -> onUpdateContextsConflictResolver.firstNotNullOfOrNull { it(old, new, currentNew) } ?: false }
),
onStateHandlingErrorHandler = koinApp.koin.getOrNull<StateHandlingErrorHandler<State>>() ?: { state, e ->
logger.eS(e) { "Unable to handle state $state" }
null
}
) {
logger.i("Start setup of bot part")
behaviourContext = this
setupBotPlugin(koinApp.koin)
deleteWebhook()
}.start()
logger.i("Behaviour builder has been setup")
return bot.startGettingOfUpdatesByLongPolling(scope = behaviourContext, updatesFilter = behaviourContext).also {
logger.i("Long polling has been started")
}
}
}

View File

@ -1,166 +1,20 @@
package dev.inmo.plagubot.config
import com.github.matfax.klassindex.KlassIndex
import dev.inmo.micro_utils.common.Warning
import dev.inmo.micro_utils.startup.plugin.StartPlugin
import dev.inmo.plagubot.Plugin
import dev.inmo.plagubot.PluginSerializer
import dev.inmo.sdi.*
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.*
import kotlinx.serialization.modules.*
import kotlin.reflect.KClass
@InternalSerializationApi
internal inline fun <T : Plugin> KClass<T>.includeIn(builder: PolymorphicModuleBuilder<Plugin>) = builder.subclass(this, serializer())
@InternalSerializationApi
internal val configJsonFormat: Json
get() = Json {
ignoreUnknownKeys = true
serializersModule = SerializersModule {
polymorphic(Plugin::class) {
KlassIndex.getSubclasses(Plugin::class).flatMap { kclass ->
kclass.includeIn(this)
kclass.annotations.mapNotNull { it as? SerialName }.map {
it.value to kclass.serializer()
} + listOfNotNull(
kclass.simpleName ?.let {
it to kclass.serializer()
}
)
}.toMap().let {
default { requiredType ->
it[requiredType]
}
}
}
}
}
import dev.inmo.tgbotapi.utils.telegramBotAPIDefaultUrl
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Warning("This API is internal and can be changed without notifications or mentions of changes")
@Serializable
data class Config(
val plugins: List<@Contextual Plugin>,
val database: DatabaseConfig = DatabaseConfig(),
val botToken: String,
@Contextual
val params: Module? = null
)
@Serializer(Plugin::class)
private class InternalPluginSerializer(
private val params: Module
) : KSerializer<Plugin> {
override val descriptor: SerialDescriptor = PluginSerializer.descriptor
@InternalSerializationApi
override fun deserialize(decoder: Decoder): Plugin {
val asJson = JsonElement.serializer().deserialize(decoder)
return if (asJson is JsonPrimitive) {
params[asJson.jsonPrimitive.content] as Plugin
} else {
val jsonFormat = ((decoder as? JsonDecoder)?.json ?: configJsonFormat)
jsonFormat.decodeFromJsonElement(PluginSerializer, asJson)
}
}
@InternalSerializationApi
override fun serialize(encoder: Encoder, value: Plugin) {
params.keys.firstOrNull { params[it] === value } ?.also {
encoder.encodeString(it)
} ?: PluginSerializer.serialize(encoder, value)
}
}
private val DefaultModuleSerializer = ModuleSerializer(emptyList()) {
}
@Serializer(Module::class)
private class InternalModuleSerializer(
private val original: JsonElement?,
private val params: Module
) : KSerializer<Module> {
override val descriptor: SerialDescriptor = PluginSerializer.descriptor
@InternalSerializationApi
override fun deserialize(decoder: Decoder): Module {
val asJson = JsonElement.serializer().deserialize(decoder)
return if (asJson == original) {
params
} else {
configJsonFormat.decodeFromJsonElement(DefaultModuleSerializer, asJson)
}
}
@InternalSerializationApi
override fun serialize(encoder: Encoder, value: Module) = DefaultModuleSerializer.serialize(encoder, value)
}
private fun internalPluginSerializerSerializersModule(
internalPluginSerializer: InternalPluginSerializer,
internalModuleSerializer: InternalModuleSerializer?
) = SerializersModule {
contextual(internalPluginSerializer)
contextual(internalModuleSerializer ?: return@SerializersModule)
}
@Serializer(Config::class)
internal object ConfigSerializer : KSerializer<Config> {
private val jsonSerializer = JsonObject.serializer()
private val moduleSerializer = ModuleSerializer()
@InternalSerializationApi
override fun deserialize(decoder: Decoder): Config {
val json = jsonSerializer.deserialize(decoder)
val jsonFormat = (decoder as? JsonDecoder) ?.json ?: configJsonFormat
val paramsRow = json["params"]
val resultJsonFormat = if (paramsRow != null && paramsRow != JsonNull) {
val params = jsonFormat.decodeFromJsonElement(
moduleSerializer,
paramsRow
)
val pluginsSerializer = InternalPluginSerializer(params)
val moduleSerializer = InternalModuleSerializer(paramsRow, params)
Json(jsonFormat) {
serializersModule = decoder.serializersModule.overwriteWith(
internalPluginSerializerSerializersModule(pluginsSerializer, moduleSerializer)
)
}
} else {
jsonFormat
}
return resultJsonFormat.decodeFromJsonElement(
Config.serializer(),
json
)
}
@InternalSerializationApi
override fun serialize(encoder: Encoder, value: Config) {
if (value.params != null) {
val pluginsSerializer = InternalPluginSerializer(value.params)
val jsonFormat = Json(configJsonFormat) {
serializersModule = encoder.serializersModule.overwriteWith(
internalPluginSerializerSerializersModule(pluginsSerializer, null)
)
}
jsonSerializer.serialize(
encoder,
jsonFormat.encodeToJsonElement(
Config.serializer(),
value
) as JsonObject
)
} else {
Config.serializer().serialize(encoder, value)
}
}
val plugins: List<StartPlugin>,
@SerialName("database")
val databaseConfig: DatabaseConfig = DatabaseConfig(),
val botApiServer: String = telegramBotAPIDefaultUrl
) {
val botPlugins = plugins.filterIsInstance<Plugin>()
}

View File

@ -0,0 +1,9 @@
package dev.inmo.plagubot.config
import kotlinx.serialization.Serializable
@Serializable
data class DBConnectOptions(
val attempts: Int = 3,
val delay: Long = 1000L
)

View File

@ -1,32 +1,43 @@
package dev.inmo.plagubot.config
import dev.inmo.sdi.SDIIncluded
import dev.inmo.kslog.common.e
import dev.inmo.kslog.common.logger
import kotlinx.coroutines.delay
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.transactions.transactionManager
import org.koin.core.scope.Scope
import org.sqlite.JDBC
import java.lang.Exception
import java.sql.Connection
const val defaultDatabaseParamsName = "defaultDatabase"
inline val Map<String, Any>.database: Database?
get() = (get(defaultDatabaseParamsName) as? DatabaseConfig) ?.database
inline val Scope.database: Database?
get() = getOrNull<Database>()
@Serializable
@SDIIncluded
data class DatabaseConfig(
val url: String = "jdbc:sqlite:file:test?mode=memory&cache=shared",
val driver: String = JDBC::class.qualifiedName!!,
val username: String = "",
val password: String = ""
val password: String = "",
val reconnectOptions: DBConnectOptions? = DBConnectOptions()
) {
@Transient
val database: Database = Database.connect(
url,
driver,
username,
password
).also {
it.transactionManager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE // Or Connection.TRANSACTION_READ_UNCOMMITTED
}
val database: Database = (0 until (reconnectOptions ?.attempts ?: 1)).firstNotNullOfOrNull {
runCatching {
Database.connect(
url,
driver,
username,
password
).also {
it.transactionManager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE // Or Connection.TRANSACTION_READ_UNCOMMITTED
it.connector().close()
}
}.onFailure {
logger.e(it)
Thread.sleep(reconnectOptions ?.delay ?: return@onFailure)
}.getOrNull()
} ?: error("Unable to create database")
}

View File

@ -0,0 +1,7 @@
package dev.inmo.plagubot.config
import kotlinx.serialization.json.Json
val defaultJsonFormat = Json {
ignoreUnknownKeys = true
}

View File

@ -0,0 +1,3 @@
package dev.inmo.plagubot.config
typealias StateHandlingErrorHandler<T> = suspend (T, Throwable) -> T?

View File

@ -1,37 +0,0 @@
package dev.inmo.plagubot.config
import dev.inmo.plagubot.HelloPlugin
import kotlinx.serialization.InternalSerializationApi
import org.junit.Test
import kotlin.test.assertEquals
class ConfigTest {
@InternalSerializationApi
@Test
fun testThatPluginPassedToParamsWillBeCorrectlyUsedInPlugins() {
val rawConfig = """
{
"database": {
},
"botToken": "",
"plugins": [
"helloPlugin"
],
"params": {
"helloPlugin": {"type": "dev.inmo.plagubot.HelloPlugin", "parameter": "Example"}
}
}
""".trimIndent()
val config = configJsonFormat.decodeFromString(ConfigSerializer, rawConfig)
assert(config.plugins.size == 1)
assert(config.plugins.first() is HelloPlugin)
assert((config.plugins.first() as HelloPlugin).parameter == "Example")
val redecoded = configJsonFormat.decodeFromString(ConfigSerializer, configJsonFormat.encodeToString(ConfigSerializer, config))
assertEquals(config.database, redecoded.database)
assertEquals(config.plugins, redecoded.plugins)
assertEquals(config.botToken, redecoded.botToken)
assertEquals(config.params ?.toMap(), redecoded.params ?.toMap())
}
}

View File

@ -1,22 +1,23 @@
buildscript {
repositories {
jcenter()
mavenCentral()
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
classpath "com.github.breadmoirai:github-release:$github_release_plugin_version"
classpath libs.buildscript.kt.gradle
classpath libs.buildscript.kt.serialization
classpath libs.buildscript.gh.release
classpath libs.buildscript.ksp
}
}
allprojects {
repositories {
mavenCentral()
jcenter()
mavenLocal()
maven { url 'https://jitpack.io' }
maven { url "https://nexus.inmo.dev/repository/maven-releases/" }
}
}

View File

@ -20,13 +20,13 @@ if (new File(projectDir, "secret.gradle").exists()) {
releaseAssets.from('bot/build/distributions')
owner "InsanusMokrassar"
repo "PlaguBot"
owner = "InsanusMokrassar"
repo = "PlaguBot"
tagName "${project.version}"
releaseName "${project.version}"
targetCommitish "${project.version}"
tagName = "v${project.version}"
releaseName = "${project.version}"
targetCommitish = "${project.version}"
body getCurrentVersionChangelog()
body = getCurrentVersionChangelog()
}
}

View File

@ -4,19 +4,5 @@ org.gradle.parallel=true
kotlin.js.generate.externals=true
kotlin.incremental=true
kotlin_version=1.4.32
kotlin_coroutines_version=1.4.3
kotlin_serialisation_runtime_version=1.1.0
kotlin_exposed_version=0.29.1
sdi_version=0.4.1
tgbotapi_version=0.33.1
microutils_version=0.4.31
klassindex_version=4.1.0-rc.1
sqlite_version=3.30.1
github_release_plugin_version=2.2.12
group=dev.inmo
version=0.1.6
version=8.3.0

50
gradle/libs.versions.toml Normal file
View File

@ -0,0 +1,50 @@
[versions]
kt = "1.9.23"
kt-serialization = "1.6.3"
kt-coroutines = "1.8.0"
microutils = "0.20.45"
tgbotapi = "12.0.1"
ksp = "1.9.23-1.0.20"
jb-exposed = "0.49.0"
jb-dokka = "1.9.20"
sqlite = "3.45.3.0"
gh-release = "2.5.2"
koin = "3.5.6"
[libraries]
kt-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kt" }
kt-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kt-coroutines" }
kt-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kt-serialization" }
tgbotapi = { module = "dev.inmo:tgbotapi", version.ref = "tgbotapi" }
tgbotapi-behaviourBuilder-fsm = { module = "dev.inmo:tgbotapi.behaviour_builder.fsm", version.ref = "tgbotapi" }
microutils-repos-exposed = { module = "dev.inmo:micro_utils.repos.exposed", version.ref = "microutils" }
microutils-koin = { module = "dev.inmo:micro_utils.koin", version.ref = "microutils" }
microutils-koin-generator = { module = "dev.inmo:micro_utils.koin.generator", version.ref = "microutils" }
microutils-startup-launcher = { module = "dev.inmo:micro_utils.startup.launcher", version.ref = "microutils" }
microutils-startup-plugin = { module = "dev.inmo:micro_utils.startup.plugin", version.ref = "microutils" }
koin = { module = "io.insert-koin:koin-core", version.ref = "koin" }
jb-exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc", version.ref = "jb-exposed" }
sqlite = { module = "org.xerial:sqlite-jdbc", version.ref = "sqlite" }
kt-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kt" }
buildscript-kt-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kt" }
buildscript-kt-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kt" }
buildscript-jb-dokka = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "jb-dokka" }
buildscript-gh-release = { module = "com.github.breadmoirai:github-release", version.ref = "gh-release" }
buildscript-ksp = { module = "com.google.devtools.ksp:symbol-processing-gradle-plugin", version.ref = "ksp" }

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -9,9 +9,17 @@ project.version="$version"
apply from: "publish.gradle"
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
api "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlin_serialisation_runtime_version"
implementation libs.kt.stdlib
api libs.kt.serialization
api "dev.inmo:tgbotapi:$tgbotapi_version"
api "dev.inmo:micro_utils.repos.exposed:$microutils_version"
api libs.tgbotapi
api libs.microutils.repos.exposed
api libs.microutils.startup.plugin
api libs.koin
}
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

View File

@ -1 +0,0 @@
{"bintrayConfig":{"repo":"PlaguBot","packageName":"${project.name}","packageVcs":"https://github.com/InsanusMokrassar/PlaguBot","autoPublish":true,"overridePublish":true},"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/PlaguBot/LICENSE"}],"mavenConfig":{"name":"PlaguBot Plugin","description":"Base dependency for whole PlaguBot project","url":"https://github.com/InsanusMokrassar/PlaguBot","vcsUrl":"ssh://git@github.com/InsanusMokrassar/PlaguBot.git","includeGpgSigning":true,"publishToMavenCentral":true,"developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"}]},"type":"JVM"}

View File

@ -1,14 +1,12 @@
apply plugin: 'maven-publish'
apply plugin: 'signing'
task javadocJar(type: Jar) {
from javadoc
classifier = 'javadoc'
archiveClassifier = 'javadoc'
}
task sourcesJar(type: Jar) {
from sourceSets.main.allSource
classifier = 'sources'
archiveClassifier = 'sources'
}
publishing {
@ -50,33 +48,71 @@ publishing {
}
}
repositories {
repositories {
if ((project.hasProperty('INMONEXUS_USER') || System.getenv('INMONEXUS_USER') != null) && (project.hasProperty('INMONEXUS_PASSWORD') || System.getenv('INMONEXUS_PASSWORD') != null)) {
maven {
name = "bintray"
url = uri("https://api.bintray.com/maven/${project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')}/PlaguBot/${project.name}/;publish=1;override=1")
name = "InmoNexus"
url = uri("https://nexus.inmo.dev/repository/maven-releases/")
credentials {
username = project.hasProperty('BINTRAY_USER') ? project.property('BINTRAY_USER') : System.getenv('BINTRAY_USER')
password = project.hasProperty('BINTRAY_KEY') ? project.property('BINTRAY_KEY') : System.getenv('BINTRAY_KEY')
username = project.hasProperty('INMONEXUS_USER') ? project.property('INMONEXUS_USER') : System.getenv('INMONEXUS_USER')
password = project.hasProperty('INMONEXUS_PASSWORD') ? project.property('INMONEXUS_PASSWORD') : System.getenv('INMONEXUS_PASSWORD')
}
}
}
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
maven {
name = "sonatype"
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
credentials {
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
}
}
}
}
}
}
}
signing {
useGpgCmd()
sign publishing.publications
if (project.hasProperty("signing.gnupg.keyName")) {
apply plugin: 'signing'
signing {
useGpgCmd()
sign publishing.publications
}
task signAll {
tasks.withType(Sign).forEach {
dependsOn(it)
}
}
// Workaround to make android sign operations depend on signing tasks
project.getTasks().withType(AbstractPublishToMaven.class).configureEach {
def signingTasks = project.getTasks().withType(Sign.class)
mustRunAfter(signingTasks)
}
// Workaround to make test tasks use sign
project.getTasks().withType(Sign.class).configureEach { signTask ->
def withoutSign = (signTask.name.startsWith("sign") ? signTask.name.minus("sign") : signTask.name)
def pubName = withoutSign.endsWith("Publication") ? withoutSign.substring(0, withoutSign.length() - "Publication".length()) : withoutSign
// These tasks only exist for native targets, hence findByName() to avoid trying to find them for other targets
// Task ':linkDebugTest<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
def debugTestTask = tasks.findByName("linkDebugTest$pubName")
if (debugTestTask != null) {
signTask.mustRunAfter(debugTestTask)
}
// Task ':compileTestKotlin<platform>' uses this output of task ':sign<platform>Publication' without declaring an explicit or implicit dependency
def testTask = tasks.findByName("compileTestKotlin$pubName")
if (testTask != null) {
signTask.mustRunAfter(testTask)
}
}
}

1
plugin/publish.kpsb Normal file
View File

@ -0,0 +1 @@
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/PlaguBot/LICENSE"}],"mavenConfig":{"name":"PlaguBot Plugin","description":"Base dependency for whole PlaguBot project","url":"https://github.com/InsanusMokrassar/PlaguBot","vcsUrl":"ssh://git@github.com/InsanusMokrassar/PlaguBot.git","developers":[{"id":"InsanusMokrassar","name":"Aleksei Ovsiannikov","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"InmoNexus","url":"https://nexus.inmo.dev/repository/maven-releases/"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}},"type":"JVM"}

View File

@ -1,47 +1,50 @@
package dev.inmo.plagubot
import dev.inmo.tgbotapi.bot.TelegramBot
import dev.inmo.micro_utils.fsm.common.State
import dev.inmo.micro_utils.startup.plugin.StartPlugin
import dev.inmo.tgbotapi.bot.ktor.KtorRequestsExecutorBuilder
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContext
import dev.inmo.tgbotapi.types.BotCommand
import dev.inmo.tgbotapi.updateshandlers.FlowsUpdatesFilter
import kotlinx.coroutines.CoroutineScope
import dev.inmo.tgbotapi.extensions.behaviour_builder.BehaviourContextWithFSM
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonObject
import org.jetbrains.exposed.sql.Database
import org.koin.core.Koin
import org.koin.core.module.Module
/**
* **ANY REALIZATION OF [Plugin] MUST HAVE CONSTRUCTOR WITH ABSENCE OF INCOMING PARAMETERS**
*
* Use this interface for your bot. It is possible to use [kotlinx.serialization.SerialName] annotations on your plugins
* to set up short name for your plugin. Besides, simple name of your class will be used as key for deserialization
* too.
*/
@Serializable(PluginSerializer::class)
interface Plugin {
/**
* In case you want to publish some processed by your plugin commands, you can provide it via this method
*
* @see BotCommand
*/
suspend fun getCommands(): List<BotCommand> = emptyList()
interface Plugin : StartPlugin {
fun KtorRequestsExecutorBuilder.setupBotClient() {}
@Deprecated("Override other method with receiver BehaviourContext")
suspend operator fun invoke(
bot: TelegramBot,
/**
* This method will be called when this plugin should configure di module based on the incoming params
*/
fun Module.setupDI(
database: Database,
updatesFilter: FlowsUpdatesFilter,
scope: CoroutineScope
params: JsonObject
) {
setupDI(params)
}
/**
* Override this method in cases when you want to declare common bot behaviour. In case you wish to use FSM, you
* should override the method with receiver [BehaviourContextWithFSM]
*/
suspend fun BehaviourContext.setupBotPlugin(
koin: Koin
) {}
/**
* This method (usually) will be invoked just one time in the whole application.
* Override this method in cases when you want to declare full behaviour of the plugin. It is recommended to declare
* common logic of plugin in the [setupBotPlugin] with [BehaviourContext] receiver and use override this one
* for the FSM configuration
*/
suspend operator fun BehaviourContext.invoke(
database: Database
) = invoke(bot, database, flowsUpdatesFilter, scope)
/**
* This method (usually) will be invoked just one time in the whole application.
*/
suspend operator fun BehaviourContext.invoke(
database: Database,
params: Map<String, Any>
) = invoke(database)
suspend fun BehaviourContextWithFSM<State>.setupBotPlugin(koin: Koin) {
(this as BehaviourContext).setupBotPlugin(koin)
}
}

View File

@ -1,53 +1,25 @@
package dev.inmo.plagubot
import kotlinx.serialization.*
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.*
private val defaultJson = Json {
ignoreUnknownKeys = true
}
@Serializer(Plugin::class)
object PluginSerializer : KSerializer<Plugin> {
private val polymorphic = PolymorphicSerializer(Plugin::class)
override val descriptor: SerialDescriptor = JsonObject.serializer().descriptor
class PluginSerializer : KSerializer<Plugin> {
override val descriptor: SerialDescriptor
get() = String.serializer().descriptor
@InternalSerializationApi
override fun deserialize(decoder: Decoder): Plugin {
val format = (decoder as? JsonDecoder) ?.json ?: defaultJson
val asJson = JsonElement.serializer().deserialize(decoder)
val jsonObject = (asJson as? JsonObject)
val type = (jsonObject ?.get("type") as? JsonPrimitive) ?.contentOrNull
val external = if (type != null) {
try {
Class.forName(type) ?.kotlin ?.serializerOrNull()
} catch (e: Exception) {
null
}
} else {
null
}
return if (jsonObject != null && external != null) {
format.decodeFromJsonElement(
external as KSerializer<Plugin>,
JsonObject(jsonObject.toMutableMap().also { it.remove("type") })
)
} else {
format.decodeFromJsonElement(
polymorphic,
asJson
)
}
val kclass = Class.forName(decoder.decodeString()).kotlin
return (kclass.objectInstance ?: kclass.constructors.first { it.parameters.isEmpty() }.call()) as Plugin
}
@InternalSerializationApi
override fun serialize(encoder: Encoder, value: Plugin) {
val serializer = (value::class.serializerOrNull() ?: polymorphic) as KSerializer<Plugin>
serializer.serialize(encoder, value)
encoder.encodeString(
value::class.java.canonicalName
)
}
}
}

View File

@ -2,7 +2,12 @@ String[] toInclude = [":bot", ":plugin"]
rootProject.name = 'plagubot'
toInclude.each {
include (it)
project(it).name = "${rootProject.name}${it.replace(":", ".")}"
toInclude.each { originalName ->
String projectDirectory = "${rootProject.projectDir.getAbsolutePath()}${originalName.replace(":", File.separator)}"
String projectName = "${rootProject.name}${originalName.replace(":", ".")}"
String projectIdentifier = ":${projectName}"
include projectIdentifier
ProjectDescriptor project = project(projectIdentifier)
project.name = projectName
project.projectDir = new File(projectDirectory)
}

View File

@ -4,13 +4,16 @@
"driver": "org.sqlite.JDBC",
"username": "OPTIONAL username",
"password": "OPTIONAL password",
"initAutomatically": false
"reconnectOptions": {
"attempts": 3,
"delay": 1000
}
},
"botToken": "1234567890:ABCDEFGHIJKLMNOP_qrstuvwxyz12345678",
"plugins": [
{
"type": "Hello",
"parameter": "Example"
}
]
}
"dev.inmo.plagubot.HelloPlugin"
],
"helloPlugin": {
"print": "Hello World"
}
}