Compare commits
260 Commits
Author | SHA1 | Date |
---|---|---|
Kay Marquardt | 8f23bca8a1 | |
Kay Marquardt | 420029c7f6 | |
Kay Marquardt | 02c73d432e | |
Kay Marquardt | 1c2c07397a | |
Kay Marquardt | 8f742ff1fb | |
Kay Marquardt | d0c3156e7d | |
Kay Marquardt | d157f61cf2 | |
Kay Marquardt | af7596f69a | |
Kay Marquardt | 0c25a11c5c | |
Kay Marquardt | 5653582d68 | |
Kay Marquardt | b6dc3a0d93 | |
Kay Marquardt | 4b2331b623 | |
Kay Marquardt | 38f2cc475b | |
Kay Marquardt | 74294f3fb4 | |
Kay Marquardt | 4591b357d1 | |
Kay Marquardt (Gnadelwartz) | bc71f37a2e | |
Kay Marquardt (Gnadelwartz) | 0dae2db8ac | |
Kay Marquardt (Gnadelwartz) | 1a83202a07 | |
Kay Marquardt (Gnadelwartz) | 58e6d0aaf6 | |
Kay Marquardt (Gnadelwartz) | 479f41c80e | |
Kay Marquardt (Gnadelwartz) | 67d75feace | |
Kay Marquardt (Gnadelwartz) | 1ffa890428 | |
Kay Marquardt | 6490f6756f | |
z4zz | 90d3d7551d | |
Kay Marquardt (Gnadelwartz) | d06c162f16 | |
Kay Marquardt | 89ac61afe7 | |
konqi | 369d7f8d4d | |
konqi | 93dc4a09d6 | |
konqi | 738c5e5f6d | |
Kay Marquardt (Gnadelwartz) | aad42a52fb | |
Kay Marquardt (Gnadelwartz) | a2a3927117 | |
Kay Marquardt (Gnadelwartz) | 5205fe3990 | |
Kay Marquardt (Gnadelwartz) | 783bf30190 | |
Kay Marquardt | a23370645f | |
Kay Marquardt (Gnadelwartz) | 36d8604cde | |
Kay Marquardt (Gnadelwartz) | 6e66a2877c | |
Kay Marquardt (Gnadelwartz) | 52fbb14770 | |
Kay Marquardt (Gnadelwartz) | c63f098fb0 | |
Kay Marquardt (Gnadelwartz) | 69b1871eea | |
Kay Marquardt (Gnadelwartz) | 45efa80699 | |
Kay Marquardt (Gnadelwartz) | b097f088c8 | |
Kay Marquardt (Gnadelwartz) | e4c13ddabe | |
Kay Marquardt (Gnadelwartz) | f7f55ea45f | |
Kay Marquardt (Gnadelwartz) | 9b6aba0586 | |
Kay Marquardt (Gnadelwartz) | ecaecfee6f | |
Kay Marquardt (Gnadelwartz) | 4c4ba0ba5e | |
Kay Marquardt (Gnadelwartz) | f790d73e66 | |
Kay Marquardt (Gnadelwartz) | 79fc511bdb | |
Kay Marquardt (Gnadelwartz) | 3501318d84 | |
Kay Marquardt | 443958aa5f | |
Kay Marquardt (Gnadelwartz) | 12157b380d | |
Kay Marquardt (Gnadelwartz) | cbd74a7f72 | |
Kay Marquardt (Gnadelwartz) | dedcc00b8c | |
Kay Marquardt (Gnadelwartz) | 721e433b47 | |
Kay Marquardt (Gnadelwartz) | cbde841bae | |
Kay Marquardt (Gnadelwartz) | f1ea49426b | |
Kay Marquardt (Gnadelwartz) | e60ada0bfe | |
Kay Marquardt (Gnadelwartz) | 85f7c074f4 | |
Kay Marquardt (Gnadelwartz) | 43cab461f8 | |
Kay Marquardt (Gnadelwartz) | 99950e6518 | |
Kay Marquardt | 94aefbe4d5 | |
Kay Marquardt (Gnadelwartz) | 369124bada | |
Kay Marquardt (Gnadelwartz) | 8adca9beea | |
Kay Marquardt (Gnadelwartz) | 41e6883817 | |
Kay Marquardt (Gnadelwartz) | ae525c47e0 | |
Kay Marquardt (Gnadelwartz) | 47a032d582 | |
Kay Marquardt (Gnadelwartz) | 761aa46b66 | |
Kay Marquardt (Gnadelwartz) | a5b230646b | |
Kay Marquardt (Gnadelwartz) | 24638662d3 | |
Kay Marquardt (Gnadelwartz) | b1af0f07e7 | |
Kay Marquardt (Gnadelwartz) | c4e2981116 | |
Kay Marquardt (Gnadelwartz) | 235f26a0e9 | |
Kay Marquardt (Gnadelwartz) | 50777ceff7 | |
Kay Marquardt (Gnadelwartz) | fdb2b3ac7b | |
Kay Marquardt (Gnadelwartz) | 0a296eaaa1 | |
Kay Marquardt (Gnadelwartz) | eb0c227615 | |
Kay Marquardt (Gnadelwartz) | 7500ca0d12 | |
Kay Marquardt (Gnadelwartz) | ac16103361 | |
Kay Marquardt (Gnadelwartz) | b78431eacd | |
Kay Marquardt (Gnadelwartz) | b454827109 | |
Kay Marquardt (Gnadelwartz) | e6838d1436 | |
Kay Marquardt (Gnadelwartz) | 53e936ee65 | |
Kay Marquardt (Gnadelwartz) | ec90ce820d | |
Kay Marquardt (Gnadelwartz) | 859ce92379 | |
Kay Marquardt (Gnadelwartz) | fff79d6daf | |
Kay Marquardt (Gnadelwartz) | e098aee321 | |
Kay Marquardt (Gnadelwartz) | 4854d0d051 | |
Kay Marquardt (Gnadelwartz) | 7b8e391479 | |
Kay Marquardt (Gnadelwartz) | 24158142f9 | |
Kay Marquardt (Gnadelwartz) | a9ac7eaeda | |
Kay Marquardt (Gnadelwartz) | a473e25dfd | |
Kay Marquardt (Gnadelwartz) | b6e90af4fa | |
Kay Marquardt (Gnadelwartz) | 0859354be8 | |
Kay Marquardt (Gnadelwartz) | 5dd24c3958 | |
Kay Marquardt (Gnadelwartz) | dda86e3496 | |
Kay Marquardt (Gnadelwartz) | 941598d01f | |
Kay Marquardt (Gnadelwartz) | 84ff8cec15 | |
Kay Marquardt (Gnadelwartz) | f7842f4f60 | |
Kay Marquardt (Gnadelwartz) | 34923ddabe | |
Kay Marquardt (Gnadelwartz) | 2131911625 | |
Kay Marquardt (Gnadelwartz) | f4d45d814f | |
Kay Marquardt (Gnadelwartz) | f4323e48b5 | |
Kay Marquardt (Gnadelwartz) | c57e9273fb | |
Kay Marquardt (Gnadelwartz) | 6b8ad9783a | |
Kay Marquardt (Gnadelwartz) | 17efeeb903 | |
Kay Marquardt (Gnadelwartz) | ac71000519 | |
Kay Marquardt (Gnadelwartz) | 1a0642bcce | |
Kay Marquardt (Gnadelwartz) | 192fae8a37 | |
Kay Marquardt (Gnadelwartz) | 70724427d9 | |
Kay Marquardt (Gnadelwartz) | 8b18f25c88 | |
Kay Marquardt (Gnadelwartz) | 882efa8f1a | |
Kay Marquardt (Gnadelwartz) | fdbfcebc7c | |
Kay Marquardt (Gnadelwartz) | f7897fd41b | |
Kay Marquardt (Gnadelwartz) | 473d802aab | |
Kay Marquardt | b1e6e0fc50 | |
Kay Marquardt | aee7bae141 | |
Kay Marquardt (Gnadelwartz) | 622a394494 | |
Kay Marquardt (Gnadelwartz) | 3f848ac17d | |
Kay Marquardt (Gnadelwartz) | 8efbfcaab9 | |
Kay Marquardt (Gnadelwartz) | d6f37afa3a | |
Kay Marquardt (Gnadelwartz) | 9958b5b5e1 | |
Kay Marquardt (Gnadelwartz) | 77ffbabf22 | |
Kay Marquardt (Gnadelwartz) | 82a57a77ed | |
Kay Marquardt (Gnadelwartz) | b1f6a0b230 | |
Kay Marquardt (Gnadelwartz) | 785e769460 | |
Kay Marquardt (Gnadelwartz) | 805a74eb6d | |
Kay Marquardt (Gnadelwartz) | 6b07242179 | |
Kay Marquardt (Gnadelwartz) | e67e43dd2e | |
Kay Marquardt (Gnadelwartz) | 2f4ef69971 | |
Kay Marquardt (Gnadelwartz) | 429f271939 | |
Kay Marquardt (Gnadelwartz) | 193ca1e5b9 | |
Kay Marquardt (Gnadelwartz) | a7d85e352c | |
Kay Marquardt (Gnadelwartz) | c58fa22b7a | |
Kay Marquardt (Gnadelwartz) | d3a1cecf1f | |
Kay Marquardt (Gnadelwartz) | f842730645 | |
Kay Marquardt (Gnadelwartz) | 117255a958 | |
Kay Marquardt (Gnadelwartz) | 066274c943 | |
Kay Marquardt (Gnadelwartz) | 897458a37f | |
Kay Marquardt (Gnadelwartz) | b2fc4052fc | |
Kay Marquardt (Gnadelwartz) | 62b6b618d5 | |
Kay Marquardt (Gnadelwartz) | 069570e4ed | |
Kay Marquardt (Gnadelwartz) | a9ed559383 | |
Kay Marquardt (Gnadelwartz) | 2f6f3bd4d8 | |
Kay Marquardt (Gnadelwartz) | eee5458232 | |
Kay Marquardt (Gnadelwartz) | 52d1ac5618 | |
Kay Marquardt (Gnadelwartz) | 429c230627 | |
Kay Marquardt (Gnadelwartz) | a6ff405cc5 | |
Kay Marquardt (Gnadelwartz) | 34455c2c4c | |
Kay Marquardt (Gnadelwartz) | 9d36f23b14 | |
Kay Marquardt (Gnadelwartz) | ad1b91f3bc | |
Kay Marquardt (Gnadelwartz) | ccac62dd72 | |
Kay Marquardt (Gnadelwartz) | 5294d00ae3 | |
Kay Marquardt (Gnadelwartz) | b91e96dce1 | |
Kay Marquardt (Gnadelwartz) | 5212df422e | |
Kay Marquardt (Gnadelwartz) | 0702d58ab0 | |
Kay Marquardt (Gnadelwartz) | 54673ac396 | |
Kay Marquardt (Gnadelwartz) | baa4e14ebc | |
Kay Marquardt (Gnadelwartz) | bc40a3fcbb | |
Kay Marquardt (Gnadelwartz) | 5a689d22de | |
Kay Marquardt (Gnadelwartz) | 58fb001d1e | |
Kay Marquardt | d15b4f5070 | |
Kay Marquardt (Gnadelwartz) | 6fe19556b7 | |
Kay Marquardt (Gnadelwartz) | f9dab50f84 | |
Kay Marquardt (Gnadelwartz) | 1440d56f48 | |
Kay Marquardt (Gnadelwartz) | 969c7a9fbb | |
Kay Marquardt (Gnadelwartz) | d876f758ee | |
Kay Marquardt (Gnadelwartz) | 9ce139a689 | |
Kay Marquardt (Gnadelwartz) | 3a29a9dc4a | |
Kay Marquardt (Gnadelwartz) | 737be16b3f | |
Kay Marquardt (Gnadelwartz) | 91a143ab15 | |
Kay Marquardt (Gnadelwartz) | c4d100e0ad | |
Kay Marquardt (Gnadelwartz) | e86c8dc116 | |
Kay Marquardt (Gnadelwartz) | c1aec9285e | |
Kay Marquardt (Gnadelwartz) | e4a983b16f | |
Kay Marquardt (Gnadelwartz) | 4e7b3052de | |
Kay Marquardt (Gnadelwartz) | 6754273c6e | |
Kay Marquardt (Gnadelwartz) | 5b0b121ba5 | |
Kay Marquardt (Gnadelwartz) | a7c98d750c | |
Kay Marquardt (Gnadelwartz) | 0dd5f83d5a | |
Kay Marquardt (Gnadelwartz) | 342a5da97a | |
Kay Marquardt (Gnadelwartz) | 8034a5f055 | |
Kay Marquardt (Gnadelwartz) | f377e17e44 | |
Kay Marquardt (Gnadelwartz) | bc3a3b3def | |
Kay Marquardt (Gnadelwartz) | 4833712246 | |
Kay Marquardt (Gnadelwartz) | 2a3663a463 | |
Kay Marquardt (Gnadelwartz) | a289cb8e5b | |
Kay Marquardt (Gnadelwartz) | 9316caa260 | |
Kay Marquardt (Gnadelwartz) | c0f1af529e | |
Kay Marquardt (Gnadelwartz) | 1e49f6c2b1 | |
Kay Marquardt (Gnadelwartz) | 9cfeab9cdc | |
Kay Marquardt (Gnadelwartz) | 10d275c557 | |
Kay Marquardt (Gnadelwartz) | 08b7b85d03 | |
Kay Marquardt (Gnadelwartz) | c9daa822bb | |
Kay Marquardt (Gnadelwartz) | c693ab5bb9 | |
Kay Marquardt (Gnadelwartz) | 7c748247d8 | |
Kay Marquardt (Gnadelwartz) | cfc4d2eed1 | |
Kay Marquardt (Gnadelwartz) | 41e2d09067 | |
Kay Marquardt (Gnadelwartz) | 279a9e7ca3 | |
Kay Marquardt (Gnadelwartz) | a3eec98491 | |
Kay Marquardt (Gnadelwartz) | e83f4d443f | |
Kay Marquardt (Gnadelwartz) | 0c0dc01f26 | |
Kay Marquardt (Gnadelwartz) | 3f331dc8e8 | |
Kay Marquardt (Gnadelwartz) | ca9ea1bf31 | |
Kay Marquardt (Gnadelwartz) | b45efa3726 | |
Kay Marquardt (Gnadelwartz) | 079eb1c289 | |
Kay Marquardt (Gnadelwartz) | 5a0a5712dd | |
Kay Marquardt (Gnadelwartz) | 5192212782 | |
Kay Marquardt (Gnadelwartz) | 8c85c81f94 | |
Kay Marquardt (Gnadelwartz) | cbf3945e4f | |
Kay Marquardt (Gnadelwartz) | fa0cb75c60 | |
Kay Marquardt (Gnadelwartz) | 75e775606a | |
Kay Marquardt (Gnadelwartz) | e4ee88003e | |
Kay Marquardt (Gnadelwartz) | b096338c33 | |
Kay Marquardt (Gnadelwartz) | 2222875e2b | |
Kay Marquardt (Gnadelwartz) | b441384d4a | |
Kay Marquardt (Gnadelwartz) | 08a05242f9 | |
Kay Marquardt (Gnadelwartz) | bc414eef5a | |
Kay Marquardt (Gnadelwartz) | 47cab8021d | |
Kay Marquardt (Gnadelwartz) | 6b102a728a | |
Kay Marquardt (Gnadelwartz) | 70a3c194a0 | |
Kay Marquardt (Gnadelwartz) | 5ceddde4e8 | |
Kay Marquardt (Gnadelwartz) | cc4ac1a816 | |
Kay Marquardt (Gnadelwartz) | 9584068ea3 | |
Kay Marquardt (Gnadelwartz) | c90b5658b3 | |
Kay Marquardt (Gnadelwartz) | cc7afdb149 | |
Kay Marquardt (Gnadelwartz) | aa2c20b37e | |
Kay Marquardt (Gnadelwartz) | 461e748c92 | |
Kay Marquardt (Gnadelwartz) | 1fe22a0345 | |
Kay Marquardt (Gnadelwartz) | 9023b21791 | |
Kay Marquardt (Gnadelwartz) | d9b3342c3c | |
Kay Marquardt (Gnadelwartz) | f995eeea13 | |
Kay Marquardt (Gnadelwartz) | 78e4551107 | |
Kay Marquardt (Gnadelwartz) | 41e956d517 | |
Kay Marquardt (Gnadelwartz) | 121f131bb4 | |
Kay Marquardt (Gnadelwartz) | 13052f01da | |
Kay Marquardt (Gnadelwartz) | 2960e58941 | |
Kay Marquardt (Gnadelwartz) | 8bb4b7e5ac | |
Kay Marquardt (Gnadelwartz) | 28328013c7 | |
Kay Marquardt (Gnadelwartz) | 3378c1a5d1 | |
Kay Marquardt (Gnadelwartz) | 407194b23f | |
Kay Marquardt (Gnadelwartz) | 4371050206 | |
Kay Marquardt (Gnadelwartz) | db8f32b732 | |
Kay Marquardt (Gnadelwartz) | 662c6f48cb | |
Kay Marquardt (Gnadelwartz) | e9543991ee | |
Kay Marquardt (Gnadelwartz) | 07f026c6a7 | |
Kay Marquardt (Gnadelwartz) | 749eee74a4 | |
Kay Marquardt (Gnadelwartz) | 127cc85a2a | |
Kay Marquardt (Gnadelwartz) | 85a178d68a | |
Kay Marquardt (Gnadelwartz) | f6e319c6eb | |
Kay Marquardt (Gnadelwartz) | f95b6c2e7d | |
Kay Marquardt (Gnadelwartz) | 6c91a327a6 | |
Kay Marquardt (Gnadelwartz) | 8854e03ece | |
Kay Marquardt (Gnadelwartz) | e923e2e8fc | |
Kay Marquardt (Gnadelwartz) | f2dd64c900 | |
Kay Marquardt (Gnadelwartz) | f66e5702b0 | |
Kay Marquardt (Gnadelwartz) | 0ee6973143 | |
Kay Marquardt (Gnadelwartz) | b0f653b705 | |
Kay Marquardt (Gnadelwartz) | 427f670a02 | |
Kay Marquardt (Gnadelwartz) | 62378f7cf6 | |
Kay Marquardt (Gnadelwartz) | fe1fb75748 |
223
README.html
223
README.html
|
@ -6,136 +6,6 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<title>Bashbot README</title>
|
||||
<style>
|
||||
html {
|
||||
line-height: 1.5;
|
||||
font-family: Georgia, serif;
|
||||
font-size: 20px;
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
word-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 1em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, 'Lucida Console', Consolas, monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
span.underline{text-decoration: underline;}
|
||||
|
@ -204,7 +74,6 @@
|
|||
code span.va { color: #19177c; } /* Variable */
|
||||
code span.vs { color: #4070a0; } /* VerbatimString */
|
||||
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
||||
|
@ -223,8 +92,8 @@ Written by Drew (@topkecleon) and Kay M (@gnadelwartz).
|
|||
<p>Released to the public domain wherever applicable. Elsewhere, consider it released under the <a href="http://www.wtfpl.net/txt/copying/">WTFPLv2</a>.</p>
|
||||
<p>Linted by <a href="https://github.com/koalaman/shellcheck">#ShellCheck</a></p>
|
||||
<h2>Prerequisites</h2>
|
||||
<p>Uses <a href="http://github.com/dominictarr/JSON.sh">JSON.sh</a> and the magic of sed.</p>
|
||||
<p>Bashbot is written in bash. It depends on commands typically available in a Linux/Unix Environment. For more concrete information on the common commands provided by recent versions of <a href="https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands">coreutils</a>, <a href="https://en.wikipedia.org/wiki/BusyBox#Commands">busybox</a> or <a href="https://landley.net/toybox/help.html">toybox</a>, see <a href="doc/7_develop.md#common-commands">Developer Notes</a>.</p>
|
||||
<p>Uses <a href="http://github.com/dominictarr/JSON.sh">JSON.sh</a>/<a href="https://github.com/step-/JSON.awk">JSON.awk</a> and the magic of sed.</p>
|
||||
<p>Bashbot is written in bash. It depends on commands typically available in a Linux/Unix Environment. For more information on commands provided by recent versions of <a href="https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands">coreutils</a>, <a href="https://en.wikipedia.org/wiki/BusyBox#Commands">busybox</a> or <a href="https://landley.net/toybox/help.html">toybox</a>, see <a href="doc/7_develop.md#common-commands">Developer Notes</a>.</p>
|
||||
<p><strong>Note for MacOS and BSD Users:</strong> Bashbot will not run without installing additional software as it uses modern bash and (gnu) grep/sed features. See <a href="doc/0_install.md">Install Bashbot</a>.</p>
|
||||
<p><strong>Note for embedded systems:</strong> You need to install a "real" bash as the vanilla installation of busybox or toybox is not sufficient. See <a href="doc/0_install.md">Install Bashbot</a>.</p>
|
||||
<p>Bashbot <a href="https://github.com/topkecleon/telegram-bot-bash">Documentation</a> and <a href="https://github.com/topkecleon/telegram-bot-bash/releases">Downloads</a> are available on <a href="https://www.github.com">www.github.com</a>.</p>
|
||||
|
@ -284,34 +153,35 @@ Written by Drew (@topkecleon) and Kay M (@gnadelwartz).
|
|||
<li>Setup your environment</li>
|
||||
<li>Bashbot test suite</li>
|
||||
</ul></li>
|
||||
<li><a href="examples/README.md">Examples Directory</a></li>
|
||||
<li><a href="examples">Examples Directory</a></li>
|
||||
<li><a href="examples/webhook">Webhook Example</a></li>
|
||||
</ul>
|
||||
<h3>Your very first bashbot in a nutshell</h3>
|
||||
<p>To install and run bashbot you need access to a Linux/Unix command line with bash, a <a href="https://telegram.org">Telegram client</a> and a mobile phone <a href="https://telegramguide.com/create-a-telegram-account/">with a Telegram account</a>.</p>
|
||||
<p>First you need to <a href="doc/1_firstbot.md">create a new Telegram Bot token</a> for your bot and write it down.</p>
|
||||
<p>Now open a Linux/Unix terminal with bash, create a new directory, change to it and install telegram-bot-bash:</p>
|
||||
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="co"># create bot dir</span></span>
|
||||
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="fu">mkdir</span> mybot</span>
|
||||
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="bu">cd</span> mybot</span>
|
||||
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="co"># download latest release with wget or from https://github.com/topkecleon/telegram-bot-bash/releases/latest</span></span>
|
||||
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="fu">wget</span> <span class="st">"https://github.com/</span><span class="va">$(</span><span class="fu">wget</span> <span class="at">-q</span> <span class="st">"https://github.com/topkecleon/telegram-bot-bash/releases/latest"</span> <span class="at">-O</span> <span class="at">-</span> <span class="kw">|</span> <span class="fu">egrep</span> <span class="st">'/.*/download/.*/.*tar.gz'</span> <span class="at">-o</span><span class="va">)</span><span class="st">"</span></span>
|
||||
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="co"># Extract the tar archive and go into bot dir</span></span>
|
||||
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="fu">tar</span> <span class="at">-xzf</span> <span class="pp">*</span>.tar.gz</span>
|
||||
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="bu">cd</span> telegram-bot-bash</span>
|
||||
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="co"># initialize your bot</span></span>
|
||||
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="co"># Enter your bot token when asked, all other questions can be answered by hitting the \<Return\> key.</span></span>
|
||||
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="ex">./bashbot.sh</span> init</span>
|
||||
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="co"># Now start your bot</span></span>
|
||||
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="ex">./bashbot.sh</span> start</span>
|
||||
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="ex">Bottoken</span> is valid ...</span>
|
||||
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a><span class="ex">Bot</span> Name: yourbotname_bot</span>
|
||||
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a><span class="ex">Session</span> Name: yourbotname_bot-startbot</span>
|
||||
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a><span class="ex">Bot</span> started successfully.</span></code></pre></div>
|
||||
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1"></a><span class="co"># create bot dir</span></span>
|
||||
<span id="cb1-2"><a href="#cb1-2"></a><span class="fu">mkdir</span> mybot</span>
|
||||
<span id="cb1-3"><a href="#cb1-3"></a><span class="bu">cd</span> mybot</span>
|
||||
<span id="cb1-4"><a href="#cb1-4"></a></span>
|
||||
<span id="cb1-5"><a href="#cb1-5"></a><span class="co"># download latest release with wget or from https://github.com/topkecleon/telegram-bot-bash/releases/latest</span></span>
|
||||
<span id="cb1-6"><a href="#cb1-6"></a><span class="fu">wget</span> <span class="st">"https://github.com/</span><span class="va">$(</span><span class="fu">wget</span> -q <span class="st">"https://github.com/topkecleon/telegram-bot-bash/releases/latest"</span> -O - <span class="kw">|</span> <span class="fu">egrep</span> <span class="st">'/.*/download/.*/.*tar.gz'</span> -o<span class="va">)</span><span class="st">"</span></span>
|
||||
<span id="cb1-7"><a href="#cb1-7"></a></span>
|
||||
<span id="cb1-8"><a href="#cb1-8"></a><span class="co"># Extract the tar archive and go into bot dir</span></span>
|
||||
<span id="cb1-9"><a href="#cb1-9"></a><span class="fu">tar</span> -xzf *.tar.gz</span>
|
||||
<span id="cb1-10"><a href="#cb1-10"></a><span class="bu">cd</span> telegram-bot-bash</span>
|
||||
<span id="cb1-11"><a href="#cb1-11"></a></span>
|
||||
<span id="cb1-12"><a href="#cb1-12"></a><span class="co"># initialize your bot</span></span>
|
||||
<span id="cb1-13"><a href="#cb1-13"></a><span class="co"># Enter your bot token when asked, all other questions can be answered by hitting the \<Return\> key.</span></span>
|
||||
<span id="cb1-14"><a href="#cb1-14"></a><span class="ex">./bashbot.sh</span> init</span>
|
||||
<span id="cb1-15"><a href="#cb1-15"></a></span>
|
||||
<span id="cb1-16"><a href="#cb1-16"></a><span class="co"># Now start your bot</span></span>
|
||||
<span id="cb1-17"><a href="#cb1-17"></a><span class="ex">./bashbot.sh</span> start</span>
|
||||
<span id="cb1-18"><a href="#cb1-18"></a></span>
|
||||
<span id="cb1-19"><a href="#cb1-19"></a><span class="ex">Bottoken</span> is valid ...</span>
|
||||
<span id="cb1-20"><a href="#cb1-20"></a><span class="ex">Bot</span> Name: yourbotname_bot</span>
|
||||
<span id="cb1-21"><a href="#cb1-21"></a><span class="ex">Session</span> Name: yourbotname_bot-startbot</span>
|
||||
<span id="cb1-22"><a href="#cb1-22"></a><span class="ex">Bot</span> started successfully.</span></code></pre></div>
|
||||
<p>Now open the Telegram App on your mobile phone and start a chat with your bot (<em>your bot's username is shown after 'Bot Name:'</em>):</p>
|
||||
<pre><code>/start
|
||||
|
||||
|
@ -324,7 +194,8 @@ Available commands:
|
|||
/info
|
||||
|
||||
This is bashbot, the Telegram bot written entirely in bash.
|
||||
It features background tasks and interactive chats, and can serve as an interface for CLI programs.</code></pre>
|
||||
It features background tasks and interactive chats, and can serve as an interface for CLI programs.
|
||||
</code></pre>
|
||||
<p>For more Information on how to install, customize and use your new bot, read the <a href="#Documentation">Documentation</a>.</p>
|
||||
<h3>Log files</h3>
|
||||
<p>Bashbot actions are logged to <code>BASHBOT.log</code>. Telegram send/receive errors are logged to <code>ERROR.log</code>. Start bashbot in debug mode to see all messages sent to / received from Telegram, as well as bash command error messages.</p>
|
||||
|
@ -334,13 +205,14 @@ It features background tasks and interactive chats, and can serve as an interfac
|
|||
| |__ ERROR.log # connection errors from / to Telegram API
|
||||
| |
|
||||
| |__ DEBUG.log # stdout/stderr of you bot (debug mode enabled)
|
||||
| |__ MESSAGE.log # full text of all message send/received (debug mode enabled)</code></pre>
|
||||
| |__ MESSAGE.log # full text of all message send/received (debug mode enabled)
|
||||
</code></pre>
|
||||
<hr />
|
||||
<h2>Security Considerations</h2>
|
||||
<p>Running a Telegram Bot means it is connected to the public and you never know what's send to your Bot.</p>
|
||||
<p>Bash scripts in general are not designed to be bulletproof, so consider this Bot as a proof of concept. Bash programmers often struggle with 'quoting hell' and globbing, see <a href="https://unix.stackexchange.com/questions/171346/security-implications-of-forgetting-to-quote-a-variable-in-bash-posix-shells">Implications of wrong quoting</a>.</p>
|
||||
<p>Whenever you are processing input from untrusted sources (messages, files, network) you must be as careful as possible (e.g. set IFS appropriately, disable globbing with <code>set -f</code> and quote everything). In addition remove unused scripts and examples from your Bot (e.g. everything in <code>example/</code>) and disable/remove all unused bot commands.</p>
|
||||
<p>It's important to escape or remove <code>$</code> in input from user, files or network (<em>as bashbot does</em>). One of the powerful features of Unix shells is variable and command substitution using <code>${}</code> and<code>$()</code> can lead to remote code execution (RCE) or remote information disclosure (RID) bugs if unescaped <code>$</code> is included in untrusted input (e.g. <code>$$</code> or <code>$(rm -rf /*)</code>).</p>
|
||||
<p>It's important to escape or remove <code>$</code> and ` in input from user, files or network (<em>as bashbot does</em>). One of the powerful features of Unix shells is variable and command substitution using <code>${var}</code>, <code>$(cmd)</code> and `cmd` can lead to remote code execution (RCE) or remote information disclosure (RID) bugs if unescaped <code>$</code> or ` is included in untrusted input (e.g. <code>$$</code> or <code>$(rm -rf /*)</code>).</p>
|
||||
<p>A powerful tool to improve your scripts is <code>shellcheck</code>. You can <a href="https://www.shellcheck.net/">use it online</a> or <a href="https://github.com/koalaman/shellcheck#installing">install shellcheck locally</a>. Shellcheck is used extensively in bashbot development to ensure a high code quality (e.g. it's not allowed to push changes without passing all shellcheck tests). In addition bashbot has a <a href="doc/7_develop.md">test suite</a> to check if important functionality is working as expected.</p>
|
||||
<h3>Use printf whenever possible</h3>
|
||||
<p>If you're writing a script that accepts external input (e.g. from the user as arguments or the file system), you shouldn't use echo to display it. <a href="https://unix.stackexchange.com/a/6581">Use printf whenever possible</a>.</p>
|
||||
|
@ -349,8 +221,9 @@ It features background tasks and interactive chats, and can serve as an interfac
|
|||
<p><strong>Never run your Bot as root, this is the most dangerous you can do!</strong> Usually the user 'nobody' has almost no rights on Linux/Unix systems. See <a href="doc/4_expert.md">Expert use</a> on how to run your Bot as an other user.</p>
|
||||
<h3>Secure your Bot installation</h3>
|
||||
<p><strong>Your Bot configuration must not be readable by other users.</strong> Everyone who can read your Bots token is able to act as your Bot and has access to all chats the Bot is in!</p>
|
||||
<p>Everyone with read access to your Bot files can extract your Bots data. Especially your Bot config in<code>config.jssh</code> must be protected against other users. No one except you should have write access to the Bot files. The Bot should be restricted to have write access to<code>count.jssh</code> and <code>data-bot-bash</code> only, all other files must be write protected.</p>
|
||||
<p>To set access rights for your bashbot installation to a reasonable default run<code>sudo ./bashbot.sh init</code> after every update or change to your installation directory.</p>
|
||||
<p>Everyone with read access to your Bot files can extract your Bots data. Especially your Bot config in <code>config.jssh</code> must be protected against other users. No one except you should have write access to the Bot files. The Bot should be restricted to have write access to <code>count.jssh</code>, <code>data-bot-bash/</code> and <code>logs/</code> only, all other files must be write protected.</p>
|
||||
<p>To set access rights for your bashbot installation to a reasonable default run <code>sudo ./bashbot.sh init</code> after every update or change to your installation directory.</p>
|
||||
<p><em>Note</em>: Keep old log files in a safe place or even better delete them, they are GDPR relevant and <a href="https://github.com/topkecleon/telegram-bot-bash/issues/174">may contain information</a> you don't want to be public.</p>
|
||||
<h2>FAQ</h2>
|
||||
<h3>Is this Bot insecure?</h3>
|
||||
<p>Bashbot is not more (in)secure than a Bot written in another language. We have done our best to make it as secure as possible. But YOU are responsible for the bot commands you wrote and you should know about the risks ...</p>
|
||||
|
@ -364,32 +237,32 @@ It features background tasks and interactive chats, and can serve as an interfac
|
|||
<li>no database, not event driven, not object oriented ...</li>
|
||||
</ul>
|
||||
<h3>Can I have the single bashbot.sh file back?</h3>
|
||||
<p>At the beginning bashbot was simply the file<code>bashbot.sh</code> that you could copy everywhere and run the bot. Now we have 'commands.sh', 'mycommands.sh', 'modules/*.sh' and much more.</p>
|
||||
<p>Hey no problem, if you are finished with your cool bot, run<code>dev/make-standalone.sh</code> to create a stripped down version of your bot containing only 'bashbot.sh' and 'commands.sh'! For more information see <a href="doc/7_develop.md">Create a stripped down version of your Bot</a>.</p>
|
||||
<p>At the beginning bashbot was simply the file <code>bashbot.sh</code> that you could copy everywhere and run the bot. Now we have 'commands.sh', 'mycommands.sh', 'modules/*.sh' and much more.</p>
|
||||
<p>Hey no problem, if you are finished with your cool bot, run <code>dev/make-standalone.sh</code> to create a stripped down version of your bot containing only 'bashbot.sh' and 'commands.sh'! For more information see <a href="doc/7_develop.md">Create a stripped down version of your Bot</a>.</p>
|
||||
<h3>Can I send messages from CLI and scripts?</h3>
|
||||
<p>Of course you can send messages from command line and scripts! Simply install bashbot as <a href="#Your-really-first-bashbot-in-a-nutshell">described here</a>, send the message '/start' to set yourself as botadmin and then stop the bot with <code>./bashbot.sh stop</code>.</p>
|
||||
<p>Bashbot provides some ready to use scripts for sending messages from command line in <code>bin/</code> dir, e.g. <code>send_message.sh</code>.</p>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">bin/send_message.sh</span> BOTADMIN <span class="st">"This is my first message send from CLI"</span></span>
|
||||
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="ex">bin/send_message.sh</span> <span class="at">--help</span></span></code></pre></div>
|
||||
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1"></a><span class="ex">bin/send_message.sh</span> BOTADMIN <span class="st">"This is my first message send from CLI"</span></span>
|
||||
<span id="cb4-2"><a href="#cb4-2"></a></span>
|
||||
<span id="cb4-3"><a href="#cb4-3"></a><span class="ex">bin/send_message.sh</span> --help</span></code></pre></div>
|
||||
<p>You can also source bashbot for use in your scripts, for more information see <a href="doc/4_expert.md">Expert Use</a>.</p>
|
||||
<h3>Blocked by telegram?</h3>
|
||||
<p>This may happen if too many or wrong requests are sent to api.telegram.org, e.g. using a invalid token or invalid API calls. If the block stay for longer time you can ask telegram service to unblock your IP-Address.</p>
|
||||
<p>You can check with curl or wget if you are blocked by Telegram:</p>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">curl</span> <span class="at">-m</span> 10 https://api.telegram.org/bot</span>
|
||||
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="co">#curl: (28) Connection timed out after 10001 milliseconds</span></span>
|
||||
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="fu">wget</span> <span class="at">-t</span> 1 <span class="at">-T</span> 10 https://api.telegram.org/bot</span>
|
||||
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="co">#Connecting to api.telegram.org (api.telegram.org)|46.38.243.234|:443... failed: Connection timed out.</span></span>
|
||||
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="ex">nc</span> <span class="at">-w</span> 2 api.telegram.org 443 <span class="kw">||</span> <span class="bu">echo</span> <span class="st">"your IP seems blocked by telegram"</span></span>
|
||||
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a><span class="co">#your IP seems blocked by telegram</span></span></code></pre></div>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1"></a><span class="ex">curl</span> -m 10 https://api.telegram.org/bot</span>
|
||||
<span id="cb5-2"><a href="#cb5-2"></a><span class="co">#curl: (28) Connection timed out after 10001 milliseconds</span></span>
|
||||
<span id="cb5-3"><a href="#cb5-3"></a></span>
|
||||
<span id="cb5-4"><a href="#cb5-4"></a><span class="fu">wget</span> -t 1 -T 10 https://api.telegram.org/bot</span>
|
||||
<span id="cb5-5"><a href="#cb5-5"></a><span class="co">#Connecting to api.telegram.org (api.telegram.org)|46.38.243.234|:443... failed: Connection timed out.</span></span>
|
||||
<span id="cb5-6"><a href="#cb5-6"></a></span>
|
||||
<span id="cb5-7"><a href="#cb5-7"></a><span class="ex">nc</span> -w 2 api.telegram.org 443 <span class="kw">||</span> <span class="bu">echo</span> <span class="st">"your IP seems blocked by telegram"</span></span>
|
||||
<span id="cb5-8"><a href="#cb5-8"></a><span class="co">#your IP seems blocked by telegram</span></span></code></pre></div>
|
||||
<p>Bashbot offers the option to recover from broken connections (blocked). Therefore you can provide a function named <code>bashbotBlockRecover()</code> in <code>mycommands.sh</code>, the function is called every time when a broken connection is detected.</p>
|
||||
<p>Possible actions are: Check if network is working, change IP-Address or simply wait some time. See <code>mycommnds.sh.dist</code> for an example.</p>
|
||||
<hr />
|
||||
<p>@Gnadelwartz</p>
|
||||
<h2>That's it all guys!</h2>
|
||||
<p>If you feel that there's something missing or if you found a bug, feel free to submit a pull request!</p>
|
||||
<h4>$$VERSION$$ v1.30-0-g3266427</h4>
|
||||
<h4>$$VERSION$$ v1.52-0-g1a83202</h4>
|
||||
</body>
|
||||
</html>
|
||||
|
|
32
README.md
32
README.md
|
@ -10,11 +10,19 @@ Elsewhere, consider it released under the [WTFPLv2](http://www.wtfpl.net/txt/cop
|
|||
|
||||
Linted by [#ShellCheck](https://github.com/koalaman/shellcheck)
|
||||
|
||||
---
|
||||
**Bashbot** is created by old-fashioned shell hackers to show that it's possible to write a bot in Bash.
|
||||
|
||||
It is designed for **simple** use cases and easily integrates with Linux tasks.
|
||||
For bots that serve a lot of users or a heavy workload, I strongly recommend using a dedicated bot framework.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
Uses [JSON.sh](http://github.com/dominictarr/JSON.sh) and the magic of sed.
|
||||
Uses [JSON.sh](http://github.com/dominictarr/JSON.sh)/[JSON.awk](https://github.com/step-/JSON.awk) and the magic of sed.
|
||||
|
||||
Bashbot is written in bash. It depends on commands typically available in a Linux/Unix Environment.
|
||||
For more concrete information on the common commands provided by recent versions of [coreutils](https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands), [busybox](https://en.wikipedia.org/wiki/BusyBox#Commands) or [toybox](https://landley.net/toybox/help.html), see [Developer Notes](doc/7_develop.md#common-commands).
|
||||
For more information on commands provided by recent versions of [coreutils](https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands), [busybox](https://en.wikipedia.org/wiki/BusyBox#Commands) or [toybox](https://landley.net/toybox/help.html), see [Developer Notes](doc/7_develop.md#common-commands).
|
||||
|
||||
**Note for MacOS and BSD Users:** Bashbot will not run without installing additional software as it uses modern bash and (gnu) grep/sed features. See [Install Bashbot](doc/0_install.md).
|
||||
|
||||
|
@ -63,7 +71,8 @@ Bashbot [Documentation](https://github.com/topkecleon/telegram-bot-bash) and [Do
|
|||
* Modules, addons, events
|
||||
* Setup your environment
|
||||
* Bashbot test suite
|
||||
* [Examples Directory](examples/README.md)
|
||||
* [Examples Directory](examples)
|
||||
* [Webhook Example](examples/webhook)
|
||||
|
||||
### Your very first bashbot in a nutshell
|
||||
|
||||
|
@ -145,8 +154,9 @@ Whenever you are processing input from untrusted sources (messages, files, netwo
|
|||
(e.g. set IFS appropriately, disable globbing with `set -f` and quote everything). In addition remove unused scripts and examples
|
||||
from your Bot (e.g. everything in `example/`) and disable/remove all unused bot commands.
|
||||
|
||||
It's important to escape or remove `$` in input from user, files or network (_as bashbot does_).
|
||||
One of the powerful features of Unix shells is variable and command substitution using `${}` and`$()` can lead to remote code execution (RCE) or remote information disclosure (RID) bugs if unescaped `$` is included in untrusted input (e.g. `$$` or `$(rm -rf /*)`).
|
||||
It's important to escape or remove `$` and \` in input from user, files or network (_as bashbot does_).
|
||||
One of the powerful features of Unix shells is variable and command substitution using `${var}`, `$(cmd)` and \`cmd\` can lead to remote
|
||||
code execution (RCE) or remote information disclosure (RID) bugs if unescaped `$` or \` is included in untrusted input (e.g. `$$` or `$(rm -rf /*)`).
|
||||
|
||||
A powerful tool to improve your scripts is `shellcheck`. You can [use it online](https://www.shellcheck.net/) or
|
||||
[install shellcheck locally](https://github.com/koalaman/shellcheck#installing). Shellcheck is used extensively in bashbot development
|
||||
|
@ -168,9 +178,11 @@ For the same reason every file your Bot can read is in danger of being disclosed
|
|||
### Secure your Bot installation
|
||||
**Your Bot configuration must not be readable by other users.** Everyone who can read your Bots token is able to act as your Bot and has access to all chats the Bot is in!
|
||||
|
||||
Everyone with read access to your Bot files can extract your Bots data. Especially your Bot config in`config.jssh` must be protected against other users. No one except you should have write access to the Bot files. The Bot should be restricted to have write access to`count.jssh` and `data-bot-bash` only, all other files must be write protected.
|
||||
Everyone with read access to your Bot files can extract your Bots data. Especially your Bot config in `config.jssh` must be protected against other users. No one except you should have write access to the Bot files. The Bot should be restricted to have write access to `count.jssh`, `data-bot-bash/` and `logs/` only, all other files must be write protected.
|
||||
|
||||
To set access rights for your bashbot installation to a reasonable default run`sudo ./bashbot.sh init` after every update or change to your installation directory.
|
||||
To set access rights for your bashbot installation to a reasonable default run `sudo ./bashbot.sh init` after every update or change to your installation directory.
|
||||
|
||||
*Note*: Keep old log files in a safe place or even better delete them, they are GDPR relevant and [may contain information](https://github.com/topkecleon/telegram-bot-bash/issues/174) you don't want to be public.
|
||||
|
||||
## FAQ
|
||||
|
||||
|
@ -188,9 +200,9 @@ Well, that's a damn good question... maybe because I'm a Unix admin from the sto
|
|||
- no database, not event driven, not object oriented ...
|
||||
|
||||
### Can I have the single bashbot.sh file back?
|
||||
At the beginning bashbot was simply the file`bashbot.sh` that you could copy everywhere and run the bot. Now we have 'commands.sh', 'mycommands.sh', 'modules/*.sh' and much more.
|
||||
At the beginning bashbot was simply the file `bashbot.sh` that you could copy everywhere and run the bot. Now we have 'commands.sh', 'mycommands.sh', 'modules/*.sh' and much more.
|
||||
|
||||
Hey no problem, if you are finished with your cool bot, run`dev/make-standalone.sh` to create a stripped down version of your bot containing only
|
||||
Hey no problem, if you are finished with your cool bot, run `dev/make-standalone.sh` to create a stripped down version of your bot containing only
|
||||
'bashbot.sh' and 'commands.sh'! For more information see [Create a stripped down version of your Bot](doc/7_develop.md).
|
||||
|
||||
### Can I send messages from CLI and scripts?
|
||||
|
@ -238,4 +250,4 @@ See `mycommnds.sh.dist` for an example.
|
|||
|
||||
If you feel that there's something missing or if you found a bug, feel free to submit a pull request!
|
||||
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
|
56
README.txt
56
README.txt
|
@ -39,18 +39,21 @@ Linted by #ShellCheck
|
|||
|
||||
Prerequisites
|
||||
|
||||
Uses JSON.sh [http://github.com/dominictarr/JSON.sh] and the magic of sed.
|
||||
Uses JSON.sh [http://github.com/dominictarr/JSON.sh]/JSON.awk [https://github.com/step-/
|
||||
JSON.awk] and the magic of sed.
|
||||
Bashbot is written in bash. It depends on commands typically available in a Linux/Unix
|
||||
Environment. For more concrete information on the common commands provided by recent
|
||||
versions of coreutils [https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands],
|
||||
busybox or toybox, see Developer_Notes.
|
||||
Environment. For more information on commands provided by recent versions of coreutils
|
||||
[https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands], busybox [https://
|
||||
en.wikipedia.org/wiki/BusyBox#Commands] or toybox [https://landley.net/toybox/help.html],
|
||||
see Developer Notes [doc/7_develop.md#common-commands].
|
||||
Note for MacOS and BSD Users: Bashbot will not run without installing additional software
|
||||
as it uses modern bash and (gnu) grep/sed features. See Install Bashbot [doc/
|
||||
0_install.md].
|
||||
Note for embedded systems: You need to install a "real" bash as the vanilla installation
|
||||
of busybox or toybox is not sufficient. See Install Bashbot [doc/0_install.md].
|
||||
Bashbot Documentation [https://github.com/topkecleon/telegram-bot-bash] and Downloads are
|
||||
available on www.github.com.
|
||||
Bashbot Documentation [https://github.com/topkecleon/telegram-bot-bash] and Downloads
|
||||
[https://github.com/topkecleon/telegram-bot-bash/releases] are available on www.github.com
|
||||
[https://www.github.com].
|
||||
|
||||
Documentation
|
||||
|
||||
|
@ -109,13 +112,15 @@ Documentation
|
|||
o Setup your environment
|
||||
o Bashbot test suite
|
||||
|
||||
* Examples Directory [examples/README.md]
|
||||
* Examples Directory [examples]
|
||||
* Webhook Example [examples/webhook]
|
||||
|
||||
|
||||
Your very first bashbot in a nutshell
|
||||
|
||||
To install and run bashbot you need access to a Linux/Unix command line with bash, a
|
||||
Telegram client [https://telegram.org] and a mobile phone with_a_Telegram_account.
|
||||
Telegram client [https://telegram.org] and a mobile phone with a Telegram account [https:/
|
||||
/telegramguide.com/create-a-telegram-account/].
|
||||
First you need to create a new Telegram Bot token [doc/1_firstbot.md] for your bot and
|
||||
write it down.
|
||||
Now open a Linux/Unix terminal with bash, create a new directory, change to it and install
|
||||
|
@ -195,15 +200,17 @@ Whenever you are processing input from untrusted sources (messages, files, netwo
|
|||
must be as careful as possible (e.g. set IFS appropriately, disable globbing with set -
|
||||
f and quote everything). In addition remove unused scripts and examples from your Bot
|
||||
(e.g. everything in example/) and disable/remove all unused bot commands.
|
||||
It's important to escape or remove $ in input from user, files or network (as bashbot
|
||||
does). One of the powerful features of Unix shells is variable and command substitution
|
||||
using ${} and$() can lead to remote code execution (RCE) or remote information disclosure
|
||||
(RID) bugs if unescaped $ is included in untrusted input (e.g. $$ or $(rm -rf /*)).
|
||||
It's important to escape or remove $ and ` in input from user, files or network (as
|
||||
bashbot does). One of the powerful features of Unix shells is variable and command
|
||||
substitution using ${var}, $(cmd) and `cmd` can lead to remote code execution (RCE) or
|
||||
remote information disclosure (RID) bugs if unescaped $ or ` is included in untrusted
|
||||
input (e.g. $$ or $(rm -rf /*)).
|
||||
A powerful tool to improve your scripts is shellcheck. You can use it online [https://
|
||||
www.shellcheck.net/] or install_shellcheck_locally. Shellcheck is used extensively in
|
||||
bashbot development to ensure a high code quality (e.g. it's not allowed to push changes
|
||||
without passing all shellcheck tests). In addition bashbot has a test_suite to check if
|
||||
important functionality is working as expected.
|
||||
www.shellcheck.net/] or install shellcheck locally [https://github.com/koalaman/
|
||||
shellcheck#installing]. Shellcheck is used extensively in bashbot development to ensure a
|
||||
high code quality (e.g. it's not allowed to push changes without passing all shellcheck
|
||||
tests). In addition bashbot has a test suite [doc/7_develop.md] to check if important
|
||||
functionality is working as expected.
|
||||
|
||||
Use printf whenever possible
|
||||
|
||||
|
@ -226,11 +233,14 @@ Secure your Bot installation
|
|||
Your Bot configuration must not be readable by other users. Everyone who can read your
|
||||
Bots token is able to act as your Bot and has access to all chats the Bot is in!
|
||||
Everyone with read access to your Bot files can extract your Bots data. Especially your
|
||||
Bot config inconfig.jssh must be protected against other users. No one except you should
|
||||
have write access to the Bot files. The Bot should be restricted to have write access
|
||||
tocount.jssh and data-bot-bash only, all other files must be write protected.
|
||||
To set access rights for your bashbot installation to a reasonable default runsudo ./
|
||||
Bot config in config.jssh must be protected against other users. No one except you should
|
||||
have write access to the Bot files. The Bot should be restricted to have write access to
|
||||
count.jssh, data-bot-bash/ and logs/ only, all other files must be write protected.
|
||||
To set access rights for your bashbot installation to a reasonable default run sudo ./
|
||||
bashbot.sh init after every update or change to your installation directory.
|
||||
Note: Keep old log files in a safe place or even better delete them, they are GDPR
|
||||
relevant and may contain information [https://github.com/topkecleon/telegram-bot-bash/
|
||||
issues/174] you don't want to be public.
|
||||
|
||||
FAQ
|
||||
|
||||
|
@ -258,9 +268,9 @@ Nevertheless there are more reasons from my side:
|
|||
|
||||
Can I have the single bashbot.sh file back?
|
||||
|
||||
At the beginning bashbot was simply the filebashbot.sh that you could copy everywhere and
|
||||
At the beginning bashbot was simply the file bashbot.sh that you could copy everywhere and
|
||||
run the bot. Now we have 'commands.sh', 'mycommands.sh', 'modules/*.sh' and much more.
|
||||
Hey no problem, if you are finished with your cool bot, rundev/make-standalone.sh to
|
||||
Hey no problem, if you are finished with your cool bot, run dev/make-standalone.sh to
|
||||
create a stripped down version of your bot containing only 'bashbot.sh' and 'commands.sh'!
|
||||
For more information see Create a stripped down version of your Bot [doc/7_develop.md].
|
||||
|
||||
|
@ -309,5 +319,5 @@ That's it all guys!
|
|||
If you feel that there's something missing or if you found a bug, feel free to submit a
|
||||
pull request!
|
||||
|
||||
$$VERSION$$ v1.30-0-g3266427
|
||||
$$VERSION$$ v1.52-0-g1a83202
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# this addon counts how many files, e.g. stickers, are sent to
|
||||
# a chat and takes actions if threshold is reached
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
# used events:
|
||||
#
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# Addons can register to bashbot events at startup
|
||||
# by providing their name and a callback per event
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#
|
||||
# If an event occurs each registered event function is called.
|
||||
#
|
||||
|
|
97
bashbot.rc
97
bashbot.rc
|
@ -1,13 +1,14 @@
|
|||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
# description: Start or stop telegram-bash-bot
|
||||
#
|
||||
# example service script to run bashbot in background as specified user
|
||||
#
|
||||
# tested on: ubuntu, opensuse, debian
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
# shellcheck disable=SC2009
|
||||
# shellcheck disable=SC2181
|
||||
# shellcheck disable=SC2250
|
||||
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
|
@ -31,53 +32,112 @@ runas="nobody"
|
|||
|
||||
# uncomment one of the example lines to fit your system
|
||||
# runcmd="su ${runas} -s /bin/bash -c " # runasuser with *su*
|
||||
# runcmd="runuser ${runas} -s /bin/bash -c " # runasuser with *runuser*
|
||||
# runcmd="/usr/sbin/runuser ${runas} -s /bin/bash -c " # runasuser with *runuser*
|
||||
|
||||
# edit the values of the following lines to fit your config:
|
||||
# your bot installation dir
|
||||
bashbot="cd /usr/local/telegram-bot-bash; /usr/local/telegram-bot-bash/bashbot.sh"
|
||||
# your bot name as given to botfather, e.g. mysomething_bot
|
||||
name=""
|
||||
[ -z "${name}" ] && name="unknown"
|
||||
|
||||
# your bot installation dir
|
||||
bashbotdir="/usr/local/telegram-bot-bash"
|
||||
databotdir="${bashbotdir}/data-bot-bash"
|
||||
FIFO="${databotdir}/webhook-fifo-${name}"
|
||||
|
||||
# programs to run
|
||||
bashbot="cd ${bashbotdir}; ${bashbotdir}/bashbot.sh"
|
||||
webhook="cd ${bashbotdir}; nohup ${bashbotdir}/bin/process_batch.sh --startbot --watch ${FIFO}"
|
||||
# set additionl parameter, e.g. debug
|
||||
mode=""
|
||||
|
||||
# select logfile for webhook start stop and script errors
|
||||
hooklog="DEBUG"
|
||||
hooklog="WEBHOOK"
|
||||
|
||||
# END Configuration
|
||||
#######################
|
||||
|
||||
[ "${name}" = "" ] && name="${runas}"
|
||||
|
||||
# check for bot status
|
||||
stat=""
|
||||
ps -f -u "${runas}" | grep "${name}" | grep -qF "bashbot.sh startbot"
|
||||
if [ "$?" = "0" ]; then
|
||||
# printf "bashbot (%s) is running in poll mode\n" "${name}"
|
||||
stat="${stat} polling"
|
||||
fi
|
||||
ps -f -u "${runas}" | grep "${name}" | grep -qF "process_batch.sh --startbot"
|
||||
if [ "$?" = "0" ]; then
|
||||
#printf "bashbot (%s) is running in webhook mode\n" "${name}"
|
||||
stat="${stat} webhook"
|
||||
elif [ "${name}" != "unknown" ]; then
|
||||
#printf "bashbot (%s) is stopped\n" "${name}"
|
||||
stat="stop"
|
||||
else
|
||||
stat="unknown"
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
'start')
|
||||
# shellcheck disable=SC2250
|
||||
[ "${stat}" != "stop" ] && printf "Warning, bot is already running in mode: %s\n" "${stat}"
|
||||
$runcmd "$bashbot start $mode" # >/dev/null 2>&1 </dev/null
|
||||
RETVAL=$?
|
||||
;;
|
||||
'starthook')
|
||||
[ -p "${FIFO}" ] || printf "Warning, webhook pipe not found: %s\n" "${FIFO##*/}"
|
||||
[ "${stat}" != "stop" ] && printf "Warning, bot is already running in mode: %s\n" "${stat}"
|
||||
printf "Starting bashbot in webhook mode ... "
|
||||
$runcmd "$webhook $mode </dev/null &>>${bashbotdir}/logs/${hooklog}.log &" # >/dev/null 2>&1 </dev/null
|
||||
sleep 1
|
||||
$0 status
|
||||
RETVAL=$?
|
||||
;;
|
||||
'stop')
|
||||
# shellcheck disable=SC2250
|
||||
[[ "${stat}" != *"poll"* ]] && printf "Warning, bot is not in poll mode: %s\n" "${stat}"
|
||||
$runcmd "$bashbot stop $mode"
|
||||
RETVAL=$?
|
||||
;;
|
||||
'status')
|
||||
ps -f -u "${runas}" | grep "${name}" | grep -qF "bashbot.sh startbot"
|
||||
if [ "$?" = "0" ]; then
|
||||
printf "bashbot (%s) is running\n" "${name}"
|
||||
RETVAL=0
|
||||
else
|
||||
printf "bashbot (%s) is stopped\n" "${name}"
|
||||
RETVAL=1
|
||||
'stophook')
|
||||
[[ "${stat}" != *"hook"* ]] && printf "Warning, bot is not in webhook mode: %s\n" "${stat}"
|
||||
printf "Stopping bashbot webhook mode ... "
|
||||
KILLID="$(ps -f -u "${runas}" | grep "process_batch.sh --startbot" | sed -E 's/[^0-9]+([0-9]+).*/\1/' | tr -s "\r\n" " ")"
|
||||
if [ -n "${KILLID}" ]; then
|
||||
$runcmd "kill ${KILLID} 2>/dev/null; wait ${KILLID} 2>/dev/null"
|
||||
sleep 1
|
||||
fi
|
||||
RETVAL=$?
|
||||
$0 status
|
||||
;;
|
||||
'status')
|
||||
case "${stat}" in
|
||||
*"poll"*) printf "bashbot (%s) is running in polling mode\n" "${name}"
|
||||
RETVAL=0
|
||||
;;&
|
||||
*"hook"*) printf "bashbot (%s) is running in webhook mode\n" "${name}"
|
||||
RETVAL=0
|
||||
;;
|
||||
*"stop"*) printf "bashbot (%s) is not running\n" "${name}"
|
||||
RETVAL=1
|
||||
;;
|
||||
*) printf "bashbot (%s) status is %s\n" "${name}" "${stat}"
|
||||
RETVAL=2
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
'restart'|'reload')
|
||||
$0 stop; $0 start
|
||||
RETVAL=$?
|
||||
;;
|
||||
'restarthook'|'reloadhook')
|
||||
$0 stophook; $0 starthook
|
||||
RETVAL=$?
|
||||
;;
|
||||
'restartback')
|
||||
$0 suspendback; $0 resumeback
|
||||
RETVAL=$?
|
||||
;;
|
||||
'suspendback'|'resumeback'|'killback')
|
||||
# shellcheck disable=SC2250
|
||||
$runcmd "$bashbot $1 $mode"
|
||||
$runcmd "$bashbot $1"
|
||||
RETVAL=$?
|
||||
# kill inotifywait from runuser
|
||||
if [ "$1" != "resumeback" ]; then
|
||||
|
@ -86,7 +146,8 @@ case "$1" in
|
|||
fi
|
||||
;;
|
||||
*)
|
||||
printf "%s\n" "Usage: $0 { start | stop | restart | reload | restartback | suspendback | resumeback | killback }"
|
||||
printf "%s\n" "Usage: $0 [ start | stop | restart | starthook | stophook | restarthook ]"
|
||||
printf "%s\n" " $0 [ status | restartback | suspendback | resumeback | killback ]"
|
||||
RETVAL=1
|
||||
;;
|
||||
esac
|
||||
|
|
768
bashbot.sh
768
bashbot.sh
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,85 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC1090,SC2034,SC2059
|
||||
#===============================================================================
|
||||
#
|
||||
# FILE: bin/any_command.sh
|
||||
#
|
||||
USAGE='any_command.sh [-h|--help] [--force|--reference] bot_command args ...'
|
||||
#
|
||||
# DESCRIPTION: execute (almost) any bashbot command/function
|
||||
# can be used for testing commands while bot development
|
||||
#
|
||||
# OPTIONS: -- force - execute unknown commands/functions
|
||||
# by default only commands in 6_reference.md are allowed
|
||||
#
|
||||
# -h - display short help
|
||||
# --help - this help
|
||||
#
|
||||
# Set BASHBOT_HOME to your installation directory
|
||||
#
|
||||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 30.01.2021 10:24
|
||||
#
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
# parse args
|
||||
COMMAND=""
|
||||
|
||||
# set bashbot environment
|
||||
source "${0%/*}/bashbot_env.inc.sh" "debug" # debug
|
||||
print_help "$1"
|
||||
|
||||
|
||||
error=""
|
||||
# check options
|
||||
if [[ "$1" = "--force" ]]; then
|
||||
# skip checks
|
||||
shift
|
||||
else
|
||||
# check for --ref
|
||||
ref="$1"; [[ "$1" == "--ref"* ]] && shift
|
||||
if [ "${#1}" -lt 11 ];then
|
||||
printf "${RED}Command must be minimum 11 characters!${NC}\n"
|
||||
error=3
|
||||
fi
|
||||
if [[ "$1" != *"_"* ]];then
|
||||
printf "${RED}Command must contain _ (underscore)!${NC}\n"
|
||||
error=3
|
||||
fi
|
||||
# simple hack to get allowed commands from doc
|
||||
if grep -q "^##### $1" <<<"$(sed -n -e '/^##### _is_/,$ d' -e '/^##### /p' "${BASHBOT_HOME:-..}doc/"6_*)"; then
|
||||
# oiutput reference and exit
|
||||
if [[ "${ref}" == "--ref"* ]]; then
|
||||
sed -n -e '/^##### '"$1"'/,/^##/ p' "${BASHBOT_HOME:-..}doc/"6_*
|
||||
exit
|
||||
fi
|
||||
else
|
||||
printf "Command ${GREY}%s${NC} not found in 6_reference.md, use ${GREY}--force${NC} to execute!\n" "$1"
|
||||
error=4
|
||||
fi
|
||||
[ -n "${error}" ] && exit "${error}"
|
||||
fi
|
||||
|
||||
|
||||
####
|
||||
# ready, do stuff here -----
|
||||
COMMAND="$1"
|
||||
if [ "$2" == "BOTADMIN" ]; then
|
||||
ARG1="${BOTADMIN}"
|
||||
else
|
||||
ARG1="$2"
|
||||
fi
|
||||
|
||||
# clear result and response
|
||||
BOTSENT=()
|
||||
UPD=()
|
||||
|
||||
# send message in selected format
|
||||
"${COMMAND}" "${ARG1}" "${@:3}"
|
||||
|
||||
# output result an telegram response
|
||||
print_result
|
||||
print_response
|
|
@ -13,16 +13,16 @@
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 18.12.2020 12:27
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
############
|
||||
# set where your bashbot lives
|
||||
export BASHBOT_HOME BASHBOT_ETC BASHBOT_VAR FILE_REGEX
|
||||
export BASHBOT_HOME BASHBOT_ETC BASHBOT_VAR FILE_REGEX ME
|
||||
|
||||
# default: one dir up
|
||||
BASHBOT_HOME="$(cd "${BASH_SOURCE[0]%/*}" >/dev/null 2>&1 && pwd)/../"
|
||||
[ "${BASHBOT_HOME}" = "/../" ] && BASHBOT_HOME="../"
|
||||
BASHBOT_HOME="$(cd "${BASH_SOURCE[0]%/*}/../" >/dev/null 2>&1 && pwd)"
|
||||
[ "${BASHBOT_HOME}" = "" ] && BASHBOT_HOME="../"
|
||||
|
||||
# set you own BASHBOT_HOME if different, e.g.
|
||||
# BASHBOT_HOME="/usr/local/telegram-bot-bash"
|
||||
|
@ -32,20 +32,21 @@ BASHBOT_ETC="${BASHBOT_HOME}"
|
|||
#####
|
||||
# if files are not readable, eviroment is wrong or bashbot is not initialized
|
||||
|
||||
# source bashbot
|
||||
# check for bashbot
|
||||
if [ ! -r "${BASHBOT_HOME}/bashbot.sh" ]; then
|
||||
printf "%s\n" "Bashbot.sh not found in \"${BASHBOT_HOME}\""
|
||||
exit 4
|
||||
fi
|
||||
|
||||
dev=" Are we in dev or did you forget to run init?"
|
||||
# check for botconfig.jssh readable
|
||||
if [ ! -r "${BASHBOT_ETC}/botconfig.jssh" ]; then
|
||||
printf "%s\n" "Bashbot config file in \"${BASHBOT_ETC}\" does not exist or is not readable."
|
||||
printf "%s\n" "Bashbot config file in \"${BASHBOT_ETC}\" does not exist or is not readable. ${dev}"
|
||||
exit 3
|
||||
fi
|
||||
# check for count.jssh readable
|
||||
if [ ! -r "${BASHBOT_VAR}/count.jssh" ]; then
|
||||
printf "%s\n" "Bashbot count file in \"${BASHBOT_VAR}\" does not exist or is not readable. Did you run bashbot init?"
|
||||
printf "%s\n" "Bashbot count file in \"${BASHBOT_VAR}\" does not exist or is not readable. ${dev}"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
|
@ -58,8 +59,33 @@ UPLOADDIR="${BASHBOT_VAR%/bin*}"
|
|||
FILE_REGEX="${UPLOADDIR}/.*"
|
||||
|
||||
# get and check ADMIN and NAME
|
||||
BOT_ADMIN="$(getConfigKey "botadmin")"
|
||||
BOT_NAME="$(getConfigKey "botname")"
|
||||
[[ -z "${BOT_ADMIN}" || "${BOT_ADMIN}" == "?" ]] && printf "%s\n" "${ORANGE}Warning: Botadmin not set, did you forget to sent command${NC} /start"
|
||||
[[ -z "${BOT_NAME}" ]] && printf "%s\n" "${ORANGE}Warning: Botname not set, did you ever run bashbot?"
|
||||
BOTNAME="$(getConfigKey "botname")"
|
||||
ME="${BOTNAME}"
|
||||
[[ -z "${BOTADMIN}" || "${BOTADMIN}" == "?" ]] && printf "%s\n" "${ORANGE}Warning: Botadmin not set, send bot command${NC} /start"
|
||||
[[ -z "${BOTNAME}" ]] && printf "%s\n" "${ORANGE}Warning: Botname not set, run bashbot.sh botname"
|
||||
|
||||
# default webhook pipe
|
||||
export WEBHOOK="${DATADIR}/webhook-fifo-${ME}"
|
||||
|
||||
|
||||
# output command result or Telegram response
|
||||
print_result() { jssh_printDB "BOTSENT" | sort -r; }
|
||||
print_response() { jssh_printDB "UPD"; }
|
||||
|
||||
# check and output help
|
||||
print_help() {
|
||||
case "$1" in
|
||||
'')
|
||||
printf "missing arguments\n"
|
||||
;&
|
||||
"-h"*)
|
||||
printf 'usage: %s\n' "${USAGE}"
|
||||
exit 1
|
||||
;;
|
||||
'--h'*)
|
||||
sed -n '/^#====/,/^#====/p' <"$0"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
#!/bin/bash
|
||||
#===============================================================================
|
||||
#
|
||||
# FILE: bashbot_init.inc.sh
|
||||
#
|
||||
# USAGE: source bashbot_init.inc.sh
|
||||
#
|
||||
# DESCRIPTION: extend / overwrite bashbot initialisation
|
||||
#
|
||||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 27.01.2021 13:42
|
||||
#
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
# shellcheck disable=SC2059
|
||||
|
||||
##########
|
||||
# commands to execute before bot_init() is called
|
||||
|
||||
|
||||
########
|
||||
# called after default init is finished
|
||||
my_init() {
|
||||
: # your init here
|
||||
}
|
||||
|
||||
|
||||
#########
|
||||
#
|
||||
# extended initialisation:
|
||||
#
|
||||
# - uograde old config
|
||||
# - backup of botconfig.jssh
|
||||
# - running bot as service or other user
|
||||
# - copy clean and dist files if not exist
|
||||
# - configure bot for INLINE CALLBACK MEONLY SILENCER
|
||||
#
|
||||
# delete from here to disable extended initialisation
|
||||
bot_init() {
|
||||
if [ -n "${BASHBOT_HOME}" ] && ! cd "${BASHBOT_HOME}"; then
|
||||
printf "Can't change to BASHBOT_HOME"
|
||||
exit 1
|
||||
fi
|
||||
local runuser chown touser botname DEBUG="$1"
|
||||
# upgrade from old version
|
||||
# currently no action
|
||||
printf "Check for Update actions ...\n"
|
||||
printf "Done.\n"
|
||||
# load addons on startup
|
||||
printf "Initialize modules and addons ...\n"
|
||||
for addons in "${ADDONDIR:-.}"/*.sh ; do
|
||||
# shellcheck source=./modules/aliases.sh
|
||||
[ -r "${addons}" ] && source "${addons}" "init" "${DEBUG}"
|
||||
done
|
||||
printf "Done.\n"
|
||||
# guess bashbot from botconfig.jssh owner:group
|
||||
[ -f "${BOTCONFIG}.jssh" ] && runuser="$(stat -c '%U' "${BOTCONFIG}.jssh"):$(stat -c '%G' "${BOTCONFIG}.jssh")"
|
||||
# empty or ":" use user running init, nobody for root
|
||||
if [ "${#runuser}" -lt 3 ]; then
|
||||
# shellcheck disable=SC2153
|
||||
runuser="${RUNUSER}"
|
||||
[ "${UID}" = "0" ] && runuser="nobody"
|
||||
fi
|
||||
printf "Enter User to run bashbot [${runuser}]: "
|
||||
read -r chown
|
||||
[ -z "${chown}" ] && chown="${runuser}"
|
||||
touser="${chown%:*}"
|
||||
# check user ...
|
||||
if ! id "${touser}" &>/dev/null; then
|
||||
printf "${RED}User \"${touser}\" does not exist!${NN}"
|
||||
exit 3
|
||||
elif [ "${UID}" != "0" ]; then
|
||||
# different user but not root ...
|
||||
printf "${ORANGE}You are not root, adjusting permissions may fail. Try \"sudo ./bashbot.sh init\"${NN}Press <CTRL+C> to stop or <Enter> to continue..." 1>&2
|
||||
[ -n "${INTERACTIVE}" ] && read -r runuser
|
||||
fi
|
||||
# check if mycommands exist
|
||||
if [[ ! -r "${BASHBOT_ETC:-.}/mycommands.sh" && -r ${BASHBOT_ETC:-.}/mycommands.sh.dist ]]; then
|
||||
printf "Mycommands.sh not found, copy ${GREY}<C>lean file, <E>xamples or <N>one${NC} to mycommands.sh? (c/e/N) N\b"
|
||||
read -r ANSWER
|
||||
[[ "${ANSWER}" =~ ^[cC] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.sh.clean" "${BASHBOT_ETC:-.}/mycommands.sh"
|
||||
[[ "${ANSWER}" =~ ^[eE] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.sh.dist" "${BASHBOT_ETC:-.}/mycommands.sh"
|
||||
# offer to copy config also
|
||||
if [ ! -r "${BASHBOT_ETC:-.}/mycommands.conf" ]; then
|
||||
printf "Mycommands config file not found, copy ${GREY}mycommands.conf.dist${NC} to mycommands.conf? (Y/n) Y\b"
|
||||
read -r ANSWER
|
||||
[[ "${ANSWER}" =~ ^[nN] ]] || cp -f "${BASHBOT_ETC:-.}/mycommands.conf.dist" "${BASHBOT_ETC:-.}/mycommands.conf"
|
||||
fi
|
||||
# adjust INLINE CALLBACK MEONLY SILENCER
|
||||
if [ -w "${BASHBOT_ETC:-.}/mycommands.conf" ]; then
|
||||
printf "Activate processing for ${GREY}<I>nline queries, <C>allback buttons, <B>oth or <N>one${NC} in mycommands.sh? (i/c/b/N) N\b"
|
||||
read -r ANSWER
|
||||
[[ "${ANSWER}" =~ ^[iIbB] ]] && sed -i '/INLINE="/ s/^.*$/export INLINE="1"/' "${BASHBOT_ETC:-.}/mycommands.conf"
|
||||
[[ "${ANSWER}" =~ ^[cCbB] ]] && sed -i '/CALLBACK="/ s/^.*$/export CALLBACK="1"/' "${BASHBOT_ETC:-.}/mycommands.conf"
|
||||
printf "Always ignore commands for other Bots in chat ${GREY}(/cmd@other_bot)${NC}? (y/N) N\b"
|
||||
read -r ANSWER
|
||||
[[ "${ANSWER}" =~ ^[yY] ]] && sed -i '/MEONLY="/ s/^.*$/export MEONLY="1"/' "${BASHBOT_ETC:-.}/mycommands.conf"
|
||||
printf "Delete administrative messages in chats ${GREY}(pinned, user join/leave, ...)${NC}? (y/N) N\b"
|
||||
read -r ANSWER
|
||||
[[ "${ANSWER}" =~ ^[yY] ]] && sed -i '/SILENCER="/ s/^.*$/export SILENCER="yes"/' "${BASHBOT_ETC:-.}/mycommands.conf"
|
||||
fi
|
||||
printf "Done.\n"
|
||||
fi
|
||||
# adjust permissions
|
||||
printf "Adjusting files and permissions for user \"${touser}\" ...\n"
|
||||
chown -Rf "${chown}" . ./*
|
||||
chmod 711 .
|
||||
chmod -R o-w ./*
|
||||
chmod -R u+w "${COUNTFILE}"* "${BLOCKEDFILE}"* "${DATADIR}" logs "${LOGDIR}/"*.log 2>/dev/null
|
||||
chmod -R o-r,o-w "${COUNTFILE}"* "${BLOCKEDFILE}"* "${DATADIR}" "${BOTACL}" 2>/dev/null
|
||||
# jsshDB must writeable by owner
|
||||
find . -name '*.jssh*' -exec chmod u+w \{\} +
|
||||
printf "Done.\n"
|
||||
# adjust values in bashbot.rc
|
||||
if [ -w "bashbot.rc" ]; then
|
||||
printf "Adjust user and botname in bashbot.rc ...\n"
|
||||
sed -i '/^[# ]*runas=/ s|runas=.*$|runas="'"${touser}"'"|' "bashbot.rc"
|
||||
sed -i '/^[# ]*bashbotdir=/ s|bashbotdir=.*$|bashbotdir="'"${PWD}"'"|' "bashbot.rc"
|
||||
botname="$(getConfigKey "botname")"
|
||||
[ -n "${botname}" ] && sed -i '/^[# ]*name=/ s|name=.*$|name="'"${botname}"'"|' "bashbot.rc"
|
||||
printf "Done.\n"
|
||||
fi
|
||||
# ask to check bottoken online
|
||||
if [ -z "$(getConfigKey "botid")" ]; then
|
||||
printf "Seems to be your first init. Should I verify your bot token online? (y/N) N\b"
|
||||
read -r ANSWER
|
||||
if [[ "${ANSWER}" =~ ^[Yy] ]]; then
|
||||
printf "${GREEN}Contacting telegram to verify your bot token ...${NN}"
|
||||
$0 botname
|
||||
fi
|
||||
fi
|
||||
# check if botconf seems valid
|
||||
printf "${GREEN}This is your bot config:${NN}${GREY}"
|
||||
sed 's/^/\t/' "${BOTCONFIG}.jssh" | grep -vF '["bot_config_key"]'; printf "${NC}"
|
||||
if check_token "$(getConfigKey "bottoken")" && [[ "$(getConfigKey "botadmin")" =~ ^[${o9o9o9}]+$ ]]; then
|
||||
printf "Bot config seems to be valid. Should I make a backup copy? (Y/n) Y\b"
|
||||
read -r ANSWER
|
||||
if [[ -z "${ANSWER}" || "${ANSWER}" =~ ^[^Nn] ]]; then
|
||||
printf "Copy bot config to ${BOTCONFIG}.jssh.ok ...\n"
|
||||
cp "${BOTCONFIG}.jssh" "${BOTCONFIG}.jssh.ok"
|
||||
fi
|
||||
else
|
||||
printf "${ORANGE}Bot config may incomplete, pls check.${NN}"
|
||||
fi
|
||||
# show result
|
||||
printf "${GREY}"; ls -ldp "${DATADIR}" "${LOGDIR}" ./*.jssh* ./*.sh ./*.conf 2>/dev/null; printf "${NC}"
|
||||
_exec_if_function my_init
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC1090,SC2034
|
||||
#===============================================================================
|
||||
#
|
||||
# FILE: bin/bashbot_stats.sh
|
||||
|
@ -16,30 +17,17 @@ USAGE='bashbot_stats.sh [-h|--help] [debug]'
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 23.12.2020 20:34
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
# parse args
|
||||
case "$1" in
|
||||
"-h"*)
|
||||
printf "usage: %s\n" "${USAGE}"
|
||||
exit 1
|
||||
;;
|
||||
'--h'*)
|
||||
sed -n '3,/###/p' <"$0"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# set bashbot environment
|
||||
# shellcheck disable=SC1090
|
||||
source "${0%/*}/bashbot_env.inc.sh" "$1"
|
||||
[ -n "$1" ] && print_help "$1"
|
||||
|
||||
####
|
||||
# ready, do stuff here -----
|
||||
|
||||
echo -e "${GREEN}Hi I'm ${BOT_NAME}.${NC}"
|
||||
echo -e "${GREEN}Hi I'm ${BOTNAME}.${NC}"
|
||||
declare -A STATS
|
||||
jssh_readDB_async "STATS" "${COUNTFILE}"
|
||||
for MSG in ${!STATS[*]}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC1090,SC2034
|
||||
#===============================================================================
|
||||
#
|
||||
# FILE: bin/delete_message.sh
|
||||
|
@ -19,36 +20,21 @@ USAGE='delete_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" [debug]'
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 03.01.2021 15:37
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
# parse args
|
||||
DELETE="delete_message"
|
||||
case "$1" in
|
||||
'')
|
||||
printf "missing arguments\n"
|
||||
;&
|
||||
"-h"*)
|
||||
printf 'usage: %s\n' "${USAGE}"
|
||||
exit 1
|
||||
;;
|
||||
'--h'*)
|
||||
sed -n '3,/###/p' <"$0"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# set bashbot environment
|
||||
# shellcheck disable=SC1090
|
||||
source "${0%/*}/bashbot_env.inc.sh" "${3:-debug}" # $3 debug
|
||||
print_help "$1"
|
||||
|
||||
####
|
||||
####
|
||||
# ready, do stuff here -----
|
||||
if [ "$1" == "BOTADMIN" ]; then
|
||||
CHAT="${BOT_ADMIN}"
|
||||
CHAT="${BOTADMIN}"
|
||||
else
|
||||
CHAT="$1"
|
||||
fi
|
||||
|
@ -59,5 +45,4 @@ fi
|
|||
[ "${BOTSENT[OK]}" = "true" ] && BOTSENT[ID]="$2"
|
||||
|
||||
# output send message result
|
||||
jssh_printDB "BOTSENT" | sort -r
|
||||
|
||||
print_result
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC1090,SC2034
|
||||
#===============================================================================
|
||||
#
|
||||
# FILE: bin/edit_buttons.sh
|
||||
#
|
||||
USAGE='send_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" "text|url" ...'
|
||||
#
|
||||
# DESCRIPTION: send a send buttons in a row to the given user/group
|
||||
#
|
||||
# OPTIONS: CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself
|
||||
# MESSAGE[ID] - ID of MESSAGE with buttons to edit
|
||||
# text|url - buttons to send, each button as "text|url" pair or
|
||||
# "url" only to show url as text also, "" starts new row
|
||||
# "url" not http(s):// or tg:// is sent as callback_data
|
||||
#
|
||||
# -h - display short help
|
||||
# --help - this help
|
||||
#
|
||||
# EXAMPLE: 2 buttons on 2 rows, first shows Amazon, second the url as text
|
||||
# send_buttons.sh "Amazon|https://www.amazon.com" "" "https://mydealz.de" ...
|
||||
#
|
||||
# Set BASHBOT_HOME to your installation directory
|
||||
#
|
||||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 21.01.2021 08:10
|
||||
#
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
# parse args
|
||||
SEND="edit_inline_keyboard"
|
||||
|
||||
# set bashbot environment
|
||||
source "${0%/*}/bashbot_env.inc.sh" "debug"
|
||||
print_help "$1"
|
||||
|
||||
####
|
||||
# ready, do stuff here -----
|
||||
if [ "$1" == "BOTADMIN" ]; then
|
||||
CHAT="${BOTADMIN}"
|
||||
else
|
||||
CHAT="$1"
|
||||
fi
|
||||
MESSAGE_ID="$2"
|
||||
shift 2
|
||||
|
||||
# send message in selected format
|
||||
"${SEND}" "${CHAT}" "${MESSAGE_ID}" "$(_button_row "$@")"
|
||||
|
||||
# output send message result
|
||||
print_result
|
|
@ -1,7 +1,8 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC1090,SC2034
|
||||
#===============================================================================
|
||||
#
|
||||
# FILE: bin/send_message.sh
|
||||
# FILE: bin/edit_message.sh
|
||||
#
|
||||
USAGE='send_edit_message.sh [-h|--help] [format|caption] "CHAT[ID]" "MESSAGE[ID]" "message ...." [debug]'
|
||||
#
|
||||
|
@ -22,7 +23,7 @@ USAGE='send_edit_message.sh [-h|--help] [format|caption] "CHAT[ID]" "MESSAGE[ID]
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 23.12.2020 16:52
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
|
@ -45,28 +46,16 @@ case "$1" in
|
|||
SEND="edit_message_caption"
|
||||
shift
|
||||
;;
|
||||
'')
|
||||
printf "missing arguments\n"
|
||||
;&
|
||||
"-h"*)
|
||||
printf 'usage: %s\n' "${USAGE}"
|
||||
exit 1
|
||||
;;
|
||||
'--h'*)
|
||||
sed -n '3,/###/p' <"$0"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# set bashbot environment
|
||||
# shellcheck disable=SC1090
|
||||
source "${0%/*}/bashbot_env.inc.sh" "${4:-debug}" # $4 debug
|
||||
print_help "$1"
|
||||
|
||||
####
|
||||
####
|
||||
# ready, do stuff here -----
|
||||
if [ "$1" == "BOTADMIN" ]; then
|
||||
CHAT="${BOT_ADMIN}"
|
||||
CHAT="${BOTADMIN}"
|
||||
else
|
||||
CHAT="$1"
|
||||
fi
|
||||
|
@ -75,5 +64,4 @@ fi
|
|||
"${SEND}" "${CHAT}" "$2" "$3"
|
||||
|
||||
# output send message result
|
||||
jssh_printDB "BOTSENT" | sort -r
|
||||
|
||||
print_result
|
|
@ -0,0 +1,47 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC1090,SC2034
|
||||
#===============================================================================
|
||||
#
|
||||
# FILE: bin/kickban_user.sh
|
||||
#
|
||||
USAGE='kickban_user.sh [-h|--help] [-u|--unban] "CHAT[ID]" "USER[ID]" [debug]'
|
||||
#
|
||||
# DESCRIPTION: kickban or unban a user from the given group
|
||||
#
|
||||
# OPTIONS: -u | --unban - unban user
|
||||
# CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself
|
||||
# USER[ID] - user to (un)ban
|
||||
#
|
||||
# -h - display short help
|
||||
# --help - this help
|
||||
#
|
||||
#
|
||||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 25.01.2021 20:34
|
||||
#
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
# parse args
|
||||
BAN="kick_chat_member"
|
||||
case "$1" in
|
||||
"-u"|"--unban")
|
||||
BAN="unban_chat_member"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
|
||||
# set bashbot environment
|
||||
source "${0%/*}/bashbot_env.inc.sh" "${3:-debug}" # $3 debug
|
||||
print_help "$1"
|
||||
|
||||
####
|
||||
# ready, do stuff here -----
|
||||
|
||||
# send message in selected format
|
||||
"${BAN}" "$1" "$2"
|
||||
|
||||
# output send message result
|
||||
print_result
|
|
@ -0,0 +1,98 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC1090,SC2034,SC2059
|
||||
#===============================================================================
|
||||
#
|
||||
# FILE: bin/process_batch.sh
|
||||
#
|
||||
USAGE='process_batch.sh [-h|--help] [-s|--startbot] [-w|--watch] [-n|--lines n] [file] [debug]'
|
||||
#
|
||||
# DESCRIPTION: processes last 10 telegram updates in file, one update per line
|
||||
#
|
||||
# -s --startbot load addons, start TIMER, trigger startup actions
|
||||
# -w --watch watch for new updates added to file
|
||||
# -n --lines read only last "n" lines
|
||||
# file to read updates from
|
||||
# empty means read from webhook pipe
|
||||
#
|
||||
# -h - display short help
|
||||
# --help - this help
|
||||
#
|
||||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 27.02.2021 13:14
|
||||
#
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
# parse args
|
||||
COMMAND="process_multi_updates"
|
||||
lines="-n 10"
|
||||
mode="batch"
|
||||
|
||||
opt=0
|
||||
while [[ "${opt}" -lt 5 && "$1" == "-"* ]]
|
||||
do
|
||||
(( opt++ ))
|
||||
case "$1" in
|
||||
"-s"|"--startbot")
|
||||
startbot="yes"
|
||||
shift
|
||||
;;
|
||||
"-w"|"--watch")
|
||||
follow="-f"
|
||||
mode="webhook"
|
||||
shift
|
||||
;;
|
||||
"-n"|"--lines")
|
||||
lines="-n $2"
|
||||
shift 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# set bashbot environment
|
||||
source "${0%/*}/bashbot_env.inc.sh" "debug" # debug
|
||||
print_help "${1:-nix}"
|
||||
|
||||
# empty file is webhook
|
||||
file="${WEBHOOK}"
|
||||
[ -n "$1" ] && file="$1"
|
||||
|
||||
# start bot
|
||||
if [ -n "${startbot}" ]; then
|
||||
# warn when starting bot without pipe
|
||||
[ -p "${file}" ] || printf "%(%c)T: %b\n" -1 "${ORANGE}Warning${NC}: File is not a pipe:${GREY} ${file##*/}${NC}"
|
||||
start_bot "$2" "${mode}"
|
||||
printf "%(%c)T: %b\n" -1 "${GREEN}Bot startup actions done, start ${mode} updates ...${NC}"
|
||||
fi
|
||||
# check file exist
|
||||
if [[ ! -r "${file}" || -d "${file}" ]]; then
|
||||
printf "%(%c)T: %b\n" -1 "${RED}Error${NC}: File not readable:${GREY} ${file}${NC}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
####
|
||||
# ready, do stuff here -----
|
||||
|
||||
# kill all sub processes on exit
|
||||
trap 'printf "%(%c)T: %s\n" -1 "Bot in '"${mode}"' mode stopped"; kill $(jobs -p) 2>/dev/null; wait $(jobs -p) 2>/dev/null; send_normal_message "'"${BOTADMIN}"'" "Bot '"${BOTNAME} ${mode}"' stopped ..."' EXIT HUP QUIT
|
||||
|
||||
# wait after (first) update to avoid processing to many in parallel
|
||||
UPDWAIT="0.5"
|
||||
# use tail to read appended updates
|
||||
# shellcheck disable=SC2086,SC2248
|
||||
tail ${follow} ${lines} "${file}" 2>/dev/null |\
|
||||
while IFS="" read -r input 2>/dev/null
|
||||
do
|
||||
# read json from stdin and convert update format
|
||||
# replace any ID named BOTADMIN with ID of bot admin
|
||||
: "${input//\"id\":BOTADMIN,/\"id\":${BOTADMIN},}"
|
||||
json='{"result": ['"${_}"']}'
|
||||
UPDATE="$(${JSONSHFILE} -b -n <<<"${json}" 2>/dev/null)"
|
||||
|
||||
# process telegram update
|
||||
"${COMMAND}" "$2"
|
||||
sleep "${UPDWAIT}"
|
||||
UPDWAIT="0.05"
|
||||
done
|
|
@ -0,0 +1,41 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC1090,SC2034,SC2059
|
||||
#===============================================================================
|
||||
#
|
||||
# FILE: bin/process_update.sh
|
||||
#
|
||||
USAGE='process_update.sh [-h|--help] [debug] [<file]'
|
||||
#
|
||||
# DESCRIPTION: processes ONE telegram update read from stdin, e.g. form file or webhook
|
||||
#
|
||||
# -h - display short help
|
||||
# --help - this help
|
||||
#
|
||||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 30.01.2021 19:14
|
||||
#
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
# parse args
|
||||
COMMAND="process_multi_updates"
|
||||
|
||||
# set bashbot environment
|
||||
source "${0%/*}/bashbot_env.inc.sh" "debug" # debug
|
||||
print_help "${1:-nix}"
|
||||
|
||||
|
||||
####
|
||||
# ready, do stuff here -----
|
||||
|
||||
# read json from stdin and convert update format
|
||||
# replace any ID named BOTADMIN with ID of bot admin
|
||||
json='{"result": ['"$(cat)"']}'
|
||||
json="${json//\"id\":BOTADMIN,/\"id\":${BOTADMIN},}"
|
||||
UPDATE="$(${JSONSHFILE} -b -n <<<"${json}" 2>/dev/null)"
|
||||
|
||||
# process telegram update
|
||||
"${COMMAND}" "$1"
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC1090,SC2034
|
||||
#===============================================================================
|
||||
#
|
||||
# FILE: bin/promote_user.sh
|
||||
#
|
||||
USAGE='promote_user.sh [-h|--help] "CHAT[ID]" "USER[ID]" "right[:true|false]" ..'
|
||||
#
|
||||
# DESCRIPTION: promote / denote user rights in given group
|
||||
#
|
||||
# OPTIONS: CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself
|
||||
# USER[ID] - user to (un)ban
|
||||
# rights[:true|false] - rights to grant in long or short form,
|
||||
# followed by :true to grant or :false to renove
|
||||
# long: is_anonymous can_change_info can_post_messages can_edit_messages
|
||||
# can_delete_messages can_invite_users can_restrict_members
|
||||
# can_pin_messages can_promote_member`
|
||||
# short: anon change post edit delete invite restrict pin promote
|
||||
#
|
||||
# -h - display short help
|
||||
# --help - this help
|
||||
#
|
||||
#
|
||||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 25.01.2021 22:34
|
||||
#
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
# parse args
|
||||
PROMOTE="promote_chat_member"
|
||||
|
||||
# set bashbot environment
|
||||
source "${0%/*}/bashbot_env.inc.sh" "debug" # debug
|
||||
print_help "$1"
|
||||
|
||||
####
|
||||
# ready, do stuff here -----
|
||||
|
||||
# send message in selected format
|
||||
"${PROMOTE}" "$@"
|
||||
|
||||
# output send message result
|
||||
print_result
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC1090,SC2034
|
||||
#===============================================================================
|
||||
# shellcheck disable=SC2059
|
||||
#
|
||||
|
@ -27,7 +28,7 @@ USAGE='broadcast_message.sh [-h|--help] [--doit] [--groups|--both|--db=file] [fo
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 16.12.2020 16:14
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
|
@ -75,23 +76,11 @@ case "$1" in
|
|||
SEND="send_html_message"
|
||||
shift
|
||||
;;
|
||||
'')
|
||||
printf "missing missing arguments\n"
|
||||
;&
|
||||
"-h"*)
|
||||
printf 'usage: %s\n' "${USAGE}"
|
||||
exit 1
|
||||
;;
|
||||
'--h'*)
|
||||
sed -n -e '/# shellcheck /d' -e '3,/###/p' <"$0"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# set bashbot environment
|
||||
# shellcheck disable=SC1090
|
||||
source "${0%/*}/bashbot_env.inc.sh" "$2" # $3 debug
|
||||
|
||||
print_help "$1"
|
||||
|
||||
# read in users from given DB or count.jssh
|
||||
database="${USERDB:-${COUNTFILE}}"
|
||||
|
@ -102,7 +91,7 @@ if [ -z "${SENDALL[*]}" ]; then
|
|||
fi
|
||||
|
||||
# loop over users
|
||||
printf "${GREEN}Sending broadcast message to ${SENDTO}${GROUPSALSO} of ${BOT_NAME} using database:${NC}${GREY} ${database##*/}"
|
||||
printf "${GREEN}Sending broadcast message to ${SENDTO}${GROUPSALSO} of ${BOTNAME} using database:${NC}${GREY} ${database##*/}"
|
||||
|
||||
{ # dry run
|
||||
[ -z "${DOIT}" ] && printf "${NC}\n${ORANGE}DRY RUN! use --doit as first argument to execute broadcast...${NC}\n"
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC1090,SC2034
|
||||
#===============================================================================
|
||||
#
|
||||
# FILE: bin/send_message.sh
|
||||
#
|
||||
USAGE='send_message.sh [-h|--help] "CHAT[ID]" "message" "text|url" ...'
|
||||
#
|
||||
# DESCRIPTION: send a send buttons in a row to the given user/group
|
||||
#
|
||||
# OPTIONS: CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself
|
||||
# message - message to send
|
||||
# text|url - buttons to send, each button as "text|url" pair or
|
||||
# "url" not http(s):// or tg:// is sent as callback_data
|
||||
# "url" only to show url as text also, "" starts new row
|
||||
#
|
||||
# -h - display short help
|
||||
# --help - this help
|
||||
#
|
||||
# EXAMPLE: 2 buttons on 2 rows, first shows Amazon, second the url as text
|
||||
# send_buttons.sh "Amazon|https://www.amazon.com" "" "https://mydealz.de" ...
|
||||
#
|
||||
# Set BASHBOT_HOME to your installation directory
|
||||
#
|
||||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 18.01.2021 11:34
|
||||
#
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
# parse args
|
||||
SEND="send_inline_keyboard"
|
||||
|
||||
# set bashbot environment
|
||||
source "${0%/*}/bashbot_env.inc.sh" "debug"
|
||||
print_help "$1"
|
||||
|
||||
####
|
||||
# ready, do stuff here -----
|
||||
if [ "$1" == "BOTADMIN" ]; then
|
||||
CHAT="${BOTADMIN}"
|
||||
else
|
||||
CHAT="$1"
|
||||
fi
|
||||
MESSAGE="$2"
|
||||
shift 2
|
||||
|
||||
# send message in selected format
|
||||
"${SEND}" "${CHAT}" "${MESSAGE}" "$(_button_row "$@")"
|
||||
|
||||
# output send message result
|
||||
print_result
|
|
@ -0,0 +1,47 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC1090,SC2034
|
||||
#===============================================================================
|
||||
#
|
||||
# FILE: bin/send_dice.sh
|
||||
#
|
||||
USAGE='send_dice.sh [-h|--help] "CHAT[ID]" "emoji" [debug]'
|
||||
#
|
||||
# DESCRIPTION: send an animated emoji (dice) to given chat
|
||||
#
|
||||
# OPTIONS: CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself
|
||||
# emoji - must be one of: “🎲”, “🎯”, “🏀”, “⚽” “🎰” "🎳"
|
||||
# :game_die: :dart: :basketball: :soccer: :slot_machine: :bowling:
|
||||
#
|
||||
# -h - display short help
|
||||
# --help - this help
|
||||
#
|
||||
# Set BASHBOT_HOME to your installation directory
|
||||
#
|
||||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 07.02.2021 18:45
|
||||
#
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
# parse args
|
||||
SEND="send_dice"
|
||||
|
||||
# set bashbot environment
|
||||
source "${0%/*}/bashbot_env.inc.sh" "${3:-debug}" # $5 debug
|
||||
print_help "$1"
|
||||
|
||||
####
|
||||
# ready, do stuff here -----
|
||||
if [ "$1" == "BOTADMIN" ]; then
|
||||
CHAT="${BOTADMIN}"
|
||||
else
|
||||
CHAT="$1"
|
||||
fi
|
||||
|
||||
# send message in selected format
|
||||
"${SEND}" "${CHAT}" "$2"
|
||||
|
||||
# output send message result
|
||||
print_result
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC1090,SC2034
|
||||
#===============================================================================
|
||||
#
|
||||
# FILE: bin/send_file.sh
|
||||
|
@ -24,34 +25,21 @@ USAGE='send_file.sh [-h|--help] "CHAT[ID]" "file|URL" "caption ...." [type] [deb
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 25.12.2020 20:24
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
# parse args
|
||||
SEND="send_file"
|
||||
case "$1" in
|
||||
'')
|
||||
printf "missing arguments\n"
|
||||
;&
|
||||
"-h"*)
|
||||
printf 'usage: %s\n' "${USAGE}"
|
||||
exit 1
|
||||
;;
|
||||
'--h'*)
|
||||
sed -n '3,/###/p' <"$0"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# set bashbot environment
|
||||
# shellcheck disable=SC1090
|
||||
source "${0%/*}/bashbot_env.inc.sh" "${5:-debug}" # $5 debug
|
||||
print_help "$1"
|
||||
|
||||
####
|
||||
# ready, do stuff here -----
|
||||
if [ "$1" == "BOTADMIN" ]; then
|
||||
CHAT="${BOT_ADMIN}"
|
||||
CHAT="${BOTADMIN}"
|
||||
else
|
||||
CHAT="$1"
|
||||
fi
|
||||
|
@ -64,5 +52,4 @@ FILE="$2"
|
|||
"${SEND}" "${CHAT}" "${FILE}" "$3" "$4"
|
||||
|
||||
# output send message result
|
||||
jssh_printDB "BOTSENT" | sort -r
|
||||
|
||||
print_result
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC1090,SC2034
|
||||
#===============================================================================
|
||||
#
|
||||
# FILE: bin/send_message.sh
|
||||
|
@ -7,11 +8,15 @@ USAGE='send_message.sh [-h|--help] [format] "CHAT[ID]" "message ...." [debug]'
|
|||
#
|
||||
# DESCRIPTION: send a message to the given user/group
|
||||
#
|
||||
# OPTIONS: format - normal, markdown, html (optional)
|
||||
# OPTIONS: format - normal, markdown, html, stdin, - (optional)
|
||||
# CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself
|
||||
# message - message to send in specified format
|
||||
# if no format is givern send_message() format is used
|
||||
#
|
||||
# use format "stdin" to read message from stdin or from a file:
|
||||
# send_message.sh stdin "CHAT[ID]" <file
|
||||
# df -h | send_message.sh - "CHAT[ID]"
|
||||
#
|
||||
# -h - display short help
|
||||
# --help - this help
|
||||
#
|
||||
|
@ -21,7 +26,7 @@ USAGE='send_message.sh [-h|--help] [format] "CHAT[ID]" "message ...." [debug]'
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 16.12.2020 11:34
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
|
@ -40,34 +45,29 @@ case "$1" in
|
|||
SEND="send_html_message"
|
||||
shift
|
||||
;;
|
||||
'')
|
||||
printf "missing arguments\n"
|
||||
;&
|
||||
"-h"*)
|
||||
printf 'usage: %s\n' "${USAGE}"
|
||||
exit 1
|
||||
;;
|
||||
'--h'*)
|
||||
sed -n '3,/###/p' <"$0"
|
||||
exit 1
|
||||
"stdin"|"-")
|
||||
FILE="stdin"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
|
||||
# set bashbot environment
|
||||
# shellcheck disable=SC1090
|
||||
source "${0%/*}/bashbot_env.inc.sh" "${3:-debug}" # $3 debug
|
||||
print_help "$1"
|
||||
|
||||
####
|
||||
# ready, do stuff here -----
|
||||
if [ "$1" == "BOTADMIN" ]; then
|
||||
CHAT="${BOT_ADMIN}"
|
||||
CHAT="${BOTADMIN}"
|
||||
else
|
||||
CHAT="$1"
|
||||
fi
|
||||
|
||||
# send message in selected format
|
||||
"${SEND}" "${CHAT}" "$2"
|
||||
|
||||
if [ "${FILE}" = "stdin" ]; then
|
||||
"${SEND}" "${CHAT}" "$(cat)"
|
||||
else
|
||||
"${SEND}" "${CHAT}" "$2"
|
||||
fi
|
||||
# output send message result
|
||||
jssh_printDB "BOTSENT" | sort -r
|
||||
|
||||
print_result
|
||||
|
|
42
commands.sh
42
commands.sh
|
@ -8,14 +8,14 @@
|
|||
# | |__/ / |_| | | | | | |_| | |__ | |____( (_| | | |__ _
|
||||
# |_____/ \___/ |_| |_|\___/ \___) |_______)____|_|\___)_|
|
||||
#
|
||||
# this file *MUST* not be edited! place your config and commands in
|
||||
# the file "mycommands.sh". a clean version is provided as "mycommands.sh.clean"
|
||||
# this file *MUST* not edited! place your config in the file "mycommands.conf"
|
||||
# and commands in "mycommands.sh", a clean version is provided as "mycommands.sh.clean"
|
||||
#
|
||||
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#
|
||||
|
||||
# bashbot locale defaults to c.UTF-8, adjust locale in mycommands.sh if needed
|
||||
|
@ -42,12 +42,16 @@ bashbot_help='
|
|||
*• /start*: _Start bot and get this message_.
|
||||
*• /help*: _Get this message_.
|
||||
*• /info*: _Get shorter info message about this bot_.
|
||||
*• /question*: _Start interactive chat (mycommands.dist)_.
|
||||
*• /cancel*: _Cancel any currently running interactive chat_.
|
||||
*• /kickme*: _You will be autokicked from the group_.
|
||||
*• /leavechat*: _The bot will leave the group with this command _.
|
||||
Additional commands from mycommands.dist ...
|
||||
*• /game*: _throw a die_.
|
||||
*• /question*: _Start interactive chat_.
|
||||
*• /cancel*: _Cancel any currently running interactive chat_.
|
||||
*• /run_notify*: _Start background job_.
|
||||
*• /stop_notify*: _Stop notify background job_.
|
||||
Written by Drew (@topkecleon) and KayM (@gnadelwartz).
|
||||
Get the code in my [GitHub](http://github.com/topkecleon/telegram-bot-bash)
|
||||
Get the code on [GitHub](http://github.com/topkecleon/telegram-bot-bash)
|
||||
'
|
||||
|
||||
# load modules on startup and always on on debug
|
||||
|
@ -66,6 +70,7 @@ fi
|
|||
# copy "mycommands.sh.dist" to "mycommands.sh" and change the values there
|
||||
# defaults to no inline, all commands and nonsense home dir
|
||||
export INLINE="0"
|
||||
export CALLBACK="0"
|
||||
export MEONLY="0"
|
||||
export FILE_REGEX="${BASHBOT_ETC}/.*"
|
||||
|
||||
|
@ -76,23 +81,26 @@ export FILE_REGEX="${BASHBOT_ETC}/.*"
|
|||
|
||||
|
||||
if [ -z "$1" ] || [[ "$1" == *"debug"* ]];then
|
||||
# detect inline commands....
|
||||
# no default commands, all processing is done in myinlines()
|
||||
if [ "${INLINE}" != "0" ] && [ -n "${iQUERY[ID]}" ]; then
|
||||
# forward iinline query to optional dispatcher
|
||||
_exec_if_function myinlines
|
||||
#################
|
||||
# detect inline and callback query
|
||||
if [ -n "${iQUERY[ID]}" ]; then
|
||||
# forward inline query to optional dispatcher
|
||||
[ "${INLINE:-0}" != "0" ] && _exec_if_function myinlines
|
||||
|
||||
# regular (global) commands ...
|
||||
# your commands are in mycommands()
|
||||
elif [ -n "${iBUTTON[ID]}" ]; then
|
||||
# forward inline query to optional dispatcher
|
||||
[ "${CALLBACK:-0}" != "0" ] && _exec_if_function mycallbacks
|
||||
|
||||
#################
|
||||
# regular command
|
||||
else
|
||||
|
||||
###################
|
||||
# if is bashbot is group admin it get commands sent to other bots
|
||||
# set MEONLY=1 to ignore commands for other bots
|
||||
if [[ "${MEONLY}" != "0" && "${MESSAGE}" == "/"* && "${MESSAGE%% *}" == *"@"* ]]; then
|
||||
if [[ "${MEONLY}" != "0" && "${MESSAGE}" == "/"*"@"* ]]; then
|
||||
# here we have a command with @xyz_bot added, check if it's our bot
|
||||
MYCHECK="${MESSAGE%% *}"
|
||||
[ "${MYCHECK}" != "${MYCHECK%%@${ME}}" ] && return
|
||||
[ "${MESSAGE%%@*}" != "${MESSAGE%%@${ME}}" ] && return
|
||||
fi
|
||||
|
||||
###################
|
||||
|
@ -127,7 +135,7 @@ if [ -z "$1" ] || [[ "$1" == *"debug"* ]];then
|
|||
'/help'*)
|
||||
send_markdown_message "${CHAT[ID]}" "${bashbot_help}"
|
||||
;;
|
||||
'/leavechat'*) # bot leave chat if user is admin in chat
|
||||
'/leavechat'*) # bot leave chat if user is admin in chat
|
||||
if user_is_admin "${CHAT[ID]}" "${USER[ID]}" || user_is_allowed "${USER[ID]}" "leave" ; then
|
||||
send_markdown_message "${CHAT[ID]}" "*LEAVING CHAT...*"
|
||||
leave_chat "${CHAT[ID]}"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#
|
||||
# Description: run all tests, exit after failed test
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#############################################################
|
||||
|
||||
#shellcheck disable=SC1090
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#
|
||||
# Description: common stuff for all dev scripts
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#############################################################
|
||||
|
||||
# magic to ensure that we're always inside the root of our application,
|
||||
|
@ -20,3 +20,5 @@ else
|
|||
printf "Sorry, no git repository %s\n" "$(pwd)" && exit 1
|
||||
fi
|
||||
|
||||
HOOKDIR="dev/hooks"
|
||||
LASTCOMMIT=".git/.lastcommit"
|
||||
|
|
|
@ -3,15 +3,21 @@
|
|||
#
|
||||
# works together with git pre-push.sh and ADD all changed files since last push
|
||||
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
#shellcheck disable=SC1090
|
||||
source "${0%/*}/dev.inc.sh"
|
||||
|
||||
[ ! -f .git/.lastcommit ] && printf "No previous commit or hooks not installed, use \"git add\" instead ... Abort\n" && exit
|
||||
# check for last commit date
|
||||
if [ ! -f "${LASTCOMMIT}" ]; then
|
||||
if ! touch -d "$(git log -1 --format=%cD)" "${LASTCOMMIT}"; then
|
||||
printf "No previous commit found, use \"git add\" instead ... Abort\n"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
|
||||
set +f
|
||||
FILES="$(find ./* -newer .git/.lastcommit| grep -v -e 'DIST\/' -e 'STANDALONE\/' -e 'JSON.sh')"
|
||||
FILES="$(find ./* -newer "${LASTCOMMIT}" | grep -v -e 'DIST\/' -e 'STANDALONE\/' -e 'JSON.sh')"
|
||||
set -f
|
||||
# FILES="$(find ./* -newer .git/.lastpush)"
|
||||
[ "${FILES}" = "" ] && printf "Nothing changed since last commit ...\n" && exit
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
############
|
||||
# NOTE: you MUST run install-hooks.sh again when updating this file!
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
############
|
||||
# NOTE: you MUST run install-hooks.sh again when updating this file!
|
||||
|
@ -41,16 +41,17 @@ else
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# get version strings
|
||||
REMOTEVER="$(git ls-remote -t --refs 2>/dev/null | tail -1 | sed -e 's/.*\/v//' -e 's/-.*//')"
|
||||
VERSION="$(git describe --tags | sed -e 's/-.*//' -e 's/v//' -e 's/,/./')"
|
||||
|
||||
[ -z "${REMOTEVER}" ] && REMOTEVER="${VERSION}"
|
||||
|
||||
# LOCAL version must greater than latest REMOTE release version
|
||||
printf "Update Version of modified files\n"
|
||||
if ! command -v bc &> /dev/null || (( $(printf "%s\n" "${VERSION} >= ${REMOTEVER}" | bc -l) )); then
|
||||
# update version in bashbot files on push
|
||||
set +f
|
||||
[ -f "${LASTPUSH}" ] && LASTFILES="$(find ./* -newer "${LASTPUSH}")"
|
||||
[ -f "${LASTPUSH}" ] && LASTFILES="$(find ./* -newer "${LASTPUSH}" ! -path "./DIST/*" ! -path "./STANDALONE/*")"
|
||||
[ "${LASTFILES}" = "" ] && exit
|
||||
printf " "
|
||||
# shellcheck disable=SC2086
|
||||
|
@ -64,7 +65,7 @@ fi
|
|||
|
||||
if command -v codespell &>/dev/null; then
|
||||
printf "Running codespell\n............................\n"
|
||||
codespell -q 3 --skip="*.zip,*gz,*.log,*.html,*.txt,.git*,jsonDB-keyboard" -L "ba"
|
||||
codespell -q 3 --skip="*.zip,*gz,*.log,*.html,*.txt,.git*,jsonDB-keyboard,DIST,STANDALONE" -L "ba"
|
||||
printf "if there are (to many) typo's shown, consider running:\ncodespell -i 3 -w --skip=\"*.log,*.html,*.txt,.git*,examples\" -L \"ba\"\n"
|
||||
else
|
||||
printf "consider installing codespell: pip install codespell\n"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
############
|
||||
# NOTE: you MUST run install-hooks.sh again when updating this file!
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#
|
||||
# Usage: source inject-json.sh
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
##############################################################
|
||||
|
||||
# download JSON.sh
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
# this has to run once atfer git clone
|
||||
# and every time we create new hooks
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
#shellcheck disable=SC1090
|
||||
source "${0%/*}/dev.inc.sh"
|
||||
|
||||
HOOKDIR="dev/hooks"
|
||||
|
||||
printf "Installing hooks..."
|
||||
for hook in pre-commit post-commit pre-push
|
||||
do
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#
|
||||
# Options: --notest - skip tests
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
##############################################################
|
||||
|
||||
#shellcheck disable=SC1090
|
||||
|
@ -20,6 +20,7 @@ DISTDIR="./DIST/${DISTNAME}"
|
|||
DISTMKDIR="data-bot-bash logs bin bin/logs addons"
|
||||
|
||||
DISTFILES="bashbot.sh commands.sh mycommands.sh.clean bin doc examples scripts modules LICENSE README.md README.txt README.html"
|
||||
DISTFILESDEV="dev/make-standalone.sh dev/inject-json.sh dev/make-html.sh dev/obfuscate.sh"
|
||||
DISTFILESDIST="mycommands.sh mycommands.conf bashbot.rc $(echo "addons/"*.sh)"
|
||||
|
||||
# run tests first!
|
||||
|
@ -39,6 +40,9 @@ mkdir -p "${DISTDIR}" 2>/dev/null
|
|||
printf "Copy files\n"
|
||||
# shellcheck disable=SC2086
|
||||
cp -r ${DISTFILES} "${DISTDIR}"
|
||||
mkdir -p "${DISTDIR}/dev"
|
||||
# shellcheck disable=SC2086
|
||||
cp ${DISTFILESDEV} "${DISTDIR}/dev"
|
||||
cd "${DISTDIR}" || exit 1
|
||||
|
||||
printf "Create directories\n"
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
STANDALONE
|
||||
data-bot-bash/*
|
||||
test
|
||||
webhook-fifo*
|
||||
JSON.awk
|
||||
bashbot.rc
|
||||
mycommands.sh
|
||||
mycommands.conf
|
||||
awk-patch.sh
|
||||
make-standalone.sh.include
|
||||
*.jssh*
|
||||
botacl
|
||||
*.flock
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#
|
||||
# Usage: source make-hmtl
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
##############################################################
|
||||
|
||||
# check for correct dir
|
||||
|
|
|
@ -11,29 +11,53 @@
|
|||
# If you your bot is finished you can use make-standalone.sh to create the
|
||||
# the old all-in-one bashbot: bashbot.sh and commands.sh only!
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
###################################################################
|
||||
|
||||
# include git config and change to base dir
|
||||
incfile="${0%/*}/dev.inc.sh"
|
||||
#shellcheck disable=SC1090
|
||||
source "${0%/*}/dev.inc.sh"
|
||||
[ -f "${incfile}" ] && source "${incfile}"
|
||||
|
||||
# seems we are not in a dev env
|
||||
if [ -z "${BASE_DIR}" ]; then
|
||||
BASE_DIR="$(pwd)"
|
||||
[[ "${BASE_DIR}" == *"/dev" ]] && BASE_DIR="${BASE_DIR%/*}"
|
||||
# go to basedir
|
||||
cd "${BASE_DIR}" || exit 1
|
||||
fi
|
||||
|
||||
# see if if bashbot is in base dir
|
||||
[ ! -f "bashbot.sh" ] && printf "bashbot.sh not found in %s\n" " $(pwd)" && exit 1
|
||||
|
||||
# run pre_commit if exist
|
||||
[[ -f "dev/dev.inc.sh" && "$1" != "--notest" ]] && dev/hooks/pre-commit.sh
|
||||
|
||||
# files and dirs to copy
|
||||
#DISTNAME="telegram-bot-bash"
|
||||
DISTDIR="./STANDALONE"
|
||||
DISTMKDIR="data-bot-bash logs bin bin/logs addons"
|
||||
DISTFILES="bashbot.sh bashbot.rc commands.sh mycommands.sh dev/obfuscate.sh modules bin scripts LICENSE README.* doc botacl botconfig.jssh $(echo "addons/"*.sh)"
|
||||
DISTMKDIR="data-bot-bash logs bin/logs addons"
|
||||
DISTFILES="bashbot.sh commands.sh mycommands.sh modules scripts LICENSE README.* doc addons"
|
||||
DISTBINFILES="bin/bashbot_env.inc.sh bin/bashbot_stats.sh bin/process_batch.sh bin/process_update.sh bin/send_broadcast.sh bin/send_message.sh"
|
||||
|
||||
# run pre_commit on files
|
||||
[ "$1" != "--notest" ] && dev/hooks/pre-commit.sh
|
||||
# add extra files, minimum mycommands.conf
|
||||
extrafile="${BASE_DIR}/dev/${0##*/}.include"
|
||||
[ ! -f "${extrafile}" ] && printf "bashbot.rc\nbotacl\nbotconfig.jssh\nmycommands.conf\ndev/obfuscate.sh\n" >"${extrafile}"
|
||||
DISTFILES+=" $(<"${extrafile}")"
|
||||
|
||||
# create dir for distribution and copy files
|
||||
printf "Create directories and copy files\n"
|
||||
mkdir -p "${DISTDIR}" 2>/dev/null
|
||||
|
||||
mkdir -p "${DISTDIR}/bin" 2>/dev/null
|
||||
# shellcheck disable=SC2086
|
||||
cp -r ${DISTFILES} "${DISTDIR}" 2>/dev/null
|
||||
cp -rp ${DISTFILES} "${DISTDIR}" 2>/dev/null
|
||||
# shellcheck disable=SC2086
|
||||
cp -p ${DISTBINFILES} "${DISTDIR}/bin" 2>/dev/null
|
||||
|
||||
cd "${DISTDIR}" || exit 1
|
||||
|
||||
# remove log files
|
||||
find . -name '*.log' -delete
|
||||
|
||||
# shellcheck disable=SC2250
|
||||
for dir in $DISTMKDIR
|
||||
do
|
||||
|
@ -67,19 +91,20 @@ printf "OK, now lets do the magic ...\n\t... create unified commands.sh\n"
|
|||
mv $$commands.sh commands.sh
|
||||
rm -f mycommands.sh
|
||||
|
||||
printf "\n... create unified bashbot.sh\n"
|
||||
printf "\t... create unified bashbot.sh\n"
|
||||
|
||||
{
|
||||
# first head of bashbot.sh
|
||||
sed -n '0,/for module in/ p' bashbot.sh | head -n -3
|
||||
|
||||
# then mycommands from first non comment line on
|
||||
# then modules without shebang
|
||||
printf '\n##############################\n# bashbot modules starts here ...\n'
|
||||
cat modules/*.sh | sed -e 's/^#\!\/bin\/bash.*//'
|
||||
# shellcheck disable=SC2016
|
||||
cat modules/*.sh | sed -e 's/^#\!\/bin\/bash.*//' -e '/^#.*\$\$VERSION\$\$/d'
|
||||
|
||||
# last tail of commands.sh
|
||||
printf '\n##############################\n# bashbot internal functions starts here ...\n\n'
|
||||
sed -n '/BASHBOT INTERNAL functions/,$ p' bashbot.sh
|
||||
# last remaining commands.sh
|
||||
printf '\n##############################\n'
|
||||
sed -n '/^# read commands file/,$ p' bashbot.sh
|
||||
|
||||
} >>$$bashbot.sh
|
||||
|
||||
|
@ -90,11 +115,11 @@ rm -rf modules
|
|||
|
||||
printf "Create minimized Version of bashbot.sh and commands.sh\n"
|
||||
# shellcheck disable=SC2016
|
||||
sed -E -e '/(shellcheck)|(^#!\/)|(\$\$VERSION\$\$)/! s/^[[:space:]]*#.*//' -e 's/^[[:space:]]*//' -e '/^$/d' -e 'N;s/\\\n/ /;P;D' bashbot.sh |\
|
||||
sed 'N;s/\\\n/ /;P;D' > bashbot.sh.min
|
||||
sed -E -e '/(shellcheck)|(^#!\/)|(\$\$VERSION\$\$)/! s/^[[:space:]]*#.*//' -e '/shellcheck/! s/\t+#.*//' -e 's/^[[:space:]]*//'\
|
||||
-e '/^$/d' bashbot.sh | sed 'N;s/\\\n/ /;P;D' | sed 'N;s/\\\n/ /;P;D' > bashbot.sh.min
|
||||
# shellcheck disable=SC2016
|
||||
sed -E -e '/(shellcheck)|(^#!\/)|(\$\$VERSION\$\$)/! s/^[[:space:]]*#.*//' -e 's/^[[:space:]]*//' -e 's/\)[[:space:]]+#.*/)/' -e '/^$/d' commands.sh |\
|
||||
sed 'N;s/\\\n/ /;P;D' > commands.sh.min
|
||||
sed -E -e '/(shellcheck)|(^#!\/)|(\$\$VERSION\$\$)/! s/^[[:space:]]*#.*//' -e '/shellcheck/! s/\t+#.*//' -e 's/^[[:space:]]*//'\
|
||||
-e '/^$/d' commands.sh | sed 'N;s/\\\n/ /;P;D' > commands.sh.min
|
||||
chmod +x bashbot.sh.min
|
||||
|
||||
# make html doc
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
bashbot.rc
|
||||
botacl
|
||||
botconfig.jssh
|
||||
mycommands.conf
|
||||
dev/obfuscate.sh
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# joke hack to obfuscate bashbot.min.sh
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
# shellcheck disable=SC2028,SC2016,SC1117
|
||||
|
||||
infile="bashbot.sh"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# list of additional files to check from shellcheck
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
bashbot.rc
|
||||
mycommands.conf
|
||||
mycommands.sh.clean
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
# shellcheck disable=SC2016
|
||||
#
|
||||
# Easy Versioning in git:
|
||||
|
@ -43,8 +43,15 @@ unset IFS
|
|||
VERSION="$(git describe --tags --long)"
|
||||
printf "Update to version %s ...\n" "${VERSION}"
|
||||
|
||||
FILES="$(find ./*)"
|
||||
[ "$1" != "" ] && FILES="$*"
|
||||
# only regular files, ignore .dot files/dirs, e.g. .git .gitinore in BASEDIR
|
||||
if [ -n "$1" ]; then
|
||||
FILES="$*"
|
||||
else
|
||||
printf "Update version string in all files? (y/N)\b\b"
|
||||
read -r answer
|
||||
[[ "${answer}" != "y" && "${answer}" != "Y" ]] && exit
|
||||
FILES="$(find ./* -type f ! -path "./DIST/*" ! -path "./STANDALONE/*")"
|
||||
fi
|
||||
|
||||
# autogenerate REMADME.html REMADE.txt
|
||||
if [[ "${FILES}" == *"README.md"* ]]; then
|
||||
|
@ -53,7 +60,7 @@ if [[ "${FILES}" == *"README.md"* ]]; then
|
|||
cat "doc/bashbot.ascii" >"README.txt"
|
||||
if [ -r "README.html" ] && type -f html2text >/dev/null; then
|
||||
# convert html links to text [link]
|
||||
sed -E 's/<a href="([^>]+)">([^<#]+)<\/a>/\2 [\1]/' <README.html |\
|
||||
sed -E 's/<a href="([^>]+)">([^<#]+)<\/a>/\2 [\1]/g' <README.html |\
|
||||
html2text -style pretty -width 90 - >>README.txt
|
||||
else
|
||||
type -f fold >/dev/null && fold -s -w 90 README.md >>README.txt
|
||||
|
@ -63,7 +70,8 @@ fi
|
|||
# change version string in given files
|
||||
for file in ${FILES}
|
||||
do
|
||||
[ ! -f "${file}" ] && continue
|
||||
# symlink is a file :-(
|
||||
[[ -L "${file}" || ! -f "${file}" ]] && continue
|
||||
#[ "${file}" == "version" ] && continue
|
||||
printf "%s" " ${file}" >&2
|
||||
sed -i 's/^#### $$VERSION$$.*/#### \$\$VERSION\$\$ '"${VERSION}"'/' "${file}"
|
||||
|
|
|
@ -132,5 +132,5 @@ You must update to [Version 1.20](https://github.com/topkecleon/telegram-bot-bas
|
|||
|
||||
#### [Next Create Bot](1_firstbot.md)
|
||||
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
|
|
|
@ -65,5 +65,5 @@ group. This step is up to you actually.
|
|||
#### [Prev Installation](0_install.md)
|
||||
#### [Next Getting started](2_usage.md)
|
||||
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
|
|
111
doc/2_usage.md
111
doc/2_usage.md
|
@ -30,17 +30,24 @@ Have FUN!
|
|||
│
|
||||
├── bashbot.sh # main bashbot script - DO NOT EDIT!
|
||||
├── commands.sh # command dispatcher - DO NOT EDIT!
|
||||
├── JSON.sh # bashbots JSON parser, see https://github.com/dominictarr/JSON.sh
|
||||
├── JSON.sh # bashbot JSON parsers
|
||||
│ ├── JSON.sh # sh implementation, https://github.com/dominictarr/JSON.sh
|
||||
│ └── JSON.awk.dist # faster awk version, https://github.com/step-/JSON.awk
|
||||
│
|
||||
├── bin # ready to use scripts, use `scriptname --help` for help
|
||||
│ ├── bashbot_stats.sh # does what it says ...
|
||||
│ ├── send_broadcast.sh # send message to all known chats
|
||||
│ ├── send_message.sh # send message to given chat
|
||||
│ ├── edit_message.sh # replace given message id in given chat
|
||||
│ ├── delete_message.sh # delete given message id in given chat
|
||||
│ ├── send_broadcast.sh # send message to all known chats
|
||||
│ ├── send_file.sh # send file to given chat
|
||||
│ ├── bashbot_stats.sh # does what it says ...
|
||||
│ ├── delete_message.sh # delete given message id in given chat
|
||||
│ ├── send_buttons.sh # send message with attached button
|
||||
│ ├── edit_buttons.sh # attach/edit message buttons
|
||||
│ ├── kickban_user.sh # kick/unban user from given chat
|
||||
│ ├── promote_user.sh # promote/dente user rights in given chat
|
||||
│ │
|
||||
│ └── bashbot_env.inc.sh # bashbot location included from scripts, adapt if needed
|
||||
│ ├── bashbot_env.inc.sh # sourced from scripts, adapt locations if needed
|
||||
│ └── bashbot_init.inc.sh # sourced from bashbot.sh init
|
||||
│
|
||||
├── scripts # place your bashbot interactive and background scripts here
|
||||
│ └── interactive.sh.clean # interactive script template for new scripts
|
||||
|
@ -50,15 +57,15 @@ Have FUN!
|
|||
├── modules # optional functions, sourced by commands.sh
|
||||
│ ├── aliases.sh # to disable modules rename them xxx.sh.off
|
||||
│ ├── answerInline.sh
|
||||
│ ├── jsshDB.sh # read and store JSON.sh style JSON, mandatory
|
||||
│ ├── background.sh # interactive and background functions
|
||||
│ ├── chatMember.sh
|
||||
│ └── sendMessage.sh # main send message functions, mandatory
|
||||
│ ├── chatMember.sh # manage chat mambers
|
||||
│ ├── jsshDB.sh # read and store JSON.sh style JSON, mandatory
|
||||
│ ├── processUpdates.sh # process updates from telegram, mandatory (run bot)
|
||||
│ └── sendMessage.sh # send message functions, mandatory
|
||||
│
|
||||
├── addons # optional addons, disabled by default
|
||||
│ ├── example.sh # to enable addons change their XXX_ENABLE to true
|
||||
│ ├── antiFlood.sh # simple addon taking actions based on # files and text sent to chat
|
||||
│ └── xxxxxage.sh
|
||||
│ └── antiFlood.sh # simple addon taking actions based on # files and text sent to chat
|
||||
│
|
||||
├── bashbot.rc # start/stop script if you run bashbot as service
|
||||
│
|
||||
|
@ -91,6 +98,7 @@ Start or Stop your Bot use the following commands:
|
|||
```
|
||||
|
||||
### Scripts in bin/
|
||||
Use `script.sh -h` or `script --help` to get short/long help for script.
|
||||
|
||||
To count the total number of users and messages run the following command:
|
||||
|
||||
|
@ -121,7 +129,7 @@ bin/send_message.sh "CHAT[ID]" "Hey, I just wanted to let you know that the bot'
|
|||
To replace a message already sent to one user or chat run the following command:
|
||||
|
||||
```bash
|
||||
bin/send_edit_message.sh "CHAT[ID]" "12345" "Done!"
|
||||
bin/edit_message.sh "CHAT[ID]" "12345" "Done!"
|
||||
|
||||
["OK"] "true"
|
||||
["ID"] "12345"
|
||||
|
@ -144,9 +152,14 @@ Note: to get help about a script in bin/ run `scriptname.sh --help`
|
|||
Evertime a Telegram update is received, you can read incoming data using the following variables:
|
||||
In case you need other update values, the array `UPD` contains complete Telegram response.
|
||||
|
||||
### Regular Messages
|
||||
### Processing Messages
|
||||
|
||||
These Variables are always present in regular messages:
|
||||
If an update is received from Telegram, the message is pre processed by Bashbot and the following bash variables are set for use in `mycommands.sh`.
|
||||
|
||||
These variables are always present if a message is pre processed:
|
||||
|
||||
* `${ME}`: Name of your bot
|
||||
* `${BOTADMIN}`: User id of bot administrator
|
||||
|
||||
* `${MESSAGE}`: Current message text
|
||||
* `${MESSAGE[ID]}`: ID of current message
|
||||
|
@ -166,6 +179,8 @@ These Variables are always present in regular messages:
|
|||
|
||||
The following variables are set if the message contains optional parts:
|
||||
|
||||
* `MESSAGE[CAPTION]`: Picture, Audio, Video, File Captions
|
||||
* `MESSAGE[DICE]`: Animated DICE Emoji DICE values is contained in `MESSAGE[RESULT]`
|
||||
* `$REPLYTO`: Original message which was replied to
|
||||
* `$REPLYTO`: This array contains the First name, last name, username and user id of the ORIGINAL sender of the message REPLIED to.
|
||||
* `${REPLYTO[ID]}`: ID of message which was replied to
|
||||
|
@ -179,14 +194,15 @@ The following variables are set if the message contains optional parts:
|
|||
* `${FORWARD[FIRST_NAME]}`: Original user's first name
|
||||
* `${FORWARD[LAST_NAME]}`: Original user's' last name
|
||||
* `${FORWARD[USERNAME]}`: Original user's username
|
||||
* `$CAPTION`: Picture, Audio, Video, File Captions
|
||||
* `$URLS`: This array contains documents, audio files, voice recordings and stickers as URL.
|
||||
* `${URLS[AUDIO]}`: Audio files
|
||||
* `${URLS[VIDEO]}`: Videos
|
||||
* `${URLS[PHOTO]}`: Photos (maximum quality)
|
||||
* `${URLS[VOICE]}`: Voice recordings
|
||||
* `${URLS[STICKER]}`: Stickers
|
||||
* `${URLS[DOCUMENT]}`: Any other file
|
||||
* `$URLS`: This array contains the `path` on Telegram server for files send to chat, e.g. photo, video, audio file.
|
||||
* `${URLS[AUDIO]}`: Path to audio file
|
||||
* `${URLS[VIDEO]}`: Path to video
|
||||
* `${URLS[PHOTO]}`: Path to photo (maximum quality)
|
||||
* `${URLS[VOICE]}`: Path to voice recording
|
||||
* `${URLS[STICKER]}`: Path to sticker
|
||||
* `${URLS[DOCUMENT]}`: Path to any other file
|
||||
**Important:** This is NOT a full URL, you must use `download_file "${URLS[xxx]}"` or prefix path with telegram api url for manual download
|
||||
(_e.g. `getJson "${URL}/${URLS[xxx]}" >file`_).
|
||||
* `$CONTACT`: This array contains info about contacts sent in a chat.
|
||||
* `${CONTACT[ID]}`: User id
|
||||
* `${CONTACT[NUMBER]}`: Phone number
|
||||
|
@ -206,11 +222,10 @@ The following variables are set if the message contains optional parts:
|
|||
|
||||
### Service Messages
|
||||
|
||||
Service Messages are regular messages not itended for end users, instead they signal special events to the
|
||||
client, e.g. new users.
|
||||
Service Messages are updates not itended for end users, instead they signal special events in a chat, e.g. new users.
|
||||
|
||||
If a service message is received bashbot sets MESSAGE to the service message type as a command,
|
||||
e.g. if a new user joins a chat MESSAGE is set to "/_new_chat_user".
|
||||
If a service message is received bashbot pre processing sets `${MESSAGE}` according to the service message type,
|
||||
e.g. if a new user joins a chat MESSAGE is set to `/_new_chat_user ...`.
|
||||
|
||||
* `$SERVICE`: This array contains info about received service messages.
|
||||
* `${SERVICE}`: "yes" if service message is received
|
||||
|
@ -232,6 +247,8 @@ e.g. if a new user joins a chat MESSAGE is set to "/_new_chat_user".
|
|||
* `${MESSAGE}`: /_new_chat_title SENDER TEXT
|
||||
* `${SERVICE[NEWPHOTO]}`: New Chat Picture
|
||||
* `${MESSAGE}`: /_new_chat_picture SENDER URL
|
||||
**Important:** SERVICE[NEWPHOTO] is NOT a full URL, you must use `download_file "${SERVICE[NEWPHOTO]}"` or prefix path with telegram api url for manual download
|
||||
(_e.g. `getJson "${FILEURL}/${SERVICE[NEWPHOTO]}" >file`_).
|
||||
* `${SERVICE[PINNED]}`: Pinned MESSAGE ID
|
||||
* `${MESSAGE}`: /_new_pinned_message SENDER ID
|
||||
* `${PINNED[ID]}`: Id of pinned message
|
||||
|
@ -244,11 +261,17 @@ e.g. if a new user joins a chat MESSAGE is set to "/_new_chat_user".
|
|||
|
||||
|
||||
### Inline query messages
|
||||
Inline query messages are special messages for direct interaction with your bot.
|
||||
If an user starts an inline conversation an inline query is sent after each user keystroke.
|
||||
|
||||
Inline query messages are small, non regular messages used for interaction with the user,
|
||||
they contain the following variables only:
|
||||
To receive inline messages you must set `inline=1` in `mycommands.conf` and in botfather.
|
||||
THe message contatains all characters so far typed from the user.
|
||||
|
||||
* `${iQUERY}`: Current inline query
|
||||
An received inline query must be anserwered with `answer_inline_query`, see also (Inline Query)[6_reference.md#inline-query]
|
||||
|
||||
If an inline query is received only the following variables are available:
|
||||
|
||||
* `${iQUERY}`: Inline message typed so far by user
|
||||
* `$iQUERY`: This array contains the ID, First name, last name, username and user id of the sender of the current inline query.
|
||||
* `${iQUERY[ID]}`: Inline query ID
|
||||
* `${iQUERY[USER_ID]}`: User's id
|
||||
|
@ -256,11 +279,29 @@ they contain the following variables only:
|
|||
* `${iQUERY[LAST_NAME]}`: User's last name
|
||||
|
||||
|
||||
|
||||
### Callback button messages
|
||||
Callback button messages special messages swend from callback buttons, they contain the following variables only:
|
||||
|
||||
* `$iBUTTON`: This array contains the ID, First name, last name, username and user id of the user clicked on the button
|
||||
* `${iBUTTON[ID]}`: Callback query ID
|
||||
* `${iBUTTON[DATA]`: Data attached to button, hopefully unique
|
||||
* `${iBUTTON[CHAT_ID]`: Chat where button was pressed
|
||||
* `${iBUTTON[MESSAGE_ID]`: Message to which button is attached
|
||||
* `${iBUTTON[MESSAGE]`: Text of message
|
||||
* `${iBUTTON[USER_ID]}`: User's id
|
||||
* `${iBUTTON[FIRST_NAME]}`: User's first name
|
||||
* `${iBUTTON[LAST_NAME]}`: User's last name
|
||||
* `${iBUTTON[USERNAME]}`: User's @username
|
||||
|
||||
|
||||
## Send data / get response
|
||||
|
||||
After every `send_xxx` `get_xxx` call the array BOTSENT contains the most important values from Telegram response.
|
||||
In case you need other response values , the array `UPD` contains complete Telegram response.
|
||||
|
||||
You can use the array values to check if a commands was successful and get returned values from Telegram.
|
||||
|
||||
### BOTSENT array
|
||||
|
||||
* `$BOTSENT`: This array contains the parsed results from the last transmission to telegram.
|
||||
|
@ -274,7 +315,7 @@ In case you need other response values , the array `UPD` contains complete Teleg
|
|||
## Usage of bashbot functions
|
||||
|
||||
#### sending messages
|
||||
To send messages use the `send_xxx_message`functions.
|
||||
To send messages use the `send_xxx_message` functions.
|
||||
To insert line brakes in a message place `\n` in the text.
|
||||
|
||||
To send regular text without any markdown use:
|
||||
|
@ -290,7 +331,7 @@ To send text with html:
|
|||
send_html_message "${CHAT[ID]}" "lol <b>bold</b>"
|
||||
```
|
||||
|
||||
To forward messages use the `forward`function:
|
||||
To forward messages use the `forward` function:
|
||||
```bash
|
||||
forward "${CHAT[ID]}" "from_chat_id" "message_id"
|
||||
```
|
||||
|
@ -328,20 +369,20 @@ To send local files or URL's (photo, video, voice, sticker, documents) use the `
|
|||
send_file "${CHAT[ID]}" "/home/user/dog.jpg" "Lool" "photo"
|
||||
send_file "${CHAT[ID]}" "https://images-na.ssl-images-amazon.com/images/I/81DQ0FpoSNL._AC_SL1500_.jpg"
|
||||
```
|
||||
To send custom keyboards use the `send_keyboard`function:
|
||||
To send custom keyboards use the `send_keyboard` function:
|
||||
```bash
|
||||
send_keyboard "${CHAT[ID]}" "Text that will appear in chat?" '[ "Yep" , "No" ]' # note the single quotes!
|
||||
send_keyboard "${CHAT[ID]}" "Text that will appear in chat?" "[ \\"Yep\\" , \\"No\\" ]" # within double quotes you must escape the inside double quots
|
||||
```
|
||||
To send locations use the `send_location`function:
|
||||
To send locations use the `send_location` function:
|
||||
```bash
|
||||
send_location "${CHAT[ID]}" "Latitude" "Longitude"
|
||||
```
|
||||
To send venues use the `send_venue`function:
|
||||
To send venues use the `send_venue` function:
|
||||
```bash
|
||||
send_venue "${CHAT[ID]}" "Latitude" "Longitude" "Title" "Address" "optional foursquare id"
|
||||
```
|
||||
To send a chat action use the `send_action`function.
|
||||
To send a chat action use the `send_action` function.
|
||||
Allowed values: typing for text messages, upload_photo for photos, record_video or upload_video for videos, record_audio or upload_audio for audio files, upload_document for general files, find_location for locations.
|
||||
```bash
|
||||
send_action "${CHAT[ID]}" "action"
|
||||
|
@ -351,5 +392,5 @@ send_action "${CHAT[ID]}" "action"
|
|||
#### [Prev Create Bot](1_firstbot.md)
|
||||
#### [Next Advanced Usage](3_advanced.md)
|
||||
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
|
|
|
@ -73,18 +73,31 @@ You must use the function `user_is_allowed` to check if a user has the capabilit
|
|||
**See also [Bashbot User Access Control functions](6_reference.md#User-Access-Control)**
|
||||
|
||||
### Interactive Chats
|
||||
Interactive chats are short running scripts, reading user input and echo data to the user.
|
||||
Interactive chats are simple Bash scripts, reading user input as TEXT and output TEXT to the user.
|
||||
|
||||
To create a new interactive chat script copy `scripts/interactive.sh.clean` to e.g. `scripts/mynewinteractive.sh`, make it executable
|
||||
and then use `start_proc` function from your bot, it's possible to pass two arguments. You find more examples for interactive scripts in 'examples'
|
||||
|
||||
**Important**: The script runs standalone in a [pipeline](https://www.geeksforgeeks.org/piping-in-unix-or-linux/), it's **not possible** to use bashbot functions and variables!
|
||||
|
||||
```bash
|
||||
commands.sh send user input as TEXT | script reads TEXT | bashbot.sh recieve output as formated TEXT (see below)
|
||||
```
|
||||
|
||||
In case you want to process any other data then message TEXT, I recommend to switch to a more advanced bot framework.
|
||||
In Bashbot you have to implement methods yourself to pass additional information in the message TEXT to the script.
|
||||
(only recommended for advanced bash experts).
|
||||
|
||||
#### Example script
|
||||
|
||||
*usage*: start_proc chat_id script arg1 arg2
|
||||
|
||||
*usage*: kill_proc chat_id
|
||||
|
||||
*usage*: check_prog chat_id
|
||||
|
||||
**IMPORTANT:** Scripts must read user input from '$3' instead of stdin!
|
||||
|
||||
**Note:** Scripts must read user input from '$3' instead of stdin!
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
@ -144,7 +157,7 @@ echo "Text that will appear in one message \nwith this text on a new line"
|
|||
```
|
||||
|
||||
In case you want extend a message already containing a location, a file, a keyboard etc.,
|
||||
with an additionial text simply add ` mytextstartshere additional text`at the end of the string:
|
||||
with an additionial text simply add ` mytextstartshere additional text` at the end of the string:
|
||||
```bash
|
||||
out="Text that will appear mylatstartshere 45 mylongstartshere 45"
|
||||
[[ "$out" != *'in chat'* ]] && out="$out mytextstartshere in chat."
|
||||
|
@ -190,7 +203,7 @@ Note: Background jobs run independent from main bot and continue running until y
|
|||
|
||||
In order to enable **inline mode**, send `/setinline` command to [@BotFather](https://telegram.me/botfather) and provide the placeholder text that the user will see in the input field after typing your bot’s name.
|
||||
|
||||
The following commands allows you to send ansers to *inline queries*. To enable bashbot to process inline queries set `INLINE="1"`in 'mycommands.sh'.
|
||||
The following commands allows you to send ansers to *inline queries*. To enable bashbot to process inline queries set `INLINE="1"` in `mycommands.sh`.
|
||||
|
||||
To send messages or links through an *inline query*:
|
||||
```bash
|
||||
|
@ -258,7 +271,7 @@ By default you don't have to care about retry, as bashbot resend the message aft
|
|||
Only if the retry fails also an error is returned. The downside is that send_message functions will wait until resend is done.
|
||||
|
||||
If you want to disable automatic error processing and handle all errors manually (or don't care)
|
||||
set `BASHBOT_RETRY`to any no zero value.
|
||||
set `BASHBOT_RETRY` to any no zero value.
|
||||
|
||||
[Telegram Bot API error codes](https://github.com/TelegramBotAPI/errors)
|
||||
|
||||
|
@ -266,9 +279,9 @@ set `BASHBOT_RETRY`to any no zero value.
|
|||
#### Detect bot blocked
|
||||
|
||||
If the we can't connect to telegram, e.g. blocked from telegram server but also any other reason,
|
||||
bashbot set `BOTSENT[ERROR]`to `999`.
|
||||
bashbot set `BOTSENT[ERROR]` to `999`.
|
||||
|
||||
To get a notification on every connection problem create a function named `bashbotBlockRecover`and handle blocks there.
|
||||
To get a notification on every connection problem create a function named `bashbotBlockRecover` and handle blocks there.
|
||||
If the function returns true (0 or no value) bashbot will retry once and then return to the calling function.
|
||||
In case you return any non 0 value bashbot will return to the calling function without retry.
|
||||
|
||||
|
@ -302,5 +315,5 @@ Note: If you disable automatic retry, se above, you disable also connection prob
|
|||
#### [Prev Getting started](2_usage.md)
|
||||
#### [Next Expert Use](4_expert.md)
|
||||
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
|
|
|
@ -154,8 +154,9 @@ To use bashbot as a system service include a working `bashbot.rc` in your init s
|
|||
An example crontab is provided in `examples/bashbot.cron`.
|
||||
|
||||
- If you are running bashbot with your user-ID, copy the examples lines to your crontab and remove username `nobody`.
|
||||
- if you run bashbot as an other user or a system service edit `examples/bashbot.cron` to fit your needs and replace username `nobody` with the username you want to run bashbot. Copy the modified file to `/etc/cron.d/bashbot`
|
||||
- if you run bashbot as an other user or a system service edit `examples/bashbot.cron` to fit your needs and replace username `nobody` with the username you want to run bashbot. Insert the modified lines to systm crontab file or copy to `/etc/cron.d/bashbot`
|
||||
|
||||
**Warning:** You must use `contab -e` command to modify sytem and user crontabs, see [Cron How-To](https://help.ubuntu.com/community/CronHowto)
|
||||
|
||||
### Use bashbot from CLI and scripts
|
||||
You can use bashbot to send *messages*, *locations*, *venues*, *pictures* etc. from command line and scripts
|
||||
|
@ -434,5 +435,5 @@ for every poll until the maximum of BASHBOT_SLEEP ms.
|
|||
#### [Prev Advanced Use](3_advanced.md)
|
||||
#### [Next Best Practice](5_practice.md)
|
||||
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ If you don't have a github account, it may time to [setup a free account now](ht
|
|||
### Add commands to mycommands.sh only
|
||||
Do not change `bashbot.sh` and `commands.sh`, instead place your commands in to `mycommands.sh`.
|
||||
To start with a clean/minimal bot copy `mycommands.sh.clean` to `mycommands.sh` and start editing
|
||||
the message strings and place commands in the`case ... esac` block of the function mycommands():
|
||||
the message strings and place commands in the` case ... esac` block of the function mycommands():
|
||||
```bash
|
||||
# file: mycommands.sh
|
||||
# your additional bashbot commands
|
||||
|
@ -160,5 +160,5 @@ The second warning is about an unused variable, this is true because in our exam
|
|||
#### [Prev Best Practice](5_practice.md)
|
||||
#### [Next Functions Reference](6_reference.md)
|
||||
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -284,8 +284,9 @@ bar="${_/__x/_c}" # a_b_c
|
|||
: ${SOMEVAR} # "String in var" $_ -> "var"
|
||||
: $(<"file") # "Content of\n file" $_ -> "file"
|
||||
|
||||
# pitfall test command
|
||||
[ -n "$MYVAR" ] && echo "$_" # outputs "]"
|
||||
# pitfall [ vs. test command
|
||||
[ -n "xxx" ] && echo "$_" # $_ -> "]"
|
||||
test -n "xxx" && echo "$_" # $_ -> "xxx"
|
||||
|
||||
# pitfall command substitution: globbing and IFS is applied!
|
||||
: "$(echo "a* is born")"# $_ -> a* is globbed even quoted!
|
||||
|
@ -386,5 +387,5 @@ fi
|
|||
|
||||
#### [Prev Function Reference](6_reference.md)
|
||||
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
|
|
|
@ -56,6 +56,10 @@ convert existing bots.
|
|||
**jsonDB-keybords** contains a stripped down real world example from my bot showing the usage of jsonDB to store and retrieve values
|
||||
plus use of keyboards in private chats. It's an extended version of mycommands.sh.dist. Messages and help are in german.
|
||||
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
### Webhook
|
||||
|
||||
**Webhook** contains instructions on how use webhook API to get updates from telegram instead polling Telegram server.
|
||||
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
######
|
||||
# parameters
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# file: run_filename
|
||||
# background job to display content of all new files in WATCHDIR
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
######
|
||||
# parameters
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# file: run_filename
|
||||
# background job to display all new files in WATCHDIR
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
######
|
||||
# parameters
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
######
|
||||
# parameters
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
# shellcheck disable=SC1117
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
# adjust your language setting here
|
||||
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# file. multibot.sh
|
||||
# description: run multiple telegram bots from one installation
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
if [ "$2" = "" ] || [ "$2" = "-h" ]; then
|
||||
echo "Usage: $0 botname command"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
|
||||
SHELL=/bin/sh
|
||||
|
@ -23,13 +23,14 @@ MAILTO=root
|
|||
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday;
|
||||
# │ │ │ │ │ 7 is also Sunday on some systems)
|
||||
# │ │ │ │ │
|
||||
# │ │ │ │ │
|
||||
# │ │ │ │ │ ┌───────────── run as user (must be omited in users crontab
|
||||
# │ │ │ │ │ |
|
||||
# * * * * * USER command to execute
|
||||
# * * * * * root echo "run every minute!"
|
||||
|
||||
# run as www every day at 0:00 plus random sleep between 0-3h
|
||||
0 0 * * * nobody sleep "$((RANDOM \% 180 ))m" ; /usr/local/telegram-bot-bash/bashbot.sh start # (re)start bot
|
||||
0 0 * * * nobody sleep "$((RANDOM \% 180 ))m" ; /usr/local/telegram-bot-bash/bashbot.sh resumeback # (re)start background jobs
|
||||
0 0 * * * nobody sleep "$((RANDOM \% 180 ))m" ; /usr/local/telegram-bot-bash/bashbot.rc start # (re)start bot
|
||||
0 0 * * * nobody sleep "$((RANDOM \% 180 ))m" ; /usr/local/telegram-bot-bash/bashbot.rc resumeback # (re)start background jobs
|
||||
|
||||
# run as www on 24 of Dec, 12:00
|
||||
0 12 24 12 * nobody /usr/local/telegram-bot-bash/bashbot.sh broadcast "X-Mas shopping is over!" # broadcast a message
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
########################################################################
|
||||
|
||||
######
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# AUTHOR: KayM (), kay@rrr.de
|
||||
# DATE: 19.12.2020 19:03
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
# shellcheck disable=SC2154
|
||||
# shellcheck disable=SC2034
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
########################################################################
|
||||
|
||||
######
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
########################################################################
|
||||
|
||||
######
|
||||
|
@ -29,6 +29,10 @@ export 'LANGUAGE=C.UTF-8'
|
|||
unset IFS
|
||||
# set -f # if you are paranoid use set -f to disable globbing
|
||||
|
||||
# kill interactive script if not finished in time, e.g. user away or error
|
||||
MAXWAIT="1m"
|
||||
{ sleep "${MAXWAIT}"; printf "Stopping Questionnaire after %s, you need to much time to finish ... BYE\n" "${MAXWAIT}"; kill $$; wait 2>/dev/null ;} &
|
||||
|
||||
# simple yes/no question, defaults to no
|
||||
printf "Hi, hello there\nWould you like some tea (y/n)?\n"
|
||||
read -r answer <"${INPUT}"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# file: botacl
|
||||
# a user not listed here, will return false from 'user_is_allowed'
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
# Format:
|
||||
# user:resource:chat
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# to show how you can customize bashbot by only editing mycommands.sh
|
||||
# NOTE: this is not tested, simply copied from original source and reworked!
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#
|
||||
# shellcheck disable=SC2154
|
||||
# shellcheck disable=SC2034
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
/usr/local/github/telegram-bot-bash-develop/DIST/telegram-bot-bash
|
||||
/usr/local/github/telegram-bot-bash-develop/STANDALONE
|
||||
/usr/local/telegram-bot-bash
|
|
@ -0,0 +1,100 @@
|
|||
#### [Examples](../README.md)
|
||||
|
||||
## Bashbot webhook example
|
||||
|
||||
### Webhook
|
||||
|
||||
Bashbot default mode is to poll Telegram server for updates but Telegram offers webhook as a more efficient method to deliver updates.
|
||||
If your server is reachable from the Internet its possible to use the method described here.
|
||||
|
||||
Prerequisite for receiving Telegram updates with webhook is a valid SSL certificate, a self signed certificate will not be sufficient.
|
||||
|
||||
Webhook processing require special setup on server and Telegram side, therefore it's implemented as separate scripts and you need at least sudo rights to setup.
|
||||
|
||||
#### Setup Apache webhook
|
||||
|
||||
Prerequisite: An Apache webserver with a valid SLL certificate chain and php enabled.\
|
||||
This should work with other webservers also but it's not testet.
|
||||
|
||||
Setup webhook with Apache:
|
||||
|
||||
- install bashbot as described in [Bashbot Installation](../../doc/0_install.md)
|
||||
- create file `data-bot-bash/webhook-fifo-<botname>` (_\<botname\> as in `botconfig.jssh`_)
|
||||
- run `sudo bashbot.sh init` to setup bashbot to run as same user as web server (_e.g. www_)
|
||||
- create a directory in web root: `telegram/<your_bot_token>` (_<your_bot_token> as `botconfig.jssh`_)
|
||||
- give web server access to directory (_e.g.`chown www:www -R telegram`_)
|
||||
- go into the new directory and copy all files from `examples/webhook` to it
|
||||
- edit file `BASHBOT_HOME` to contain ithe Bashbot installation directory as first line (_other lines are ignored_)
|
||||
- execute `php index.php` with user id of web server to test write access to `data-bot-bash/webhook-fifo-<botname>
|
||||
|
||||
Calling `https://<yourservername>/telegram/<your_bot_token>/` will execute `index.php`
|
||||
thus append received data to the file `data-bot-bash/webhook-fifo-<botname>`.
|
||||
E.g. `https://<yourservername>/telegram/<your_bot_token>/?json={"test":"me"}` will append `{"test":"me"}`.
|
||||
|
||||
Now your Server is ready to receive updates from Telegram.
|
||||
|
||||
|
||||
#### Default webhook processing
|
||||
|
||||
This is the testet and supported default method for processing Telegram updates over webhook.
|
||||
|
||||
To enable update processing delete the file `data-bot-bash/webhook-fifo-<botname>` if webhook is working as described above.
|
||||
Incoming Telegram updates are now forwarded to the script `bin/process_update.sh` for processing.
|
||||
|
||||
On incoming Telegram updates the script is executed, it sources bashbot.sh and forward the update to Bashbot for processing.
|
||||
Even it seems overhead to source Bashbot for every update, it's more responsive and create less load than Bashbot polling mode.
|
||||
|
||||
Nevertheles there are some limitations compared to polling mode:
|
||||
- no startup actions
|
||||
- `addons` and `TIMER_EVENTS` are not working
|
||||
|
||||
Interactive and background jobs are working as of Bashbot Version 1.51.
|
||||
|
||||
#### Full webhook processing
|
||||
|
||||
Full webhook processing use an external script to imitate Bashbot polling mode with webhook.
|
||||
|
||||
1. Default webook method must work first!
|
||||
2. run `bashbot.sh init` to setup bashbot to run with your user id
|
||||
2. Create a named pipe: `mkfifo data-bot-bash/webhook-fifo-botname` and give the web server write access to it
|
||||
3. execute `php index.php` with user id of web server to test write access to `data-bot-bash/webhook-fifo-<botname>
|
||||
4. Start script for Bashbot webhook polling mode:\
|
||||
`bin/process-batch.sh --startbot --watch data-bot-bash/webhook-fifo-<botname>`
|
||||
|
||||
The script read updates from given file line by line and forward updates to Bashbot update processing. `--startbot` will run the startup actions
|
||||
(_e.g. load addons, start TIMER, trigger first run_) and `--watch` will wait for new updates instead of exit on end of file.
|
||||
Short form: 'bin/process-batch.sh -s -w'
|
||||
|
||||
If script works as expected, you may run Bashbot webook polling in background by using `./bachbot.rc starthook/stophook`.
|
||||
|
||||
To switch back to default processing delete fifo `data-bot-bash/webhook-fifo-<botname>` and stop `bin/process-batch.sh`.
|
||||
|
||||
#### Enable webhook on Telegram side
|
||||
|
||||
To get updates via webhook your server must be reachable from the internet and you must
|
||||
instruct Telegram where to deliver updates, this is done by calling bashbot function `set_webhook`.
|
||||
|
||||
*Example:*
|
||||
|
||||
```bash
|
||||
bin/any_command.sh set_webhook "https://myserver.com/telegram"
|
||||
```
|
||||
|
||||
instruct Telegram to use the URL `https://myserver.com/telegram/<your_bot_token>/` to deliver updates.
|
||||
After you enable webhook to deliver Telegram updates it's no more possible to poll updates with `bashbot.sh start`.
|
||||
|
||||
To stop delivering of Telegram updates via webhook run `bin/any_command.sh delete_webhook`.
|
||||
|
||||
**Important**: Telegram will refuse to deliver updates if your webhook has no valid SSL certificate chain.
|
||||
|
||||
|
||||
#### Bash webhook
|
||||
|
||||
A pure bash webhook implementation is not possible without extra software because Telegram delivers
|
||||
webhook updates only over secure TLS connections with a valid SSL certificate chain.
|
||||
|
||||
`socat` looks like a tool to listen for Telegram updates from bash scripts, let's see ...
|
||||
|
||||
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
/************************************************************
|
||||
* @file examples/webhook/index.php
|
||||
* @description example webhook implementation for apache
|
||||
* write to fifo/file if writeable, else pipe to command
|
||||
*
|
||||
* first line of BASHBOT_HOME is used as bot home (optional)
|
||||
* must start with /, not contain /. and min 20 characters long
|
||||
*
|
||||
* @author KayM (gnadelwartz), kay@rrr.de
|
||||
* @license http://www.wtfpl.net/txt/copying/ WTFPLv2
|
||||
* @since 30.01.2021 20:24
|
||||
*
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
***********************************************************/
|
||||
|
||||
// bashbot home dir
|
||||
$CONFIG_HOME='BASHBOT_HOME';
|
||||
$BASHBOT_HOME='/usr/local/telegram-bot-bash';
|
||||
// read from config file
|
||||
if (file_exists($CONFIG_HOME)) {
|
||||
$tmp = trim(fgets(fopen($CONFIG_HOME, 'r')));
|
||||
// start with '/', not '/.', min 20 chars
|
||||
if (substr($tmp,0,1) == '/' && strlen($tmp) >= 20 && strpos($tmp, '/.') === false) {
|
||||
$BASHBOT_HOME=$tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// bashbot config file
|
||||
$CONFIG=$BASHBOT_HOME.'/botconfig.jssh';
|
||||
// set botname here or read botname from config file if unknown
|
||||
$botname="unknown";
|
||||
if ($botname == "unknown" && file_exists($CONFIG)) {
|
||||
$prefix='["botname"] "';
|
||||
$len=strlen($prefix);
|
||||
$arr = file($CONFIG, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
foreach ($arr as $line) {
|
||||
if(substr($line, 0, $len) == $prefix) {
|
||||
$botname=substr($line, $len, strlen($line)-$len-1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// script endpoint
|
||||
$cmd=$BASHBOT_HOME.'/bin/process_update.sh';
|
||||
// default fifo endpoint
|
||||
$fifo=$BASHBOT_HOME.'/data-bot-bash/webhook-fifo-'.$botname;
|
||||
|
||||
// prepeare read, e.g. run from CLI
|
||||
$data='';
|
||||
$input="php://input";
|
||||
$json_file="json.txt";
|
||||
if (php_sapi_name() == "cli") {
|
||||
if(is_readable($json_file)) {
|
||||
$input=$json_file;
|
||||
} else {
|
||||
$input="php://stdin";
|
||||
}
|
||||
}
|
||||
// read request data
|
||||
if($json = file_get_contents($input)) {
|
||||
$data = $json;
|
||||
} else {
|
||||
$data = implode(" ",$_POST);
|
||||
if ($data == '') { $data = implode(" ",$_GET); }
|
||||
}
|
||||
// uncomment to save last received JSON
|
||||
// file_put_contents($json_file, str_replace(array("\n", "\r"), '',$data). PHP_EOL));
|
||||
|
||||
// prepare for writing
|
||||
if ($data == '') {
|
||||
error_response(400, "No data received");
|
||||
}
|
||||
if (! chdir($BASHBOT_HOME)) {
|
||||
error_response(403, "No route to bot home");
|
||||
}
|
||||
|
||||
// fifo or command?
|
||||
if (! is_writeable($fifo)) {
|
||||
// pipe to command
|
||||
if (! file_exists($cmd)) {
|
||||
error_response(502, "Webhook endpoint not found");
|
||||
}
|
||||
if (! $handle = popen( $cmd.' debug', 'w' )) {
|
||||
error_response(503, "Can't open webhook command endpoint");
|
||||
}
|
||||
} else {
|
||||
// write to fifo
|
||||
if (! $handle = fopen( $fifo, 'a' )) {
|
||||
error_response(503, "Can't open webhook file endpoint");
|
||||
}
|
||||
flock($handle, LOCK_EX);
|
||||
}
|
||||
if (fwrite( $handle, str_replace(array("\n", "\r"), '',$data). PHP_EOL) === false) {
|
||||
error_response(504, "Write to webhook failed");
|
||||
}
|
||||
flock($handle, LOCK_UN);
|
||||
pclose($handle);
|
||||
/**/
|
||||
|
||||
function error_response($code, $msg) {
|
||||
$api = substr(php_sapi_name(), 0, 3);
|
||||
if ($api == 'cgi' || $api == 'fpm') {
|
||||
header('Status: '.$code.' '.$msg);
|
||||
} else {
|
||||
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
|
||||
header($protocol.' '.$code.' '.$msg);
|
||||
}
|
||||
exit('Error '.$code.': '.$msg. PHP_EOL);
|
||||
}
|
||||
?>
|
|
@ -0,0 +1 @@
|
|||
{"update_id":665220889,"message":{"message_id":760,"from":{"id":BOTADMIN,"is_bot":false,"first_name":"Kay","last_name":"M","username":"KayM","language_code":"de"},"chat":{"id":BOTADMIN,"first_name":"Kay","last_name":"M","username":"KayM","type":"private"},"date":1612029749,"text":"/info","entities":[{"offset":0,"length":5,"type":"bot_command"}]}}
|
|
@ -1,11 +1,11 @@
|
|||
#!/bin/bash
|
||||
# file: modules/alaises.sh
|
||||
# file: modules/aliases.sh
|
||||
# do not edit, this file will be overwritten on update
|
||||
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#
|
||||
# will be automatically sourced from bashbot
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
# will be automatically sourced from bashbot
|
||||
|
||||
|
@ -31,70 +31,70 @@ inline_query_compose(){
|
|||
# title2Json title caption description markup inlinekeyboard
|
||||
case "$2" in
|
||||
# user provided media
|
||||
"article"|"message") # article ID title message (markup description)
|
||||
"article"|"message") # article ID title message (markup description)
|
||||
JSON='{"type":"article","id":"'${ID}'","input_message_content": {"message_text":"'$4'"} '$(title2Json "$3" "" "$5" "$6" "$7")'}'
|
||||
;;
|
||||
"photo") # photo ID photoURL (thumbURL title description caption)
|
||||
"photo") # photo ID photoURL (thumbURL title description caption)
|
||||
[ -z "$4" ] && tumb="$3"
|
||||
JSON='{"type":"photo","id":"'${ID}'","photo_url":"'$3'","thumb_url":"'$4${tumb}'"'$(title2Json "$5" "$7" "$6" "$7" "$8")'}'
|
||||
;;
|
||||
"gif") # gif ID photoURL (thumbURL title caption)
|
||||
"gif") # gif ID photoURL (thumbURL title caption)
|
||||
[ -z "$4" ] && tumb="$3"
|
||||
JSON='{"type":"gif","id":"'${ID}'","gif_url":"'$3'", "thumb_url":"'$4${tumb}'"'$(title2Json "$5" "$6" "$7" "$8" "$9")'}'
|
||||
;;
|
||||
"mpeg4_gif") # mpeg4_gif ID mpegURL (thumbURL title caption)
|
||||
"mpeg4_gif") # mpeg4_gif ID mpegURL (thumbURL title caption)
|
||||
[ -n "$4" ] && tumb='","thumb_url":"'$4'"'
|
||||
JSON='{"type":"mpeg4_gif","id":"'${ID}'","mpeg4_url":"'$3'"'${tumb}$(title2Json "$5" "$6" "" "$7" "$8")'}'
|
||||
;;
|
||||
"video") # video ID videoURL mime thumbURL title (caption)
|
||||
"video") # video ID videoURL mime thumbURL title (caption)
|
||||
JSON='{"type":"video","id":"'${ID}'","video_url":"'$3'","mime_type":"'$4'","thumb_url":"'$5'"'$(title2Json "$6" "$7" "$8" "$9" "${10}")'}'
|
||||
;;
|
||||
"audio") # audio ID audioURL title (caption)
|
||||
"audio") # audio ID audioURL title (caption)
|
||||
JSON='{"type":"audio","id":"'${ID}'","audio_url":"'$3'"'$(title2Json "$4" "$5" "" "" "$6")'}'
|
||||
;;
|
||||
"voice") # voice ID voiceURL title (caption)
|
||||
"voice") # voice ID voiceURL title (caption)
|
||||
JSON='{"type":"voice","id":"'${ID}'","voice_url":"'$3'"'$(title2Json "$4" "$5" "" "" "$6")'}'
|
||||
;;
|
||||
"document") # document ID title documentURL mimetype (caption description)
|
||||
"document") # document ID title documentURL mimetype (caption description)
|
||||
JSON='{"type":"document","id":"'${ID}'","document_url":"'$4'","mime_type":"'$5'"'$(title2Json "$3" "$6" "$7" "$8" "$9")'}'
|
||||
;;
|
||||
"location") # location ID lat long title
|
||||
"location") # location ID lat long title
|
||||
JSON='{"type":"location","id":"'${ID}'","latitude":"'$3'","longitude":"'$4'","title":"'$5'"}'
|
||||
;;
|
||||
"venue") # venue ID lat long title (address forsquare)
|
||||
"venue") # venue ID lat long title (address forsquare)
|
||||
[ -z "$6" ] && addr="$5"
|
||||
[ -n "$7" ] && fours=',"foursquare_id":"'$7'"'
|
||||
JSON='{"type":"venue","id":"'${ID}'","latitude":"'$3'","longitude":"'$4'","title":"'$5'","address":"'$6${addr}'"'${fours}'}'
|
||||
;;
|
||||
"contact") # contact ID phone first (last thumb)
|
||||
"contact") # contact ID phone first (last thumb)
|
||||
[ -n "$5" ] && last=',"last_name":"'$5'"'
|
||||
[ -n "$6" ] && tumb='","thumb_url":"'$6'"'
|
||||
JSON='{"type":"contact","id":"'${ID}'","phone_number":"'$3'","first_name":"'$4'"'${last}'"}'
|
||||
;;
|
||||
# title2Json title caption description markup inlinekeyboard
|
||||
# Cached media stored in Telegram server
|
||||
"cached_photo") # photo ID file (title description caption)
|
||||
"cached_photo") # photo ID file (title description caption)
|
||||
JSON='{"type":"photo","id":"'${ID}'","photo_file_id":"'$3'"'$(title2Json "$4" "$6" "$5" "$7" "$8")'}'
|
||||
;;
|
||||
"cached_gif") # gif ID file (title caption)
|
||||
"cached_gif") # gif ID file (title caption)
|
||||
JSON='{"type":"gif","id":"'${ID}'","gif_file_id":"'$3'"'$(title2Json "$4" "$5" "$6" "$7" "$8" )'}'
|
||||
;;
|
||||
"cached_mpeg4_gif") # mpeg ID file (title caption)
|
||||
"cached_mpeg4_gif") # mpeg ID file (title caption)
|
||||
JSON='{"type":"mpeg4_gif","id":"'${ID}'","mpeg4_file_id":"'$3'"'$(title2Json "$4" "$5" "" "$6" "$7")'}'
|
||||
;;
|
||||
"cached_sticker") # sticker ID file
|
||||
"cached_sticker") # sticker ID file
|
||||
JSON='{"type":"sticker","id":"'${ID}'","sticker_file_id":"'$3'"}'
|
||||
;;
|
||||
"cached_document") # document ID title file (description caption)
|
||||
"cached_document") # document ID title file (description caption)
|
||||
JSON='{"type":"document","id":"'${ID}'","document_file_id":"'$4'"'$(title2Json "$3" "$6" "$5" "$6" "$7")'}'
|
||||
;;
|
||||
"cached_video") # video ID file title (description caption)
|
||||
"cached_video") # video ID file title (description caption)
|
||||
JSON='{"type":"video","id":"'${ID}'","video_file_id":"'$3'"'$(title2Json "$4" "$6" "$5" "$7" "$8")'}'
|
||||
;;
|
||||
"cached_voice") # voice ID file title (caption)
|
||||
"cached_voice") # voice ID file title (caption)
|
||||
JSON='{"type":"voice","id":"'${ID}'","voice_file_id":"'$3'"'$(title2Json "$4" "$5" "" "" "$6")'}'
|
||||
;;
|
||||
"cached_audio") # audio ID file title (caption)
|
||||
"cached_audio") # audio ID file title (caption)
|
||||
JSON='{"type":"audio","id":"'${ID}'","audio_file_id":"'$3'"'$(title2Json "$4" "$5" "" "" "$6")'}'
|
||||
;;
|
||||
esac
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
# shellcheck disable=SC1117,SC2059
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
# will be automatically sourced from bashbot
|
||||
|
||||
|
@ -46,12 +46,16 @@ start_back() {
|
|||
printf '%s\n' "$1:$3:$2" >"${cmdfile}"
|
||||
restart_back "$@"
|
||||
}
|
||||
# $1 chatid
|
||||
# $2 program
|
||||
# $3 jobname
|
||||
# $4 $5 parameters
|
||||
restart_back() {
|
||||
local fifo; fifo="${DATADIR:-.}/$(procname "$1" "back-$3-")"
|
||||
log_message "Start background job CHAT=$1 JOB=${fifo##*/} CMD=${2##*/} $4 $5"
|
||||
log_update "Start background job CHAT=$1 JOB=${fifo##*/} CMD=${2##*/} $4 $5"
|
||||
check_back "$1" "$3" && kill_proc "$1" "back-$3-"
|
||||
nohup bash -c "{ $2 \"$4\" \"$5\" \"${fifo}\" | \"${SCRIPT}\" outproc \"$1\" \"${fifo}\"; }" &>>"${fifo}.log" &
|
||||
sleep 0.5 # give bg job some time to init
|
||||
sleep 0.5 # give bg job some time to init
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,9 +66,9 @@ start_proc() {
|
|||
[ -z "$2" ] && return
|
||||
[ -x "${2%% *}" ] || return 1
|
||||
local fifo; fifo="${DATADIR:-.}/$(procname "$1")"
|
||||
log_message "Start interactive script CHAT=$1 JOB=${fifo##*/} CMD=$2 $3 $4"
|
||||
check_proc "$1" && kill_proc "$1"
|
||||
mkfifo "${fifo}"
|
||||
log_update "Start interactive script CHAT=$1 JOB=${fifo##*/} CMD=$2 $3 $4"
|
||||
nohup bash -c "{ $2 \"$4\" \"$5\" \"${fifo}\" | \"${SCRIPT}\" outproc \"$1\" \"${fifo}\"
|
||||
rm \"${fifo}\"; [ -s \"${fifo}.log\" ] || rm -f \"${fifo}.log\"; }" &>>"${fifo}.log" &
|
||||
}
|
||||
|
@ -99,9 +103,11 @@ kill_proc() {
|
|||
fifo="$(procname "$1" "$2")"
|
||||
prid="$(proclist "${fifo}")"
|
||||
fifo="${DATADIR:-.}/${fifo}"
|
||||
log_message "Stop interactive / background CHAT=$1 JOB=${fifo##*/}"
|
||||
# shellcheck disable=SC2086
|
||||
[ -n "${prid}" ] && kill ${prid}
|
||||
if [ -n "${prid}" ]; then
|
||||
log_update "Stop interactive / background CHAT=$1 JOB=${fifo##*/}"
|
||||
kill ${prid}
|
||||
fi
|
||||
[ -s "${fifo}.log" ] || rm -f "${fifo}.log"
|
||||
[ -p "${fifo}" ] && rm -f "${fifo}";
|
||||
}
|
||||
|
@ -110,7 +116,7 @@ kill_proc() {
|
|||
# $2 message
|
||||
send_interactive() {
|
||||
local fifo; fifo="${DATADIR:-.}/$(procname "$1")"
|
||||
[ -p "${fifo}" ] && printf '%s\n' "$2" >"${fifo}" & # not blocking!
|
||||
[ -p "${fifo}" ] && printf '%s\n' "$2" >"${fifo}" & # not blocking!
|
||||
}
|
||||
|
||||
# old style but may not work because of local checks
|
||||
|
@ -118,16 +124,15 @@ inproc() {
|
|||
send_interactive "${CHAT[ID]}" "${MESSAGE[0]}"
|
||||
}
|
||||
|
||||
# start stop all jobs
|
||||
# $1 command
|
||||
# killb*
|
||||
# suspendb*
|
||||
# resumeb*
|
||||
# start stop all jobs
|
||||
# $1 command # kill suspend resume restart
|
||||
job_control() {
|
||||
local BOT ADM content proc CHAT job fifo killall=""
|
||||
BOT="$(getConfigKey "botname")"
|
||||
ADM="$(getConfigKey "botadmin")"
|
||||
ADM="${BOTADMIN}"
|
||||
debug_checks "Enter job_control" "$1"
|
||||
# cleanup on start
|
||||
[[ "$1" == "re"* ]] && bot_cleanup "startback"
|
||||
for FILE in "${DATADIR:-.}/"*-back.cmd; do
|
||||
[ "${FILE}" = "${DATADIR:-.}/*-back.cmd" ] && printf "${RED}No background processes.${NN}" && break
|
||||
content="$(< "${FILE}")"
|
||||
|
@ -138,23 +143,23 @@ job_control() {
|
|||
fifo="$(procname "${CHAT}" "${job}")"
|
||||
debug_checks "Execute job_control" "$1" "${FILE##*/}"
|
||||
case "$1" in
|
||||
"resumeb"*|"backgr"*)
|
||||
"resume"*|"restart"*)
|
||||
printf "Restart Job: %s %s\n" "${proc}" " ${fifo##*/}"
|
||||
restart_back "${CHAT}" "${proc}" "${job}"
|
||||
# inform botadmin about stop
|
||||
[ -n "${ADM}" ] && send_normal_message "${ADM}" "Bot ${BOT} restart background jobs ..." &
|
||||
;;
|
||||
"suspendb"*)
|
||||
"suspend"*)
|
||||
printf "Suspend Job: %s %s\n" "${proc}" " ${fifo##*/}"
|
||||
kill_proc "${CHAT}" "${job}"
|
||||
# inform botadmin about stop
|
||||
[ -n "${ADM}" ] && send_normal_message "${ADM}" "Bot ${BOT} suspend background jobs ..." &
|
||||
killall="y"
|
||||
;;
|
||||
"killb"*)
|
||||
"kill"*)
|
||||
printf "Kill Job: %s %s\n" "${proc}" " ${fifo##*/}"
|
||||
kill_proc "${CHAT}" "${job}"
|
||||
rm -f "${FILE}" # remove job
|
||||
rm -f "${FILE}" # remove job
|
||||
# inform botadmin about stop
|
||||
[ -n "${ADM}" ] && send_normal_message "${ADM}" "Bot ${BOT} kill background jobs ..." &
|
||||
killall="y"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
# will be automatically sourced from bashbot
|
||||
|
||||
|
@ -20,6 +20,10 @@ new_chat_invite() {
|
|||
[ "${BOTSENT[OK]}" = "true" ] && printf "%s\n" "${BOTSENT[RESULT]}"
|
||||
}
|
||||
|
||||
# $1 chat, $2 user_id, $3 title
|
||||
set_chatadmin_title() {
|
||||
sendJson "$1" '"user_id":'"$2"',"custom_title": "'"$3"'"' "${URL}/setChatAdministratorCustomTitle"
|
||||
}
|
||||
# $1 chat, $2 title
|
||||
set_chat_title() {
|
||||
sendJson "$1" '"title": "'"$2"'"' "${URL}/setChatTitle"
|
||||
|
@ -30,6 +34,12 @@ set_chat_description() {
|
|||
sendJson "$1" '"description": "'"$2"'"' "${URL}/setChatDescription"
|
||||
}
|
||||
|
||||
# $1 chat $2 file
|
||||
set_chat_photo() {
|
||||
local file; file="$(checkUploadFile "$1" "$2" "set_chat_photo")"
|
||||
[ -z "${file}" ] && return 1
|
||||
sendUpload "$1" "photo" "${file}" "${URL}/setChatPhoto"
|
||||
}
|
||||
# $1 chat
|
||||
delete_chat_photo() {
|
||||
sendJson "$1" "" "${URL}/deleteChatPhoto"
|
||||
|
@ -56,18 +66,52 @@ delete_chat_stickers() {
|
|||
}
|
||||
|
||||
# manage chat member functions -------
|
||||
# $1 chat
|
||||
chat_member_count() {
|
||||
sendJson "$1" "" "${URL}/getChatMembersCount"
|
||||
[ "${BOTSENT[OK]}" = "true" ] && printf "%s\n" "${BOTSENT[RESULT]}"
|
||||
}
|
||||
|
||||
kick_chat_member() {
|
||||
sendJson "$1" 'user_id: '"$2"'' "${URL}/kickChatMember"
|
||||
sendJson "$1" '"user_id": '"$2"'' "${URL}/kickChatMember"
|
||||
}
|
||||
|
||||
unban_chat_member() {
|
||||
sendJson "$1" 'user_id: '"$2"'' "${URL}/unbanChatMember"
|
||||
sendJson "$1" '"user_id": '"$2"'' "${URL}/unbanChatMember"
|
||||
}
|
||||
|
||||
leave_chat() {
|
||||
sendJson "$1" "" "${URL}/leaveChat"
|
||||
}
|
||||
|
||||
# $1 chat, $2 userid, $3 ... "right[:true]" default false
|
||||
# right: is_anonymous change_info post_messages edit_messages delete_messages invite_users restrict_members pin_messages promote_member
|
||||
promote_chat_member() {
|
||||
local arg bool json chat="$1" user="$2; shift 2"
|
||||
for arg in "$@"
|
||||
do
|
||||
# default false
|
||||
bool=false; [ "${arg##*:}" = "true" ] && bool="true"
|
||||
# expand args
|
||||
case "${arg}" in
|
||||
*"anon"*) arg="is_anonymous";;
|
||||
*"change"*) arg="can_change_info";;
|
||||
*"post"*) arg="can_post_messages";;
|
||||
*"edit"*) arg="can_edit_messages";;
|
||||
*"delete"*) arg="can_delete_messages";;
|
||||
*"pin"*) arg="can_pin_messages";;
|
||||
*"invite"*) arg="can_invite_users";;
|
||||
*"restrict"*) arg="can_restrict_members";;
|
||||
*"promote"*) arg="can_promote_members";;
|
||||
*) [ -n "${BASHBOTDEBUG}" ] && log_debug "promote_chat_member: unknown promotion CHAT=${chat} USER=${user} PROM=${arg}"
|
||||
continue;;
|
||||
esac
|
||||
# compose json
|
||||
[ -n "${json}" ] && json+=","
|
||||
json+='"'"${arg}"'": "'"${bool}"'"'
|
||||
done
|
||||
sendJson "${chat}" '"user_id":'"${user}"','"${json}"'' "${URL}/promoteChatMember"
|
||||
}
|
||||
|
||||
# bashbot specific functions ---------
|
||||
|
||||
|
@ -76,7 +120,7 @@ leave_chat() {
|
|||
get_chat_member_status() {
|
||||
sendJson "$1" '"user_id":'"$2"'' "${URL}/getChatMember"
|
||||
# shellcheck disable=SC2154
|
||||
JsonGetString '"result","status"' <<< "${res}"
|
||||
printf "%s\n" "${UPD["result,status"]}"
|
||||
}
|
||||
|
||||
user_is_creator() {
|
||||
|
@ -103,10 +147,9 @@ user_is_admin() {
|
|||
# $1 user
|
||||
user_is_botadmin() {
|
||||
[ -z "$1" ] && return 1
|
||||
local admin; admin="$(getConfigKey "botadmin")"; [ -z "${admin}" ] && return 1
|
||||
[[ "${admin}" == "$1" || "${admin}" == "$2" ]] && return 0
|
||||
#[[ "${admin}" = "@*" ]] && [[ "${admin}" = "$2" ]] && return 0
|
||||
if [ "${admin}" = "?" ]; then setConfigKey "botadmin" "${1:-?}"; return 0; fi
|
||||
[ -z "${BOTADMIN}" ] && return 1
|
||||
[[ "${BOTADMIN}" == "$1" || "${BOTADMIN}" == "$2" ]] && return 0
|
||||
if [ "${BOTADMIN}" = "?" ]; then setConfigKey "botadmin" "${1:-?}"; BOTADMIN="${1:-?}"; return 0; fi
|
||||
return 1
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#
|
||||
# source from commands.sh to use jsonDB functions
|
||||
#
|
||||
|
@ -25,7 +25,9 @@ eval "$(basename "${BASH_SOURCE[0]}")(){ :; }"
|
|||
# tinybox
|
||||
|
||||
# lockfile filename.flock is persistent and will be testet with flock for active lock (file open)
|
||||
export JSSH_LOCKNAME=".flock"
|
||||
export JSSHDB_LOCKNAME=".flock"
|
||||
# an array value containing this string will not saveed to DB (unset)
|
||||
export JSSHDB_UNSET="99999999999999999999_JSSHDB_UNSET_99999999999999999999"
|
||||
|
||||
# in UTF-8 äöü etc. are part of [:alnum:] and ranges (e.g. a-z), but we want ASCII a-z ranges!
|
||||
# for more information see doc/4_expert.md#Character_classes
|
||||
|
@ -42,7 +44,7 @@ JSSH_KEYOK="[-${azAZo9},._]"
|
|||
# $1 - invalid charcaters are replaced with first character
|
||||
# or deleted if $1 is empty
|
||||
jssh_stripKey() { # tr: we must escape first - in [-a-z...]
|
||||
if [[ "$1" =~ ^${JSSH_KEYOK} ]]; then # tr needs [\-...
|
||||
if [[ "$1" =~ ^${JSSH_KEYOK} ]]; then # tr needs [\-...
|
||||
tr -c "${JSSH_KEYOK/\[-/[\\-}\r\n" "${1:0:1}"
|
||||
else
|
||||
tr -dc "${JSSH_KEYOK/\[-/[\\-}\r\n"
|
||||
|
@ -64,7 +66,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
|
|||
[ -z "${DB}" ] && return 1
|
||||
[ ! -f "${DB}" ] && return 2
|
||||
# shared lock, many processes can read, max wait 1s
|
||||
{ flock -s -w 1 200; Json2Array "$1" <"${DB}"; } 200>"${DB}${JSSH_LOCKNAME}"
|
||||
{ flock -s -w 1 200; Json2Array "$1" <"${DB}"; } 200>"${DB}${JSSHDB_LOCKNAME}"
|
||||
}
|
||||
|
||||
# write ARRAY content to a file in JSON.sh format
|
||||
|
@ -76,7 +78,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
|
|||
[ -z "${DB}" ] && return 1
|
||||
[ ! -f "${DB}" ] && return 2
|
||||
# exclusive lock, no other process can read or write, maximum wait to get lock is 10s
|
||||
{ flock -e -w 10 200; Array2Json "$1" >"${DB}"; } 200>"${DB}${JSSH_LOCKNAME}"
|
||||
{ flock -e -w 10 200; Array2Json "$1" >"${DB}"; } 200>"${DB}${JSSHDB_LOCKNAME}"
|
||||
}
|
||||
|
||||
# update/write ARRAY content in file without deleting keys not in ARRAY
|
||||
|
@ -86,16 +88,16 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
|
|||
jssh_updateDB() {
|
||||
# for atomic update we can't use read/writeDB
|
||||
[ -z "$2" ] && return 1
|
||||
local DB="$2.jssh" # check in async
|
||||
local DB="$2.jssh" # check in async
|
||||
[ ! -f "${DB}" ] && return 2
|
||||
{ flock -e -w 10 200; jssh_updateDB_async "$@"; } 200>"${DB}${JSSH_LOCKNAME}"
|
||||
{ flock -e -w 10 200; jssh_updateDB_async "$@"; } 200>"${DB}${JSSHDB_LOCKNAME}"
|
||||
}
|
||||
|
||||
# insert, update, apped key/value to jsshDB
|
||||
# $1 key name, can only contain -a-zA-Z0-9,._
|
||||
# $2 key value
|
||||
# $3 filename (must exist!), must be relative to BASHBOT_ETC, and not contain '..'
|
||||
alias jssh_insertDB=jssh_insertKeyDB # backward compatibility
|
||||
alias jssh_insertDB=jssh_insertKeyDB # backward compatibility
|
||||
# renamed to be more consistent
|
||||
jssh_insertKeyDB() {
|
||||
[[ "$1" =~ ^${JSSH_KEYOK}+$ ]] || return 3
|
||||
|
@ -106,7 +108,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
|
|||
{ flock -e -w 2 200
|
||||
# it's append, but last one counts, its a simple DB ...
|
||||
printf '["%s"]\t"%s"\n' "${1//,/\",\"}" "${2//\"/\\\"}" >>"${DB}"
|
||||
} 200>"${DB}${JSSH_LOCKNAME}"
|
||||
} 200>"${DB}${JSSHDB_LOCKNAME}"
|
||||
|
||||
}
|
||||
|
||||
|
@ -119,7 +121,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
|
|||
[[ "$1" =~ ^${JSSH_KEYOK}+$ ]] || return 3
|
||||
local DB="$2.jssh"
|
||||
# start atomic delete here, exclusive max wait 10s
|
||||
{ flock -e -w 10 200; jssh_deleteKeyDB_async "$@"; } 200>"${DB}${JSSH_LOCKNAME}"
|
||||
{ flock -e -w 10 200; jssh_deleteKeyDB_async "$@"; } 200>"${DB}${JSSHDB_LOCKNAME}"
|
||||
}
|
||||
|
||||
# get key/value from jsshDB
|
||||
|
@ -133,7 +135,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
|
|||
# start atomic delete here, exclusive max wait 1s
|
||||
{ flock -s -w 1 200
|
||||
[ -r "${DB}" ] && sed -n 's/\["'"$1"'"\]\t*"\(.*\)"/\1/p' "${DB}" | tail -n 1
|
||||
} 200>"${DB}${JSSH_LOCKNAME}"
|
||||
} 200>"${DB}${JSSHDB_LOCKNAME}"
|
||||
}
|
||||
|
||||
|
||||
|
@ -148,7 +150,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
|
|||
[[ "$1" =~ ^${JSSH_KEYOK}+$ ]] || return 3
|
||||
local DB="$2.jssh"
|
||||
# start atomic delete here, exclusive max wait 5
|
||||
{ flock -e -w 5 200; jssh_countKeyDB_async "$@"; } 200>"${DB}${JSSH_LOCKNAME}"
|
||||
{ flock -e -w 5 200; jssh_countKeyDB_async "$@"; } 200>"${DB}${JSSHDB_LOCKNAME}"
|
||||
}
|
||||
|
||||
# update key/value in place to jsshDB
|
||||
|
@ -169,7 +171,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
|
|||
jssh_clearDB() {
|
||||
local DB; DB="$(jssh_checkDB "$1")"
|
||||
[ -z "${DB}" ] && return 1
|
||||
{ flock -e -w 10 200; printf '' >"${DB}"; } 200>"${DB}${JSSH_LOCKNAME}"
|
||||
{ flock -e -w 10 200; printf '' >"${DB}"; } 200>"${DB}${JSSHDB_LOCKNAME}"
|
||||
}
|
||||
|
||||
# updates Array if DB file has changed since last call
|
||||
|
@ -179,7 +181,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
|
|||
# medium complex, wrapper async
|
||||
jssh_updateArray() {
|
||||
[ -z "$2" ] && return 1
|
||||
local DB="$2.jssh" # name check in async
|
||||
local DB="$2.jssh" # name check in async
|
||||
[ ! -f "${DB}" ] && return 2
|
||||
declare -n ARRAY="$1"
|
||||
[[ -z "${ARRAY[*]}" || "${DB}" -nt "${DB}.last$3" ]] && touch "${DB}.last$3" && jssh_readDB "$1" "$2"
|
||||
|
@ -216,7 +218,7 @@ jssh_newDB_async() { jssh_newDB "$@"; }
|
|||
jssh_newDB() {
|
||||
local DB; DB="$(jssh_checkDB "$1")"
|
||||
[ -z "${DB}" ] && return 1
|
||||
[ -f "${DB}" ] && return 2 # already exist
|
||||
[ -f "${DB}" ] && return 2 # already exist
|
||||
touch "${DB}"
|
||||
}
|
||||
|
||||
|
@ -353,9 +355,10 @@ function jssh_updateArray_async() {
|
|||
# read JSON.sh style data and asssign to an ARRAY
|
||||
# $1 ARRAY name, must be declared with "declare -A ARRAY" before calling
|
||||
Json2Array() {
|
||||
# match ["....."]\t and replace \t with = and print quote true false escape not escaped $
|
||||
# shellcheck disable=SC1091,SC1090
|
||||
[ -z "$1" ] || source <( printf "$1"'=( %s )' "$(sed -E -n -e '/\["[-0-9a-zA-Z_,."]+"\]\+*\t/ s/\t/=/p' -e 's/=(true|false)/="\1"/' -e 's/([^\]|^)\$/\1\\$/g')" )
|
||||
# step 1: output only basic pattern
|
||||
[ -z "$1" ] || source <( printf "$1"'=( %s )'\
|
||||
"$(sed -E -n -e 's/[`´]//g' -e 's/\t(true|false)/\t"\1"/' -e 's/([^\]|^)\$/\1\\$/g' -e '/\["[-0-9a-zA-Z_,."]+"\]\+*\t/ s/\t/=/p')" )
|
||||
}
|
||||
# get Config Key from jssh file without jsshDB
|
||||
# output ARRAY as JSON.sh style data
|
||||
|
@ -366,7 +369,7 @@ Array2Json() {
|
|||
declare -n ARRAY="$1"
|
||||
for key in "${!ARRAY[@]}"
|
||||
do
|
||||
[[ "${key}" =~ ^${JSSH_KEYOK}+$ ]] || continue
|
||||
[[ ! "${key}" =~ ^${JSSH_KEYOK}+$ || "${ARRAY[${key}]}" == "${JSSHDB_UNSET}" ]] && continue
|
||||
# in case value contains newline convert to \n
|
||||
: "${ARRAY[${key}]//$'\n'/\\n}"
|
||||
printf '["%s"]\t"%s"\n' "${key//,/\",\"}" "${_//\"/\\\"}"
|
||||
|
|
|
@ -0,0 +1,507 @@
|
|||
#!/bin/bash
|
||||
##################################################################
|
||||
#
|
||||
# File: processUpdates.sh
|
||||
# Note: DO NOT EDIT! this file will be overwritten on update
|
||||
#
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
##################################################################
|
||||
|
||||
##############
|
||||
# manage webhooks
|
||||
|
||||
# $1 URL to sed updates to: https://host.dom[:port][/path], port and path are optional
|
||||
# port must be 443, 80, 88 8443, TOKEN will be added to URL for security
|
||||
# e.g. https://myhost.com -> https://myhost.com/12345678:azndfhbgdfbbbdsfg
|
||||
# $2 max connections 1-100 default 1 (because of bash ;-)
|
||||
set_webhook() {
|
||||
local url='"url": "'"$1/${BOTTOKEN}/"'"'
|
||||
local max=',"max_connections": 1'
|
||||
[[ "$2" =~ ^[0-9]+$ ]] && max=',"max_connections": '"$2"''
|
||||
# shellcheck disable=SC2153
|
||||
sendJson "" "${url}${max}" "${URL}/setWebhook"
|
||||
unset "BOTSENT[ID]" "BOTSENT[CHAT]"
|
||||
|
||||
}
|
||||
|
||||
get_webhook_info() {
|
||||
sendJson "" "" "${URL}/getWebhookInfo"
|
||||
if [ "${BOTSENT[OK]}" = "true" ]; then
|
||||
BOTSENT[URL]="${UPD[result,url]}"
|
||||
BOTSENT[COUNT]="${UPD[result,pending_update_count]}"
|
||||
BOTSENT[CERT]="${UPD[result,has_custom_certificate]}"
|
||||
BOTSENT[LASTERR]="${UPD[result,last_error_message]}"
|
||||
unset "BOTSENT[ID]" "BOTSENT[CHAT]"
|
||||
fi
|
||||
}
|
||||
|
||||
# $1 drop pending updates true/false, default false
|
||||
delete_webhook() {
|
||||
local drop; [ "$1" = "true" ] && drop='"drop_pending_updates": true'
|
||||
sendJson "" "${drop}" "${URL}/deleteWebhook"
|
||||
unset "BOTSENT[ID]" "BOTSENT[CHAT]"
|
||||
}
|
||||
|
||||
################
|
||||
# processing of array of updates starts here
|
||||
process_multi_updates() {
|
||||
local max num debug="$1"
|
||||
# get num array elements
|
||||
max="$(grep -F ',"update_id"]' <<< "${UPDATE}" | tail -1 | cut -d , -f 2 )"
|
||||
# escape bash $ expansion bug
|
||||
UPDATE="${UPDATE//$/\\$}"
|
||||
# convert updates to bash array
|
||||
Json2Array 'UPD' <<<"${UPDATE}"
|
||||
# iterate over array
|
||||
for ((num=0; num<=max; num++)); do
|
||||
process_update "${num}" "${debug}"
|
||||
done
|
||||
}
|
||||
|
||||
################
|
||||
# processing of a single array item of update
|
||||
# $1 array index
|
||||
process_update() {
|
||||
local chatuser="Chat" num="$1" debug="$2"
|
||||
pre_process_message "${num}"
|
||||
# log message on debug
|
||||
[[ -n "${debug}" ]] && log_message "New Message ==========\n$(grep -F '["result",'"${num}" <<<"${UPDATE}")"
|
||||
|
||||
# check for users / groups to ignore, inform them ...
|
||||
jssh_updateArray_async "BASHBOTBLOCKED" "${BLOCKEDFILE}"
|
||||
if [ -n "${USER[ID]}" ] && [[ -n "${BASHBOTBLOCKED[${USER[ID]}]}" || -n "${BASHBOTBLOCKED[${CHAT[ID]}]}" ]];then
|
||||
[ -n "${BASHBOTBLOCKED[${USER[ID]}]}" ] && chatuser="User"
|
||||
[ "${NOTIFY_BLOCKED_USERS}" == "yes" ] &&\
|
||||
send_normal_message "${CHAT[ID]}" "${chatuser} blocked because: ${BASHBOTBLOCKED[${USER[ID]}]} ${BASHBOTBLOCKED[${CHAT[ID]}]}" &
|
||||
return
|
||||
fi
|
||||
|
||||
# process per message type
|
||||
if [ -n "${iQUERY[ID]}" ]; then
|
||||
process_inline_query "${num}" "${debug}"
|
||||
printf "%(%c)T: Inline Query update received FROM=%s iQUERY=%s\n" -1\
|
||||
"${iQUERY[USERNAME]:0:20} (${iQUERY[USER_ID]})" "${iQUERY[0]}" >>"${UPDATELOG}"
|
||||
elif [ -n "${iBUTTON[ID]}" ]; then
|
||||
process_inline_button "${num}" "${debug}"
|
||||
printf "%(%c)T: Inline Button update received FROM=%s CHAT=%s CALLBACK=%s DATA:%s \n" -1\
|
||||
"${iBUTTON[USERNAME]:0:20} (${iBUTTON[USER_ID]})" "${iBUTTON[CHAT_ID]}" "${iBUTTON[ID]}" "${iBUTTON[DATA]}" >>"${UPDATELOG}"
|
||||
else
|
||||
if grep -qs -e '\["result",'"${num}"',"edited_message"' <<<"${UPDATE}"; then
|
||||
# edited message
|
||||
UPDATE="${UPDATE//,${num},\"edited_message\",/,${num},\"message\",}"
|
||||
Json2Array 'UPD' <<<"${UPDATE}"
|
||||
MESSAGE[0]="/_edited_message "
|
||||
fi
|
||||
process_message "${num}" "${debug}"
|
||||
printf "%(%c)T: update received FROM=%s CHAT=%s CMD=%s\n" -1 "${USER[USERNAME]:0:20} (${USER[ID]})"\
|
||||
"${CHAT[USERNAME]:0:20}${CHAT[TITLE]:0:30} (${CHAT[ID]})"\
|
||||
"${MESSAGE:0:30}${CAPTION:0:30}${URLS[*]}" >>"${UPDATELOG}"
|
||||
if [[ -z "${USER[ID]}" || -z "${CHAT[ID]}" ]]; then
|
||||
printf "%(%c)T: IGNORE unknown update type: %s\n" -1 "$(grep '\["result",'"${num}"'.*,"id"\]' <<<"${UPDATE}")" >>"${UPDATELOG}"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
#####
|
||||
# process inline and message events
|
||||
# first classic command dispatcher
|
||||
# shellcheck disable=SC2153,SC1090
|
||||
{ source "${COMMANDS}" "${debug}"; } &
|
||||
|
||||
# then all registered addons
|
||||
if [ -z "${iQUERY[ID]}" ]; then
|
||||
event_message "${debug}"
|
||||
else
|
||||
event_inline "${debug}"
|
||||
fi
|
||||
|
||||
# last count users
|
||||
jssh_countKeyDB_async "${CHAT[ID]}" "${COUNTFILE}"
|
||||
}
|
||||
|
||||
pre_process_message(){
|
||||
local num="$1"
|
||||
# unset everything to not have old values
|
||||
CMD=( ); iQUERY=( ); iBUTTON=(); MESSAGE=(); CHAT=(); USER=(); CONTACT=(); LOCATION=(); unset CAPTION
|
||||
REPLYTO=( ); FORWARD=( ); URLS=(); VENUE=( ); SERVICE=( ); NEWMEMBER=( ); LEFTMEMBER=( ); PINNED=( ); MIGRATE=( )
|
||||
iQUERY[ID]="${UPD["result,${num},inline_query,id"]}"
|
||||
iBUTTON[ID]="${UPD["result,${num},callback_query,id"]}"
|
||||
CHAT[ID]="${UPD["result,${num},message,chat,id"]}"
|
||||
USER[ID]="${UPD["result,${num},message,from,id"]}"
|
||||
[ -z "${CHAT[ID]}" ] && CHAT[ID]="${UPD["result,${num},edited_message,chat,id"]}"
|
||||
[ -z "${USER[ID]}" ] && USER[ID]="${UPD["result,${num},edited_message,from,id"]}"
|
||||
# always true
|
||||
return 0
|
||||
}
|
||||
|
||||
process_inline_query() {
|
||||
local num="$1"
|
||||
iQUERY[0]="$(JsonDecode "${UPD["result,${num},inline_query,query"]}")"
|
||||
iQUERY[USER_ID]="${UPD["result,${num},inline_query,from,id"]}"
|
||||
iQUERY[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},inline_query,from,first_name"]}")"
|
||||
iQUERY[LAST_NAME]="$(JsonDecode "${UPD["result,${num},inline_query,from,last_name"]}")"
|
||||
iQUERY[USERNAME]="$(JsonDecode "${UPD["result,${num},inline_query,from,username"]}")"
|
||||
# always true
|
||||
return 0
|
||||
}
|
||||
|
||||
process_inline_button() {
|
||||
local num="$1"
|
||||
iBUTTON[DATA]="${UPD["result,${num},callback_query,data"]}"
|
||||
iBUTTON[CHAT_ID]="${UPD["result,${num},callback_query,message,chat,id"]}"
|
||||
iBUTTON[MESSAGE_ID]="${UPD["result,${num},callback_query,message,message_id"]}"
|
||||
iBUTTON[MESSAGE]="$(JsonDecode "${UPD["result,${num},callback_query,message,text"]}")"
|
||||
# XXX should we give back pressed button, all buttons or nothing?
|
||||
iBUTTON[USER_ID]="${UPD["result,${num},callback_query,from,id"]}"
|
||||
iBUTTON[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},callback_query,from,first_name"]}")"
|
||||
iBUTTON[LAST_NAME]="$(JsonDecode "${UPD["result,${num},callback_query,from,last_name"]}")"
|
||||
iBUTTON[USERNAME]="$(JsonDecode "${UPD["result,${num},callback_query,from,username"]}")"
|
||||
# always true
|
||||
return 0
|
||||
}
|
||||
|
||||
process_message() {
|
||||
local num="$1"
|
||||
# Message
|
||||
MESSAGE[0]+="$(JsonDecode "${UPD["result,${num},message,text"]}" | sed 's|\\/|/|g')"
|
||||
MESSAGE[ID]="${UPD["result,${num},message,message_id"]}"
|
||||
MESSAGE[CAPTION]="$(JsonDecode "${UPD["result,${num},message,caption"]}")"
|
||||
CAPTION="${MESSAGE[CAPTION]}" # backward compatibility
|
||||
# dice received
|
||||
MESSAGE[DICE]="${UPD["result,${num},message,dice,emoji"]}"
|
||||
if [ -n "${MESSAGE[DICE]}" ]; then
|
||||
MESSAGE[RESULT]="${UPD["result,${num},message,dice,value"]}"
|
||||
MESSAGE[0]="/_dice_received ${MESSAGE[DICE]} ${MESSAGE[RESULT]}"
|
||||
fi
|
||||
# Chat ID is now parsed when update is received
|
||||
CHAT[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,chat,last_name"]}")"
|
||||
CHAT[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,chat,first_name"]}")"
|
||||
CHAT[USERNAME]="$(JsonDecode "${UPD["result,${num},message,chat,username"]}")"
|
||||
# set real name as username if empty
|
||||
[ -z "${CHAT[USERNAME]}" ] && CHAT[USERNAME]="${CHAT[FIRST_NAME]} ${CHAT[LAST_NAME]}"
|
||||
CHAT[TITLE]="$(JsonDecode "${UPD["result,${num},message,chat,title"]}")"
|
||||
CHAT[TYPE]="$(JsonDecode "${UPD["result,${num},message,chat,type"]}")"
|
||||
CHAT[ALL_ADMIN]="${UPD["result,${num},message,chat,all_members_are_administrators"]}"
|
||||
|
||||
# user ID is now parsed when update is received
|
||||
USER[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,from,first_name"]}")"
|
||||
USER[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,from,last_name"]}")"
|
||||
USER[USERNAME]="$(JsonDecode "${UPD["result,${num},message,from,username"]}")"
|
||||
# set real name as username if empty
|
||||
[ -z "${USER[USERNAME]}" ] && USER[USERNAME]="${USER[FIRST_NAME]} ${USER[LAST_NAME]}"
|
||||
|
||||
# in reply to message from
|
||||
if [ -n "${UPD["result,${num},message,reply_to_message,from,id"]}" ]; then
|
||||
REPLYTO[UID]="${UPD["result,${num},message,reply_to_message,from,id"]}"
|
||||
REPLYTO[0]="$(JsonDecode "${UPD["result,${num},message,reply_to_message,text"]}")"
|
||||
REPLYTO[ID]="${UPD["result,${num},message,reply_to_message,message_id"]}"
|
||||
REPLYTO[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,reply_to_message,from,first_name"]}")"
|
||||
REPLYTO[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,reply_to_message,from,last_name"]}")"
|
||||
REPLYTO[USERNAME]="$(JsonDecode "${UPD["result,${num},message,reply_to_message,from,username"]}")"
|
||||
fi
|
||||
|
||||
# forwarded message from
|
||||
if [ -n "${UPD["result,${num},message,forward_from,id"]}" ]; then
|
||||
FORWARD[UID]="${UPD["result,${num},message,forward_from,id"]}"
|
||||
FORWARD[ID]="${MESSAGE[ID]}" # same as message ID
|
||||
FORWARD[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,forward_from,first_name"]}")"
|
||||
FORWARD[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,forward_from,last_name"]}")"
|
||||
FORWARD[USERNAME]="$(JsonDecode "${UPD["result,${num},message,forward_from,username"]}")"
|
||||
fi
|
||||
|
||||
# get file URL from telegram, check for any of them!
|
||||
if grep -qs -e '\["result",'"${num}"',"message","[avpsd].*,"file_id"\]' <<<"${UPDATE}"; then
|
||||
URLS[AUDIO]="$(get_file "${UPD["result,${num},message,audio,file_id"]}")"
|
||||
URLS[DOCUMENT]="$(get_file "${UPD["result,${num},message,document,file_id"]}")"
|
||||
URLS[PHOTO]="$(get_file "${UPD["result,${num},message,photo,0,file_id"]}")"
|
||||
URLS[STICKER]="$(get_file "${UPD["result,${num},message,sticker,file_id"]}")"
|
||||
URLS[VIDEO]="$(get_file "${UPD["result,${num},message,video,file_id"]}")"
|
||||
URLS[VOICE]="$(get_file "${UPD["result,${num},message,voice,file_id"]}")"
|
||||
fi
|
||||
# Contact, must have phone_number
|
||||
if [ -n "${UPD["result,${num},message,contact,phone_number"]}" ]; then
|
||||
CONTACT[USER_ID]="$(JsonDecode "${UPD["result,${num},message,contact,user_id"]}")"
|
||||
CONTACT[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,contact,first_name"]}")"
|
||||
CONTACT[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,contact,last_name"]}")"
|
||||
CONTACT[NUMBER]="${UPD["result,${num},message,contact,phone_number"]}"
|
||||
CONTACT[VCARD]="${UPD["result,${num},message,contact,vcard"]}"
|
||||
fi
|
||||
|
||||
# venue, must have a position
|
||||
if [ -n "${UPD["result,${num},message,venue,location,longitude"]}" ]; then
|
||||
VENUE[TITLE]="$(JsonDecode "${UPD["result,${num},message,venue,title"]}")"
|
||||
VENUE[ADDRESS]="$(JsonDecode "${UPD["result,${num},message,venue,address"]}")"
|
||||
VENUE[LONGITUDE]="${UPD["result,${num},message,venue,location,longitude"]}"
|
||||
VENUE[LATITUDE]="${UPD["result,${num},message,venue,location,latitude"]}"
|
||||
VENUE[FOURSQUARE]="${UPD["result,${num},message,venue,foursquare_id"]}"
|
||||
fi
|
||||
|
||||
# Location
|
||||
LOCATION[LONGITUDE]="${UPD["result,${num},message,location,longitude"]}"
|
||||
LOCATION[LATITUDE]="${UPD["result,${num},message,location,latitude"]}"
|
||||
|
||||
# service messages, group or channel only!
|
||||
if [[ "${CHAT[ID]}" == "-"* ]] ; then
|
||||
# new chat member
|
||||
if [ -n "${UPD["result,${num},message,new_chat_member,id"]}" ]; then
|
||||
SERVICE[NEWMEMBER]="${UPD["result,${num},message,new_chat_member,id"]}"
|
||||
NEWMEMBER[ID]="${SERVICE[NEWMEMBER]}"
|
||||
NEWMEMBER[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,new_chat_member,first_name"]}")"
|
||||
NEWMEMBER[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,new_chat_member,last_name"]}")"
|
||||
NEWMEMBER[USERNAME]="$(JsonDecode "${UPD["result,${num},message,new_chat_member,username"]}")"
|
||||
NEWMEMBER[ISBOT]="${UPD["result,${num},message,new_chat_member,is_bot"]}"
|
||||
MESSAGE[0]="/_new_chat_member ${NEWMEMBER[ID]} ${NEWMEMBER[USERNAME]:=${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]}}"
|
||||
fi
|
||||
# left chat member
|
||||
if [ -n "${UPD["result,${num},message,left_chat_member,id"]}" ]; then
|
||||
SERVICE[LEFTMEMBER]="${UPD["result,${num},message,left_chat_member,id"]}"
|
||||
LEFTMEMBER[ID]="${SERVICE[LEFTMEBER]}"
|
||||
LEFTMEMBER[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,left_chat_member,first_name"]}")"
|
||||
LEFTMEMBER[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,left_chat_member,last_name"]}")"
|
||||
LEFTMEBER[USERNAME]="$(JsonDecode "${UPD["result,${num},message,left_chat_member,username"]}")"
|
||||
LEFTMEMBER[ISBOT]="${UPD["result,${num},message,left_chat_member,is_bot"]}"
|
||||
MESSAGE[0]="/_left_chat_member ${LEFTMEMBER[ID]} ${LEFTMEMBER[USERNAME]:=${LEFTMEMBER[FIRST_NAME]} ${LEFTMEMBER[LAST_NAME]}}"
|
||||
fi
|
||||
# chat title / photo, check for any of them!
|
||||
if grep -qs -e '\["result",'"${num}"',"message","new_chat_[tp]' <<<"${UPDATE}"; then
|
||||
SERVICE[NEWTITLE]="$(JsonDecode "${UPD["result,${num},message,new_chat_title"]}")"
|
||||
[ -n "${SERVICE[NEWTITLE]}" ] &&\
|
||||
MESSAGE[0]="/_new_chat_title ${USER[ID]} ${SERVICE[NEWTITLE]}"
|
||||
SERVICE[NEWPHOTO]="$(get_file "${UPD["result,${num},message,new_chat_photo,0,file_id"]}")"
|
||||
[ -n "${SERVICE[NEWPHOTO]}" ] &&\
|
||||
MESSAGE[0]="/_new_chat_photo ${USER[ID]} ${SERVICE[NEWPHOTO]}"
|
||||
fi
|
||||
# pinned message
|
||||
if [ -n "${UPD["result,${num},message,pinned_message,message_id"]}" ]; then
|
||||
SERVICE[PINNED]="${UPD["result,${num},message,pinned_message,message_id"]}"
|
||||
PINNED[ID]="${SERVICE[PINNED]}"
|
||||
PINNED[MESSAGE]="$(JsonDecode "${UPD["result,${num},message,pinned_message,text"]}")"
|
||||
MESSAGE[0]="/_new_pinned_message ${USER[ID]} ${PINNED[ID]} ${PINNED[MESSAGE]}"
|
||||
fi
|
||||
# migrate to super group
|
||||
if [ -n "${UPD["result,${num},message,migrate_to_chat_id"]}" ]; then
|
||||
MIGRATE[TO]="${UPD["result,${num},message,migrate_to_chat_id"]}"
|
||||
MIGRATE[FROM]="${UPD["result,${num},message,migrate_from_chat_id"]}"
|
||||
# CHAT is already migrated, so set new chat id
|
||||
[ "${CHAT[ID]}" = "${MIGRATE[FROM]}" ] && CHAT[ID]="${MIGRATE[FROM]}"
|
||||
SERVICE[MIGRATE]="${MIGRATE[FROM]} ${MIGRATE[TO]}"
|
||||
MESSAGE[0]="/_migrate_group ${SERVICE[MIGRATE]}"
|
||||
fi
|
||||
# set SERVICE to yes if a service message was received
|
||||
[[ "${SERVICE[*]}" =~ ^[[:blank:]]*$ ]] || SERVICE[0]="yes"
|
||||
fi
|
||||
|
||||
# split message in command and args
|
||||
[[ "${MESSAGE[0]}" == "/"* ]] && read -ra CMD <<<"${MESSAGE[0]}" && CMD[0]="${CMD[0]%%@*}"
|
||||
# everything went well
|
||||
return 0
|
||||
}
|
||||
|
||||
#########################
|
||||
# bot startup actions, call before start polling or webhook loop
|
||||
declare -A BASHBOTBLOCKED
|
||||
start_bot() {
|
||||
local DEBUGMSG
|
||||
# startup message
|
||||
DEBUGMSG="BASHBOT startup actions, mode set to \"${1:-normal}\" =========="
|
||||
log_update "${DEBUGMSG}"
|
||||
# redirect to Debug.log
|
||||
if [[ "$1" == *"debug" ]]; then
|
||||
# shellcheck disable=SC2153
|
||||
exec &>>"${DEBUGLOG}"
|
||||
log_debug "${DEBUGMSG}";
|
||||
fi
|
||||
DEBUGMSG="$1"
|
||||
[[ "${DEBUGMSG}" == "xdebug"* ]] && set -x
|
||||
# cleaup old pipes and empty logfiles
|
||||
find "${DATADIR}" -type p -not -name "webhook-fifo-*" -delete
|
||||
find "${DATADIR}" -size 0 -name "*.log" -delete
|
||||
# load addons on startup
|
||||
for addons in "${ADDONDIR:-.}"/*.sh ; do
|
||||
# shellcheck disable=SC1090
|
||||
[ -r "${addons}" ] && source "${addons}" "startbot" "${DEBUGMSG}"
|
||||
done
|
||||
# shellcheck disable=SC1090
|
||||
source "${COMMANDS}" "startbot"
|
||||
# start timer events
|
||||
if [ -n "${BASHBOT_START_TIMER}" ] ; then
|
||||
# shellcheck disable=SC2064
|
||||
trap "event_timer ${DEBUGMSG}" ALRM
|
||||
start_timer &
|
||||
# shellcheck disable=SC2064
|
||||
trap "kill -9 $!; exit" EXIT INT HUP TERM QUIT
|
||||
fi
|
||||
# cleanup on start
|
||||
bot_cleanup "startup"
|
||||
# read blocked users
|
||||
jssh_readDB_async "BASHBOTBLOCKED" "${BLOCKEDFILE}"
|
||||
# inform botadmin about start
|
||||
send_normal_message "$(getConfigKey "botadmin")" "Bot ${ME} $2 started ..." &
|
||||
}
|
||||
|
||||
# main polling updates loop, should never terminate
|
||||
get_updates(){
|
||||
local errsleep="200" DEBUG="$1" OFFSET=0
|
||||
# adaptive sleep defaults
|
||||
local nextsleep="100"
|
||||
local stepsleep="${BASHBOT_SLEEP_STEP:-100}"
|
||||
local maxsleep="${BASHBOT_SLEEP:-5000}"
|
||||
printf "%(%c)T: %b\n" -1 "Bot startup actions done, start polling updates ..."
|
||||
while true; do
|
||||
# adaptive sleep in ms rounded to next 0.1 s
|
||||
sleep "$(_round_float "${nextsleep}e-3" "1")"
|
||||
# get next update
|
||||
# shellcheck disable=SC2153
|
||||
UPDATE="$(getJson "${URL}/getUpdates?offset=${OFFSET}" 2>/dev/null | "${JSONSHFILE}" -b -n 2>/dev/null | iconv -f utf-8 -t utf-8 -c)"
|
||||
# did we get an response?
|
||||
if [ -n "${UPDATE}" ]; then
|
||||
# we got something, do processing
|
||||
[ "${OFFSET}" = "-999" ] && [ "${nextsleep}" -gt "$((maxsleep*2))" ] &&\
|
||||
log_error "Recovered from timeout/broken/no connection, continue with telegram updates"
|
||||
# calculate next sleep interval
|
||||
((nextsleep+= stepsleep , nextsleep= nextsleep>maxsleep ?maxsleep:nextsleep))
|
||||
# warn if webhook is set
|
||||
if grep -q '^\["error_code"\] 409' <<<"${UPDATE}"; then
|
||||
[ "${OFFSET}" != "-999" ] && nextsleep="${stepsleep}"
|
||||
OFFSET="-999"; errsleep="$(_round_float "$(( errsleep= 300*nextsleep ))e-3")"
|
||||
log_error "Warning conflicting webhook set, can't get updates until your run delete_webhook! Sleep $((errsleep/60)) min ..."
|
||||
sleep "${errsleep}"
|
||||
continue
|
||||
fi
|
||||
# Offset
|
||||
OFFSET="$(grep <<<"${UPDATE}" '\["result",[0-9]*,"update_id"\]' | tail -1 | cut -f 2)"
|
||||
((OFFSET++))
|
||||
|
||||
if [ "${OFFSET}" != "1" ]; then
|
||||
nextsleep="100"
|
||||
process_multi_updates "${DEBUG}"
|
||||
fi
|
||||
else
|
||||
# oops, something bad happened, wait maxsleep*10
|
||||
(( nextsleep=nextsleep*2 , nextsleep= nextsleep>maxsleep*10 ?maxsleep*10:nextsleep ))
|
||||
# second time, report problem
|
||||
if [ "${OFFSET}" = "-999" ]; then
|
||||
log_error "Repeated timeout/broken/no connection on telegram update, sleep $(_round_float "${nextsleep}e-3")s"
|
||||
# try to recover
|
||||
if _is_function bashbotBlockRecover && [ -z "$(getJson "${ME_URL}")" ]; then
|
||||
log_error "Try to recover, calling bashbotBlockRecover ..."
|
||||
bashbotBlockRecover >>"${ERRORLOG}"
|
||||
fi
|
||||
fi
|
||||
OFFSET="-999"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
declare -Ax BASHBOT_EVENT_INLINE BASHBOT_EVENT_MESSAGE BASHBOT_EVENT_CMD BASHBOT_EVENT_REPLYTO BASHBOT_EVENT_FORWARD BASHBOT_EVENT_SEND
|
||||
declare -Ax BASHBOT_EVENT_CONTACT BASHBOT_EVENT_LOCATION BASHBOT_EVENT_FILE BASHBOT_EVENT_TEXT BASHBOT_EVENT_TIMER BASHBOT_BLOCKED
|
||||
|
||||
start_timer(){
|
||||
# send alarm every ~60 s
|
||||
while :; do
|
||||
sleep 59.5
|
||||
kill -ALRM $$
|
||||
done;
|
||||
}
|
||||
|
||||
EVENT_TIMER="0"
|
||||
event_timer() {
|
||||
local key timer debug="$1"
|
||||
(( EVENT_TIMER++ ))
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_TIMER[@]}"
|
||||
do
|
||||
timer="${key##*,}"
|
||||
[[ ! "${timer}" =~ ^-*[1-9][0-9]*$ ]] && continue
|
||||
if [ "$(( EVENT_TIMER % timer ))" = "0" ]; then
|
||||
_exec_if_function "${BASHBOT_EVENT_TIMER[${key}]}" "timer" "${key}" "${debug}"
|
||||
[ "$(( EVENT_TIMER % timer ))" -lt "0" ] && \
|
||||
unset BASHBOT_EVENT_TIMER["${key}"]
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
event_inline() {
|
||||
local key debug="$1"
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_INLINE[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_INLINE[${key}]}" "inline" "${key}" "${debug}"
|
||||
done
|
||||
}
|
||||
event_message() {
|
||||
local key debug="$1"
|
||||
# ${MESSAEG[*]} event_message
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_MESSAGE[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_MESSAGE[${key}]}" "message" "${key}" "${debug}"
|
||||
done
|
||||
|
||||
# ${TEXT[*]} event_text
|
||||
if [ -n "${MESSAGE[0]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_TEXT[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_TEXT[${key}]}" "text" "${key}" "${debug}"
|
||||
done
|
||||
|
||||
# ${CMD[*]} event_cmd
|
||||
if [ -n "${CMD[0]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_CMD[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_CMD[${key}]}" "command" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
# ${REPLYTO[*]} event_replyto
|
||||
if [ -n "${REPLYTO[UID]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_REPLYTO[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_REPLYTO[${key}]}" "replyto" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
# ${FORWARD[*]} event_forward
|
||||
if [ -n "${FORWARD[UID]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_FORWARD[@]}"
|
||||
do
|
||||
_exec_if_function && "${BASHBOT_EVENT_FORWARD[${key}]}" "forward" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
# ${CONTACT[*]} event_contact
|
||||
if [ -n "${CONTACT[FIRST_NAME]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_CONTACT[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_CONTACT[${key}]}" "contact" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
# ${VENUE[*]} event_location
|
||||
# ${LOCATION[*]} event_location
|
||||
if [ -n "${LOCATION[LONGITUDE]}" ] || [ -n "${VENUE[TITLE]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_LOCATION[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_LOCATION[${key}]}" "location" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
# ${URLS[*]} event_file
|
||||
# NOTE: compare again #URLS -1 blanks!
|
||||
if [[ "${URLS[*]}" != " " ]]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_FILE[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_FILE[${key}]}" "file" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
# shellcheck disable=SC1117
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
# will be automatically sourced from bashbot
|
||||
|
||||
|
@ -25,7 +25,6 @@ EDIT_URL=${URL}'/editMessageText'
|
|||
# $1 CHAT $2 message
|
||||
send_normal_message() {
|
||||
local len text; text="$(JsonEscape "$2")"
|
||||
text="${text//$'\n'/\\n}"
|
||||
until [ -z "${text}" ]; do
|
||||
if [ "${#text}" -le 4096 ]; then
|
||||
sendJson "$1" '"text":"'"${text}"'"' "${MSG_URL}"
|
||||
|
@ -38,46 +37,74 @@ send_normal_message() {
|
|||
text="${text:$((len+2))}"
|
||||
fi
|
||||
done
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
|
||||
}
|
||||
|
||||
# $1 CHAT $2 message
|
||||
send_markdown_message() {
|
||||
_format_message_url "$1" "$2" ',"parse_mode":"markdown"' "${MSG_URL}"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
|
||||
}
|
||||
|
||||
# $1 CHAT $2 message
|
||||
send_markdownv2_message() {
|
||||
_markdownv2_message_url "$1" "$2" ',"parse_mode":"markdownv2"' "${MSG_URL}"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
|
||||
}
|
||||
|
||||
# $1 CHAT $2 message
|
||||
send_html_message() {
|
||||
_format_message_url "$1" "$2" ',"parse_mode":"html"' "${MSG_URL}"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
|
||||
}
|
||||
|
||||
# $1 CHAT $2 msg-id $3 message
|
||||
edit_normal_message() {
|
||||
_format_message_url "$1" "$3" ',"message_id":'"$2"'' "${EDIT_URL}"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
|
||||
}
|
||||
|
||||
# $1 CHAT $2 msg-id $3 message
|
||||
edit_markdown_message() {
|
||||
_format_message_url "$1" "$3" ',"message_id":'"$2"',"parse_mode":"markdown"' "${EDIT_URL}"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
|
||||
}
|
||||
|
||||
# $1 CHAT $2 msg-id $3 message
|
||||
edit_markdownv2_message() {
|
||||
_markdownv2_message_url "$1" "$3" ',"message_id":'"$2"',"parse_mode":"markdownv2"' "${EDIT_URL}"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
|
||||
}
|
||||
|
||||
# $1 CHAT $2 msg-id $3 message
|
||||
edit_html_message() {
|
||||
_format_message_url "$1" "$3" ',"message_id":'"$2"',"parse_mode":"html"' "${EDIT_URL}"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
|
||||
}
|
||||
|
||||
# $1 chat $2 mesage_id, $3 caption
|
||||
edit_message_caption() {
|
||||
sendJson "$1" '"message_id":'"$2"',"caption":"'"$3"'"' "${URL}/editMessageCaption"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
|
||||
}
|
||||
|
||||
|
||||
# $ chat $2 msg_id $3 nolog
|
||||
delete_message() {
|
||||
[ -z "$3" ] && log_update "Delete Message CHAT=$1 MSG_ID=$2"
|
||||
sendJson "$1" '"message_id": '"$2"'' "${URL}/deleteMessage"
|
||||
[ "${BOTSENT[OK]}" = "true" ] && BOTSENT[CHAT]="$1"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
|
||||
}
|
||||
|
||||
|
||||
|
@ -85,7 +112,6 @@ edit_message_caption() {
|
|||
# $1 CHAT $2 message $3 action $4 URL
|
||||
_format_message_url(){
|
||||
local text; text="$(JsonEscape "$2")"
|
||||
text="${text//$'\n'/\\n}"
|
||||
[ "${#text}" -ge 4096 ] && log_error "Warning: html/markdown message longer than 4096 characters, message is rejected if formatting crosses 4096 border."
|
||||
until [ -z "${text}" ]; do
|
||||
sendJson "$1" '"text":"'"${text:0:4096}"'"'"$3"'' "$4"
|
||||
|
@ -97,7 +123,6 @@ _format_message_url(){
|
|||
# $1 CHAT $2 message $3 action $4 URL
|
||||
_markdownv2_message_url() {
|
||||
local text; text="$(JsonEscape "$2")"
|
||||
text="${text//$'\n'/\\n}"
|
||||
[ "${#text}" -ge 4096 ] && log_error "Warning: markdownv2 message longer than 4096 characters, message is rejected if formatting crosses 4096 border."
|
||||
# markdown v2 needs additional double escaping!
|
||||
text="$(sed -E -e 's|([_|~`>+=#{}()!.-])|\\\1|g' <<< "${text}")"
|
||||
|
@ -119,9 +144,17 @@ send_keyboard() {
|
|||
text="$(JsonEscape "$2")"
|
||||
text='"text":"'"${text//$'\n'/\\n}"'"'
|
||||
fi
|
||||
# text longer than 4096, send text and keyboard separate
|
||||
if [ "${#2}" -gt 4096 ]; then
|
||||
send_normal_message "$1" "$2"
|
||||
send_keyboard "$1" "..." "$3"
|
||||
return
|
||||
fi
|
||||
local one_time=', "one_time_keyboard":true' && [ -n "$4" ] && one_time=""
|
||||
sendJson "$1" "${text}"', "reply_markup": {"keyboard": [ '"$3"' ] '"${one_time}"'}' "${MSG_URL}"
|
||||
# '"text":"$2", "reply_markup": {"keyboard": [ $3 ], "one_time_keyboard": true}'
|
||||
sendJson "$1" "${text}"', "reply_markup": {"keyboard": [ '"$3"' ] '"${one_time}"'}' "${MSG_URL}"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
|
||||
}
|
||||
|
||||
# $1 CHAT $2 message $3 remove
|
||||
|
@ -133,24 +166,79 @@ remove_keyboard() {
|
|||
fi
|
||||
sendJson "$1" "${text}"', "reply_markup": {"remove_keyboard":true}' "${MSG_URL}"
|
||||
# delete message if no message or $3 not empty
|
||||
[[ -z "$2" || -n "$3" ]] && delete_message "$1" "${BOTSENT[ID]}" "nolog"
|
||||
#JSON='"text":"$2", "reply_markup": {"remove_keyboard":true}'
|
||||
[[ -z "$2" || -n "$3" ]] && delete_message "$1" "${BOTSENT[ID]}" "nolog"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
|
||||
}
|
||||
|
||||
# buttons will specified as "texts
|
||||
#|url" ... "text|url" empty arg starts new row
|
||||
# url not starting with http:// or https:// will be send as callback_data
|
||||
send_inline_buttons(){
|
||||
send_inline_keyboard "$1" "$2" "$(_button_row "${@:3}")"
|
||||
}
|
||||
|
||||
# $1 CHAT $2 message-id $3 buttons
|
||||
# buttons will specified as "text|url" ... "text|url" empty arg starts new row
|
||||
# url not starting with http:// or https:// will be send as callback_data
|
||||
edit_inline_buttons(){
|
||||
edit_inline_keyboard "$1" "$2" "$(_button_row "${@:3}")"
|
||||
}
|
||||
|
||||
|
||||
# $1 CHAT $2 message $3 button text $4 button url
|
||||
send_button() {
|
||||
send_inline_keyboard "$1" "$2" '[{"text":"'"$(JsonEscape "$3")"'", "url":"'"$4"'"}]'
|
||||
}
|
||||
|
||||
# helper function to create json for a button row
|
||||
# buttons will specified as "text|url" ... "text|url" empty arg starts new row
|
||||
# url not starting with http:// or https:// will be send as callback_data
|
||||
_button_row() {
|
||||
[ -z "$1" ] && return 1
|
||||
local arg type json sep
|
||||
for arg in "$@"
|
||||
do
|
||||
[ -z "${arg}" ] && sep="],[" && continue
|
||||
type="callback_data"
|
||||
[[ "${arg##*|}" =~ ^(https*://|tg://) ]] && type="url"
|
||||
json+="${sep}"'{"text":"'"$(JsonEscape "${arg%|*}")"'", "'"${type}"'":"'"${arg##*|}"'"}'
|
||||
sep=","
|
||||
done
|
||||
printf "[%s]" "${json}"
|
||||
}
|
||||
|
||||
# raw inline functions, for special use
|
||||
# $1 CHAT $2 message-id $3 keyboard
|
||||
edit_inline_keyboard() {
|
||||
# JSON='"message_id":"$2", "reply_markup": {"inline_keyboard": [ $3->[{"text":"text", "url":"url"}]<- ]}'
|
||||
sendJson "$1" '"message_id":'"$2"', "reply_markup": {"inline_keyboard": [ '"$3"' ]}' "${URL}/editMessageReplyMarkup"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
|
||||
}
|
||||
|
||||
|
||||
# $1 CHAT $2 message $3 keyboard
|
||||
send_inline_keyboard() {
|
||||
local text; text='"text":"'$(JsonEscape "$2")'"'; [ -z "$2" ] && text='"text":"'"Keyboard:"'"'
|
||||
local text; text='"text":"'$(JsonEscape "$2")'"'; [ -z "$2" ] && text='"text":"..."'
|
||||
sendJson "$1" "${text}"', "reply_markup": {"inline_keyboard": [ '"$3"' ]}' "${MSG_URL}"
|
||||
# JSON='"text":"$2", "reply_markup": {"inline_keyboard": [ $3->[{"text":"text", "url":"url"}]<- ]}'
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
|
||||
}
|
||||
# $1 CHAT $2 message $3 button text $4 URL
|
||||
send_button() {
|
||||
send_inline_keyboard "$1" "$2" '[ {"text":"'"$(JsonEscape "$3")"'", "url":"'"$4"'"}]'
|
||||
|
||||
# $1 callback id, $2 text to show, alert if not empty
|
||||
answer_callback_query() {
|
||||
local alert
|
||||
[ -n "$3" ] && alert='","show_alert": true'
|
||||
sendJson "" '"callback_query_id": "'"$1"'","text":"'"$2${alert}"'"' "${URL}/answerCallbackQuery"
|
||||
}
|
||||
|
||||
# $1 chat, $2 file_id on telegram server
|
||||
send_sticker() {
|
||||
sendJson "$1" '"sticker": "'"$2"'"' "${URL}/sendSticker"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
|
||||
}
|
||||
|
||||
|
||||
|
@ -160,7 +248,7 @@ if detect_curl ; then
|
|||
# $1 chat $3 ... $n URL or ID
|
||||
send_album(){
|
||||
[ -z "$1" ] && return 1
|
||||
[ -z "$3" ] && return 2 # minimum 2 files
|
||||
[ -z "$3" ] && return 2 # minimum 2 files
|
||||
local CHAT JSON IMAGE; CHAT="$1"; shift
|
||||
for IMAGE in "$@"
|
||||
do
|
||||
|
@ -181,13 +269,10 @@ else
|
|||
}
|
||||
fi
|
||||
|
||||
UPLOADDIR="${BASHBOT_UPLOAD:-${DATADIR}/upload}"
|
||||
|
||||
# supports local file, URL and file_id
|
||||
# $1 chat, $2 file https::// file_id:// , $3 caption, $4 extension (optional)
|
||||
send_file(){
|
||||
local url what num stat err media capt file="$2" ext="$4"
|
||||
capt="$(JsonEscape "$3")"
|
||||
local url what num stat media capt="$3" file="$2" ext="$4"
|
||||
if [[ "${file}" =~ ^https*:// ]]; then
|
||||
media="URL"
|
||||
elif [[ "${file}" == file_id://* ]]; then
|
||||
|
@ -196,28 +281,8 @@ send_file(){
|
|||
else
|
||||
# we have a file, check file location ...
|
||||
media="FILE"
|
||||
[[ "${file}" = *'..'* || "${file}" = '.'* ]] && err=1 # no directory traversal
|
||||
if [[ "${file}" = '/'* ]] ; then
|
||||
[[ ! "${file}" =~ ${FILE_REGEX} ]] && err=2 # absolute must match REGEX
|
||||
else
|
||||
file="${UPLOADDIR:-NOUPLOADDIR}/${file}" # others must be in UPLOADDIR
|
||||
fi
|
||||
[ ! -r "${file}" ] && err=3 # and file must exits of course
|
||||
# file path error, generate error response
|
||||
if [ -n "${err}" ]; then
|
||||
BOTSENT=(); BOTSENT[OK]="false"
|
||||
case "${err}" in
|
||||
1) BOTSENT[ERROR]="Path to file $2 contains to much '../' or starts with '.'";;
|
||||
2) BOTSENT[ERROR]="Path to file $2 does not match regex: ${FILE_REGEX} ";;
|
||||
3) if [[ "$2" == "/"* ]];then
|
||||
BOTSENT[ERROR]="File not found: $2"
|
||||
else
|
||||
BOTSENT[ERROR]="File not found: ${UPLOADDIR}/$2"
|
||||
fi;;
|
||||
esac
|
||||
[ -n "${BASHBOTDEBUG}" ] && log_message "Error in upload_file: ${BOTSENT[ERROR]}"
|
||||
return
|
||||
fi
|
||||
file="$(checkUploadFile "$1" "$2" "send_file")"
|
||||
[ -z "${file}" ] && return 1
|
||||
# file OK, let's continue
|
||||
fi
|
||||
|
||||
|
@ -265,24 +330,55 @@ send_file(){
|
|||
return 0
|
||||
}
|
||||
|
||||
# $1 typing upload_photo record_video upload_video record_audio upload_audio upload_document find_location
|
||||
# $1 chat $2 typing upload_photo record_video upload_video record_audio upload_audio upload_document find_location
|
||||
send_action() {
|
||||
[ -z "$2" ] && return
|
||||
sendJson "$1" '"action": "'"$2"'"' "${URL}/sendChatAction" &
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
|
||||
}
|
||||
|
||||
# $1 chat $2 emoji “🎲”, “🎯”, “🏀”, “⚽”, “🎰" "🎳"
|
||||
# code: "\ud83c\udfb2" "\ud83c\udfaf" "\ud83c\udfc0" "\u26bd" "\ud83c\udfb0"
|
||||
# text: ":game_die:" ":dart:" ":basketball:" ":soccer:" :slot_machine:"
|
||||
# $3 reply_to_id
|
||||
send_dice() {
|
||||
local reply emoji='\ud83c\udfb2' # default "🎲"
|
||||
[[ "$3" =~ ^[${o9o9o9}-]+$ ]] && reply=',"reply_to_message_id":'"$3"',"allow_sending_without_reply": true'
|
||||
case "$2" in # convert input to single character emoji
|
||||
*🎲*|*game*|*dice*|*'dfb2'*|*'DFB2'*) : ;;
|
||||
*🎯*|*dart* |*'dfaf'*|*'DFAF'*) emoji='\ud83c\udfaf' ;;
|
||||
*🏀*|*basket*|*'dfc0'*|*'DFC0'*) emoji='\ud83c\udfc0' ;;
|
||||
*⚽*|*soccer*|*'26bd'*|*'26BD'*) emoji='\u26bd' ;;
|
||||
*🎰*|*slot* |*'dfb0'*|*'DFB0'*) emoji='\ud83c\udfb0' ;;
|
||||
*🎳*|*bowl* |*'dfb3'*|*'DFB3'*) emoji='\ud83c\udfb3' ;;
|
||||
esac
|
||||
sendJson "$1" '"emoji": "'"${emoji}"'"'"${reply}" "${URL}/sendDice"
|
||||
if [ "${BOTSENT[OK]}" = "true" ]; then
|
||||
BOTSENT[DICE]="${UPD["result,dice,emoji"]}"
|
||||
BOTSENT[RESULT]="${UPD["result,dice,value"]}"
|
||||
else
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
# $1 CHAT $2 lat $3 long
|
||||
send_location() {
|
||||
[ -z "$3" ] && return
|
||||
sendJson "$1" '"latitude": '"$2"', "longitude": '"$3"'' "${URL}/sendLocation"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
|
||||
}
|
||||
|
||||
# $1 CHAT $2 lat $3 long $4 title $5 address $6 foursquard id
|
||||
# $1 CHAT $2 lat $3 long $4 title $5 address $6 foursquare id
|
||||
send_venue() {
|
||||
local add=""
|
||||
[ -z "$5" ] && return
|
||||
[ -n "$6" ] && add=', "foursquare_id": '"$6"''
|
||||
sendJson "$1" '"latitude": '"$2"', "longitude": '"$3"', "address": "'"$5"'", "title": "'"$4"'"'"${add}" "${URL}/sendVenue"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3" "$4" "$5" "$6"
|
||||
}
|
||||
|
||||
|
||||
|
@ -294,9 +390,16 @@ send_venue() {
|
|||
forward_message() {
|
||||
[ -z "$3" ] && return
|
||||
sendJson "$1" '"from_chat_id": '"$2"', "message_id": '"$3"'' "${URL}/forwardMessage"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
|
||||
}
|
||||
forward() { # backward compatibility
|
||||
forward_message "$@" || return
|
||||
|
||||
# $1 CHAT $2 from chat $3 from msg id
|
||||
copy_message() {
|
||||
[ -z "$3" ] && return
|
||||
sendJson "$1" '"from_chat_id": '"$2"', "message_id": '"$3"'' "${URL}/copyMessage"
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
|
||||
}
|
||||
|
||||
# $1 CHAT $2 bashbot formatted message, see manual advanced usage
|
||||
|
@ -323,7 +426,7 @@ send_message() {
|
|||
sent=y
|
||||
fi
|
||||
if [ -n "${keyboard}" ]; then
|
||||
if [[ "${keyboard}" != *"["* ]]; then # pre 0.60 style
|
||||
if [[ "${keyboard}" != *"["* ]]; then # pre 0.60 style
|
||||
keyboard="[ ${keyboard//\" \"/\" \] , \[ \"} ]"
|
||||
fi
|
||||
send_keyboard "$1" "${text}" "${keyboard}"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC2034
|
||||
#######################################################
|
||||
#
|
||||
# File: mycommands.conf
|
||||
|
@ -11,7 +12,7 @@
|
|||
# Author: KayM (gnadelwartz), kay@rrr.de
|
||||
# Created: 09.01.2021 07:27
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#######################################################
|
||||
|
||||
##########
|
||||
|
@ -46,6 +47,10 @@ Edit commands and messages in mycommands.sh!
|
|||
# To enable this option in your bot, send the /setinline command to @BotFather.
|
||||
export INLINE="0"
|
||||
|
||||
# Set CALLBACK to 1 in order to receive callback queries.
|
||||
# callbacks are sent from inline_keyboards (buttons) attached tp bot messages
|
||||
export CALLBACK="0"
|
||||
|
||||
# if your bot is group admin it get commands sent to other bots
|
||||
# Set MEONLY to 1 to ignore commands sent to other bots
|
||||
export MEONLY="0"
|
||||
|
@ -63,7 +68,11 @@ unset BASHBOT_RETRY
|
|||
|
||||
# set value for adaptive sleeping while waiting for uodates in millisconds
|
||||
# max slepp between polling updates 10s (default 5s)
|
||||
export BASHBOT_SLEEP="10000"
|
||||
# export BASHBOT_SLEEP="10000"
|
||||
|
||||
# max slepp between polling updates 2s (default 5s)
|
||||
# export BASHBOT_SLEEP="2000"
|
||||
|
||||
# add 0.2s if no update available, up to BASHBOT_SLEEP (default 0.1s)
|
||||
export BASHBOT_SLEEP_STEP="200"
|
||||
|
||||
|
@ -87,6 +96,9 @@ WELCOME_MSG="Welcome"
|
|||
# export REPORT_NEWMEMBER="yes"
|
||||
# export REPORT_LEFTMEMBER="yes"
|
||||
|
||||
# uncomment to send user blocked by bot a warning if they send commands
|
||||
# export NOTIFY_BLOCKED_USERS="yes"
|
||||
|
||||
# messages for admin only commands
|
||||
NOTADMIN="Sorry, this command is allowed for admin or owner only"
|
||||
NOTBOTADMIN="Sorry, this command is allowed for bot owner only"
|
||||
|
|
104
mycommands.sh
104
mycommands.sh
|
@ -13,7 +13,7 @@
|
|||
# License: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# Author: KayM (gnadelwartz), kay@rrr.de
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#######################################################
|
||||
# shellcheck disable=SC1117
|
||||
|
||||
|
@ -106,12 +106,12 @@ else
|
|||
"${WELCOME_MSG} ${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]} (@${NEWMEMBER[USERNAME]})"
|
||||
MYSENTID="${BOTSENT[ID]}"
|
||||
{ sleep 5; delete_message "${CHAT[ID]}" "${MYSENTID}"; } &
|
||||
[ -n "${REPORT_NEWMEMBER}" ] && send_normal_message "$(getConfigKey "botadmin")"\
|
||||
[ -n "${REPORT_NEWMEMBER}" ] && send_normal_message "${BOTADMIN}"\
|
||||
"New member: ${CHAT[TITLE]} (${CHAT[ID]}): ${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]} (@${NEWMEMBER[USERNAME]})"
|
||||
fi
|
||||
;;
|
||||
'/_left_chat_member'*)
|
||||
[ -n "${REPORT_LEFTMEMBER}" ] && send_normal_message "$(getConfigKey "botadmin")"\
|
||||
[ -n "${REPORT_LEFTMEMBER}" ] && send_normal_message "${BOTADMIN}"\
|
||||
"Left member: ${CHAT[TITLE]} (${CHAT[ID]}): ${LEFTMEMBER[FIRST_NAME]} ${LEFTMEMBER[LAST_NAME]} (@${LEFTMEMBER[USERNAME]})"
|
||||
;;
|
||||
'/_migrate_group'*)
|
||||
|
@ -123,7 +123,26 @@ else
|
|||
|
||||
case "${MESSAGE}" in
|
||||
##################
|
||||
# example commands, replace thm by your own
|
||||
# example commands, replace them by your own
|
||||
'/_dice_re'*) # dice from user received
|
||||
sleep 5
|
||||
local gameresult="*Congratulation ${USER[FIRST_NAME]} ${USER[LAST_NAME]}* you got *${MESSAGE[RESULT]} Points*."
|
||||
[ -z "${FORWARD[UID]}" ] && send_markdownv2_message "${CHAT[ID]}" "${gameresult}"
|
||||
;;
|
||||
'/game'*) # send random dice, edit list to fit your needs
|
||||
send_dice "${CHAT[ID]}" ":$(printf "slot_machine\ngame_die\ndart\nbasketball\nsoccer\nslot_machine"|sort -R|shuf -n 1shuf -n 1):"
|
||||
if [ "${BOTSENT[OK]}" = "true" ]; then
|
||||
local gameresult="*Congratulation ${USER[FIRST_NAME]}* ${USER[LAST_NAME]} you got *${BOTSENT[RESULT]} Points*."
|
||||
sleep 5
|
||||
case "${BOTSENT[RESULT]}" in
|
||||
1) gameresult="*Sorry* only *one Point* ...";;
|
||||
2) gameresult="*Hey*, 2 Points are *more then one!*";;
|
||||
5|6) [[ "${BOTSENT[EMOJI]}" =~ fb0$ ]] || gameresult="*Super! ${BOTSENT[RESULT]} Points!*";;
|
||||
6*) gameresult="*JACKPOT! ${BOTSENT[RESULT]} Points!*";;
|
||||
esac
|
||||
send_markdownv2_message "${CHAT[ID]}" "${gameresult}"
|
||||
fi
|
||||
;;
|
||||
'/unpin'*) # unpin all messages if (bot)admin or allowed for user
|
||||
user_is_allowed "${USER[ID]}" "unpin" "${CHAT[ID]}" &&\
|
||||
unpinall_chat_messages "${CHAT[ID]}"
|
||||
|
@ -131,6 +150,9 @@ else
|
|||
'/echo'*) # example echo command
|
||||
send_normal_message "${CHAT[ID]}" "${MESSAGE}"
|
||||
;;
|
||||
'/button'*)# inline button, set CALLBACK=1 for processing callbacks
|
||||
send_inline_buttons "${CHAT[ID]}" "Press Button ..." " Button |RANDOM-BUTTON"
|
||||
;;
|
||||
'/question'*) # start interactive questions
|
||||
checkproc
|
||||
if [ "${res}" -gt 0 ] ; then
|
||||
|
@ -179,6 +201,47 @@ else
|
|||
esac
|
||||
}
|
||||
|
||||
mycallbacks() {
|
||||
#######################
|
||||
# callbacks from buttons attached to messages will be processed here
|
||||
# no standard use case for processing callbacks, let's log them for some users and chats
|
||||
case "${iBUTTON[USER_ID]}+${iBUTTON[CHAT_ID]}" in
|
||||
'USERID1+'*) # do something for all callbacks from USER
|
||||
printf "%s: U=%s C=%s D=%s\n" "$(date)" "${iBUTTON[USER_ID]}" "${iBUTTON[CHAT_ID]}" "${iBUTTON[DATA]}"\
|
||||
>>"${DATADIR}/${iBUTTON[USER_ID]}.log"
|
||||
answer_callback_query "${iBUTTON[ID]}" "Request has been logged in your user log..."
|
||||
return
|
||||
;;
|
||||
*'+CHATID1') # do something for all callbacks from CHAT
|
||||
printf "%s: U=%s C=%s D=%s\n" "$(date)" "${iBUTTON[USER_ID]}" "${iBUTTON[CHAT_ID]}" "${iBUTTON[DATA]}"\
|
||||
>>"${DATADIR}/${iBUTTON[CHAT_ID]}.log"
|
||||
answer_callback_query "${iBUTTON[ID]}" "Request has been logged in chat log..."
|
||||
return
|
||||
;;
|
||||
'USERID2+CHATID2') # do something only for callbacks form USER in CHAT
|
||||
printf "%s: U=%s C=%s D=%s\n" "$(date)" "${iBUTTON[USER_ID]}" "${iBUTTON[CHAT_ID]}" "${iBUTTON[DATA]}"\
|
||||
>>"${DATADIR}/${iBUTTON[USER_ID]}-${iBUTTON[CHAT_ID]}.log"
|
||||
answer_callback_query "${iBUTTON[ID]}" "Request has been logged in user-chat log..."
|
||||
return
|
||||
;;
|
||||
*) # all other callbacks are processed here
|
||||
local callback_answer
|
||||
# your processing here ...
|
||||
# message available?
|
||||
if [[ -n "${iBUTTON[CHAT_ID]}" && -n "${iBUTTON[MESSAGE_ID]}" ]]; then
|
||||
if [ "${iBUTTON[DATA]}" = "RANDOM-BUTTON" ]; then
|
||||
callback_answer="Button pressed"
|
||||
edit_inline_buttons "${iBUTTON[CHAT_ID]}" "${iBUTTON[MESSAGE_ID]}" "Button ${RANDOM}|RANDOM-BUTTON"
|
||||
fi
|
||||
else
|
||||
callback_answer="Button to old, sorry."
|
||||
fi
|
||||
# Telegram needs an ack each callback query, default empty
|
||||
answer_callback_query "${iBUTTON[ID]}" "${callback_answer}"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
myinlines() {
|
||||
#######################
|
||||
# Inline query examples, do not use them in production (except image search ;-)
|
||||
|
@ -237,6 +300,8 @@ else
|
|||
[ -f ".jssh" ] && printf "%s: %s\n" "$1" "Ups, found file \"${PWD:-.}/.jssh\"! =========="
|
||||
}
|
||||
|
||||
###########################
|
||||
# example recover from telegram block function
|
||||
# called when bashbot send_xxx command failed because we can not connect to telegram
|
||||
# return 0 to retry, return non 0 to give up
|
||||
bashbotBlockRecover() {
|
||||
|
@ -247,7 +312,35 @@ else
|
|||
return 1
|
||||
}
|
||||
|
||||
# place your processing functions here
|
||||
###########################
|
||||
# example error processing
|
||||
# called when delete Message failed
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
bashbotError_delete_message() {
|
||||
log_debug "custom errorProcessing delete_message: ERR=$2 CHAT=$3 MSGID=$6 ERTXT=$5"
|
||||
}
|
||||
|
||||
# called when error 403 is returned (and no func processing)
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
bashbotError_403() {
|
||||
log_debug "custom errorProcessing error 403: FUNC=$1 CHAT=$3 USER=${4:-no-user} MSGID=$6 ERTXT=$5"
|
||||
local user="$4"; [[ -z "$4" && -n "$3" ]] && user="$3"
|
||||
if [ -n "${user}" ]; then
|
||||
# block chat/user
|
||||
case "$5" in
|
||||
*"blocked"*)
|
||||
jssh_insertKeyDB "${user}" "User blocked bot on $(LANG=C date)" "${BLOCKEDFILE}";;
|
||||
*"kicked"*)
|
||||
jssh_insertKeyDB "${user}" "Bot kicked from chat on $(LANG=C date)" "${BLOCKEDFILE}";;
|
||||
*)
|
||||
jssh_insertKeyDB "${user}" "Reason: $6 on $(LANG=C date)" "${BLOCKEDFILE}";;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
###########################
|
||||
# place your processing functions here --------------
|
||||
|
||||
# $1 search parameter
|
||||
my_image_search(){
|
||||
|
@ -263,3 +356,4 @@ else
|
|||
}
|
||||
|
||||
fi
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# License: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# Author: KayM (gnadelwartz), kay@rrr.de
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#######################################################
|
||||
# shellcheck disable=SC1117
|
||||
|
||||
|
@ -55,6 +55,8 @@ else
|
|||
[ -n "${REMOVEKEYBOARD}" ] && remove_keyboard "${CHAT[ID]}" &
|
||||
[[ -n "${REMOVEKEYBOARD_PRIVATE}" && "${CHAT[ID]}" == "${USER[ID]}" ]] && remove_keyboard "${CHAT[ID]}" &
|
||||
|
||||
# uncommet to fix first letter upper case because of smartphone auto correction
|
||||
#[[ "${MESSAGE}" =~ ^/[[:upper:]] ]] && MESSAGE="${MESSAGE:0:1}$(tr '[:upper:]' '[:lower:]' <<<"${MESSAGE:1:1}")${MESSAGE:2}"
|
||||
case "${MESSAGE}" in
|
||||
##################
|
||||
# example command, replace them by your own
|
||||
|
@ -77,6 +79,19 @@ else
|
|||
esac
|
||||
}
|
||||
|
||||
mycallbacks() {
|
||||
#######################
|
||||
# callbacks from buttons attached to messages will be processed here
|
||||
case "${iBUTTON[USER_ID]}+${iBUTTON[CHAT_ID]}" in
|
||||
*) # all other callbacks are processed here
|
||||
local callback_answer
|
||||
: # your processing here ...
|
||||
:
|
||||
# Telegram needs an ack each callback query, default empty
|
||||
answer_callback_query "${iBUTTON[ID]}" "${callback_answer}"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
myinlines() {
|
||||
#######################
|
||||
# this fuinction is called only if you has set INLINE=1 !!
|
||||
|
@ -111,4 +126,17 @@ else
|
|||
done <<<"${result}"
|
||||
}
|
||||
|
||||
###########################
|
||||
# example error processing
|
||||
# called when delete Message failed
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
bashbotError_delete_message() {
|
||||
log_debug "custom errorProcessing delete_message: ERR=$2 CHAT=$3 MSGID=$6 ERTXT=$5"
|
||||
}
|
||||
|
||||
# called when error 403 is returned (and no func processing)
|
||||
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
|
||||
bashbotError_403() {
|
||||
log_debug "custom errorProcessing error 403: FUNC=$1 CHAT=$3 USER=${4:-no-user} MSGID=$6 ERTXT=$5"
|
||||
}
|
||||
fi
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
########################################################################
|
||||
|
||||
######
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
# magic to ensure that we're always inside the root of our application,
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
# common variables
|
||||
|
@ -39,12 +39,12 @@ export SUCCESS NOSUCCESS
|
|||
NOSUCCESS=" FAILED!"
|
||||
|
||||
# default input, reference and output files
|
||||
export INPUTFILE REFFILE INPUTFILE2 REFFILE2 OUTPUTFILE
|
||||
export INPUTFILE REFFILE OUTPUTFILE INPUTFILELIST
|
||||
# shellcheck disable=SC2125
|
||||
INPUTFILELIST="${DIRME}/${REFDIR}/${REFDIR}-"*".input"
|
||||
OUTPUTFILE="${TESTDIR}/${REFDIR}.out"
|
||||
INPUTFILE="${DIRME}/${REFDIR}/${REFDIR}.input"
|
||||
REFFILE="${DIRME}/${REFDIR}/${REFDIR}.result"
|
||||
INPUTFILE2="${DIRME}/${REFDIR}/${REFDIR}2.input"
|
||||
REFFILE2="${DIRME}/${REFDIR}/${REFDIR}2.result"
|
||||
|
||||
# reset ENVIRONMENT
|
||||
export BASHBOT_URL TESTTOKEN BOTTOKEN BASHBOT_HOME BASHBOT_VAR BASHBOT_ETC
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
../dev/hooks/pre-commit.sh
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
# include common functions and definitions
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
# include common functions and definitions
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
# include common functions and definitions
|
||||
# shellcheck source=test/ALL-tests.inc.sh
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
# include common functions and definitions
|
||||
|
@ -41,7 +41,7 @@ source <( printf 'UPD=( %s )' "$(sed <<<"${UPDATE}" -E -e 's/\t/=/g' -e 's/=(tru
|
|||
printf "Check process_inline ...\n"
|
||||
printf " ... with JsonDecode Bash\n"
|
||||
set -x
|
||||
{ process_inline "0"; set +x; } >>"${LOGFILE}" 2>&1;
|
||||
{ process_inline_query "0"; set +x; } >>"${LOGFILE}" 2>&1;
|
||||
|
||||
# output processed input
|
||||
print_array "iQUERY" >"${OUTPUTFILE}"
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
# include common functions and definitions
|
||||
|
@ -38,34 +38,24 @@ declare -Ax UPD
|
|||
# run process_message --------------
|
||||
ARRAYS="USER CHAT REPLYTO FORWARD URLS CONTACT CAPTION LOCATION MESSAGE VENUE SERVICE NEWMEMBER LEFTMEMBER PINNED"
|
||||
|
||||
printf "Check process_message regular message...\n"
|
||||
printf "Check process_message ...\n"
|
||||
|
||||
UPDATE="$(< "${INPUTFILE}")"
|
||||
Json2Array 'UPD' <"${INPUTFILE}"
|
||||
set -x
|
||||
{ pre_process_message "0"; process_message "0"; set +x; } >>"${LOGFILE}" 2>&1;
|
||||
USER[ID]="123456789"; CHAT[ID]="123456789"
|
||||
for testfile in ${INPUTFILELIST}
|
||||
do
|
||||
printf " ... %s\n" "${testfile##*/}"
|
||||
testref="${testfile%.input}.result"
|
||||
UPDATE="$(< "${testfile}")"
|
||||
Json2Array 'UPD' <"${testfile}"
|
||||
set -x
|
||||
{ pre_process_message "0"; process_message "0"; set +x; } >>"${LOGFILE}" 2>&1;
|
||||
USER[ID]="123456789"; CHAT[ID]="123456789"
|
||||
|
||||
# output processed input
|
||||
# shellcheck disable=SC2086
|
||||
print_array ${ARRAYS} >"${OUTPUTFILE}"
|
||||
compare_sorted "${REFFILE}" "${OUTPUTFILE}" || exit 1
|
||||
# output processed input
|
||||
# shellcheck disable=SC2086
|
||||
print_array ${ARRAYS} >"${OUTPUTFILE}"
|
||||
compare_sorted "${testref}" "${OUTPUTFILE}" || exit 1
|
||||
printf "%s\n" "${SUCCESS}"
|
||||
|
||||
# run process_message ------------
|
||||
printf "Check process_message service message...\n"
|
||||
|
||||
UPDATE="$(cat "${INPUTFILE2}")"
|
||||
Json2Array 'UPD' <"${INPUTFILE2}"
|
||||
set -x
|
||||
{ pre_process_message "0"; process_message "0"; set +x; } >>"${LOGFILE}" 2>&1;
|
||||
USER[ID]="123456789"; CHAT[ID]="123456789"
|
||||
|
||||
# output processed input
|
||||
# shellcheck disable=SC2086
|
||||
print_array ${ARRAYS} >"${OUTPUTFILE}"
|
||||
compare_sorted "${REFFILE2}" "${OUTPUTFILE}" || exit 1
|
||||
|
||||
|
||||
printf "%s\n" "${SUCCESS}"
|
||||
done
|
||||
|
||||
cd "${DIRME}" || exit 1
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
["ok"] true
|
||||
["result",0,"update_id"] 123456789
|
||||
["result",0,"message","message_id"] 123456789
|
||||
["result",0,"message","from","id"] 123456789
|
||||
["result",0,"message","from","is_bot"] false
|
||||
["result",0,"message","from","first_name"] "Kay"
|
||||
["result",0,"message","from","last_name"] "M"
|
||||
["result",0,"message","from","username"] "Gnadelwartz"
|
||||
["result",0,"message","from","language_code"] "de"
|
||||
["result",0,"message","chat","id"] -123456789
|
||||
["result",0,"message","chat","title"] "Testgruppe bot only test"
|
||||
["result",0,"message","chat","type"] "group"
|
||||
["result",0,"message","chat","all_members_are_administrators"] true
|
||||
["result",0,"message","date"] 1592372719
|
||||
|
||||
["result",0,"message","left_chat_participant","id"] 123456789
|
||||
["result",0,"message","left_chat_participant","is_bot"] false
|
||||
["result",0,"message","left_chat_participant","first_name"] "Kay"
|
||||
["result",0,"message","left_chat_participant","last_name"] "M"
|
||||
["result",0,"message","left_chat_participant","username"] "Gnadelwartz"
|
||||
["result",0,"message","left_chat_member","id"] 123456789
|
||||
["result",0,"message","left_chat_member","is_bot"] false
|
||||
["result",0,"message","left_chat_member","first_name"] "Kay"
|
||||
["result",0,"message","left_chat_member","last_name"] "M"
|
||||
["result",0,"message","left_chat_member","username"] "Gnadelwartz"
|
|
@ -0,0 +1,25 @@
|
|||
USER: FIRST_NAME Kay
|
||||
USER: ID 123456789
|
||||
USER: LAST_NAME M
|
||||
USER: USERNAME Gnadelwartz
|
||||
CHAT: ALL_ADMIN true
|
||||
CHAT: FIRST_NAME
|
||||
CHAT: ID 123456789
|
||||
CHAT: LAST_NAME
|
||||
CHAT: TITLE Testgruppe bot only test
|
||||
CHAT: TYPE group
|
||||
CHAT: USERNAME
|
||||
CAPTION: 0
|
||||
LOCATION: LATITUDE
|
||||
LOCATION: LONGITUDE
|
||||
MESSAGE: 0 /_left_chat_member Kay M
|
||||
MESSAGE: CAPTION
|
||||
MESSAGE: DICE
|
||||
MESSAGE: ID 123456789
|
||||
SERVICE: 0 yes
|
||||
SERVICE: LEFTMEMBER 123456789
|
||||
LEFTMEMBER: FIRST_NAME Kay
|
||||
LEFTMEMBER: ID
|
||||
LEFTMEMBER: ISBOT false
|
||||
LEFTMEMBER: LAST_NAME M
|
||||
LEFTMEMBER: USERNAME Kay M
|
|
@ -31,11 +31,13 @@ CONTACT: LAST_NAME Pannenhilfe
|
|||
CONTACT: NUMBER 222222
|
||||
CONTACT: USER_ID
|
||||
CONTACT: VCARD BEGIN:VCARD\nVERSION:2.1\nN:Pannenhilfe;ADAC;;;\nFN:ADAC Pannenhilfe\nTEL;CELL;PREF:+49179222222\nTEL;X-Mobil:222222\nEND:VCARD
|
||||
CAPTION: 0
|
||||
CAPTION: 0 Myproteine kein spell check
|
||||
LOCATION: LATITUDE 49.631824
|
||||
LOCATION: LONGITUDE 8.377072
|
||||
MESSAGE: 0 😂😝👌☺❤😕😈#⃣🌏🎉🙊🙉☕🚀✈🚂💯✔〽🔚
|
||||
MESSAGE: ID 6541
|
||||
MESSAGE: CAPTION Myproteine kein spell check
|
||||
MESSAGE: DICE
|
||||
VENUE: ADDRESS Am Rhein 1
|
||||
VENUE: FOURSQUARE 4c4321afce54e21eee980d1a
|
||||
VENUE: LATITUDE 49.631824
|
|
@ -89,3 +89,7 @@
|
|||
["result",0,"message","voice","duration"] 2
|
||||
["result",0,"message","voice","mime_type"] "audio/ogg"
|
||||
["result",0,"message","voice","file_size"] 4262
|
||||
["result",0,"message","caption"] "Myproteine kein spell check"
|
||||
["result","dice","emoji"] "\ud83c\udfb2"
|
||||
["result","dice","value"] 5
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
USER: FIRST_NAME Kay
|
||||
USER: ID 123456789
|
||||
USER: LAST_NAME M
|
||||
USER: USERNAME Gnadelwartz
|
||||
CHAT: ALL_ADMIN
|
||||
CHAT: FIRST_NAME Test
|
||||
CHAT: ID 123456789
|
||||
CHAT: LAST_NAME Bot
|
||||
CHAT: TITLE BotTestTitle
|
||||
CHAT: TYPE private
|
||||
CHAT: USERNAME BotTest
|
||||
REPLYTO: 0 Ich bin der Deal-O-Mat Bot. Für eine Liste der Befehle sende /help
|
||||
REPLYTO: FIRST_NAME dealzbot
|
||||
REPLYTO: ID 6542
|
||||
REPLYTO: LAST_NAME
|
||||
REPLYTO: UID 987654321
|
||||
REPLYTO: USERNAME Deal_O_Mat_bot
|
||||
FORWARD: FIRST_NAME Kay
|
||||
FORWARD: ID 6541
|
||||
FORWARD: LAST_NAME M
|
||||
FORWARD: UID 123456789
|
||||
FORWARD: USERNAME Gnadelwartz
|
||||
URLS: AUDIO audio-AgADAgADL6oxG-Gw4EndCWGl2WUfUo1pXw8ABOusSilDGzAYa
|
||||
URLS: DOCUMENT document-AgADAgADL6oxG-Gw4EndCWGl2WUfUo1pXw8ABOusSilDGzAYa
|
||||
URLS: PHOTO photo-AgADAgADL6oxG-Gw4EndCWGl2WUfUo1pXw8ABOusSilDGzAYa
|
||||
URLS: STICKER sticker-AgADAgADL6oxG-Gw4EndCWGl2WUfUo1pXw8ABOusSilDGzAYa
|
||||
URLS: VIDEO video-AgADAgADL6oxG-Gw4EndCWGl2WUfUo1pXw8ABOusSilDGzAYa
|
||||
URLS: VOICE voice-AgADAgADL6oxG-Gw4EndCWGl2WUfUo1pXw8ABOusSilDGzAYa
|
||||
CONTACT: FIRST_NAME ADAC
|
||||
CONTACT: LAST_NAME Pannenhilfe
|
||||
CONTACT: NUMBER 222222
|
||||
CONTACT: USER_ID
|
||||
CONTACT: VCARD BEGIN:VCARD\nVERSION:2.1\nN:Pannenhilfe;ADAC;;;\nFN:ADAC Pannenhilfe\nTEL;CELL;PREF:+49179222222\nTEL;X-Mobil:222222\nEND:VCARD
|
||||
CAPTION: 0 Myproteine kein spell check
|
||||
LOCATION: LATITUDE 49.631824
|
||||
LOCATION: LONGITUDE 8.377072
|
||||
MESSAGE: 0 😂😝👌☺❤😕😈#⃣🌏🎉🙊🙉☕🚀✈🚂💯✔〽🔚
|
||||
MESSAGE: CAPTION Myproteine kein spell check
|
||||
MESSAGE: DICE
|
||||
MESSAGE: ID 6541
|
||||
VENUE: ADDRESS Am Rhein 1
|
||||
VENUE: FOURSQUARE 4c4321afce54e21eee980d1a
|
||||
VENUE: LATITUDE 49.631824
|
||||
VENUE: LONGITUDE 8.377072
|
||||
VENUE: TITLE Kolb's Biergarten
|
|
@ -0,0 +1,25 @@
|
|||
["ok"] true
|
||||
["result",0,"update_id"] 123456789
|
||||
["result",0,"message","message_id"] 123456789
|
||||
["result",0,"message","from","id"] 123456789
|
||||
["result",0,"message","from","is_bot"] false
|
||||
["result",0,"message","from","first_name"] "Kay"
|
||||
["result",0,"message","from","last_name"] "M"
|
||||
["result",0,"message","from","username"] "Gnadelwartz"
|
||||
["result",0,"message","from","language_code"] "de"
|
||||
["result",0,"message","chat","id"] -123456789
|
||||
["result",0,"message","chat","title"] "Testgruppe bot only test"
|
||||
["result",0,"message","chat","type"] "group"
|
||||
["result",0,"message","chat","all_members_are_administrators"] true
|
||||
["result",0,"message","date"] 1592372719
|
||||
|
||||
["result",0,"message","new_chat_participant","id"] 123456789
|
||||
["result",0,"message","new_chat_participant","is_bot"] false
|
||||
["result",0,"message","new_chat_participant","first_name"] "Kay"
|
||||
["result",0,"message","new_chat_participant","last_name"] "M"
|
||||
["result",0,"message","new_chat_participant","username"] "Gnadelwartz"
|
||||
["result",0,"message","new_chat_member","id"] 123456789
|
||||
["result",0,"message","new_chat_member","is_bot"] false
|
||||
["result",0,"message","new_chat_member","first_name"] "Kay"
|
||||
["result",0,"message","new_chat_member","last_name"] "M"
|
||||
["result",0,"message","new_chat_member","username"] "Gnadelwartz"
|
|
@ -13,21 +13,15 @@ CAPTION: 0
|
|||
LOCATION: LATITUDE
|
||||
LOCATION: LONGITUDE
|
||||
MESSAGE: 0 /_new_chat_member 123456789 Gnadelwartz
|
||||
MESSAGE: CAPTION
|
||||
MESSAGE: DICE
|
||||
MESSAGE: ID 123456789
|
||||
SERVICE: 0 yes
|
||||
SERVICE: LEFTMEMBER 123456789
|
||||
SERVICE: NEWMEMBER 123456789
|
||||
SERVICE: NEWPHOTO AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANhAAM3SAMAARoE
|
||||
SERVICE: NEWTITLE new Testgruppe bot only
|
||||
SERVICE: PINNED 3022
|
||||
SERVICE: NEWPHOTO
|
||||
SERVICE: NEWTITLE
|
||||
NEWMEMBER: FIRST_NAME Kay
|
||||
NEWMEMBER: ID 123456789
|
||||
NEWMEMBER: ISBOT false
|
||||
NEWMEMBER: LAST_NAME M
|
||||
NEWMEMBER: USERNAME Gnadelwartz
|
||||
LEFTMEMBER: FIRST_NAME Kay
|
||||
LEFTMEMBER: ID
|
||||
LEFTMEMBER: ISBOT false
|
||||
LEFTMEMBER: LAST_NAME M
|
||||
PINNED: ID 3022
|
||||
PINNED: MESSAGE new pinned Message
|
|
@ -0,0 +1,30 @@
|
|||
["ok"] true
|
||||
["result",0,"update_id"] 123456789
|
||||
["result",0,"message","message_id"] 123456789
|
||||
["result",0,"message","from","id"] 123456789
|
||||
["result",0,"message","from","is_bot"] false
|
||||
["result",0,"message","from","first_name"] "Kay"
|
||||
["result",0,"message","from","last_name"] "M"
|
||||
["result",0,"message","from","username"] "Gnadelwartz"
|
||||
["result",0,"message","from","language_code"] "de"
|
||||
["result",0,"message","chat","id"] -123456789
|
||||
["result",0,"message","chat","title"] "Testgruppe bot only test"
|
||||
["result",0,"message","chat","type"] "group"
|
||||
["result",0,"message","chat","all_members_are_administrators"] true
|
||||
["result",0,"message","date"] 1592372719
|
||||
|
||||
["result",0,"message","new_chat_photo",0,"file_id"] "AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANhAAM3SAMAARoE"
|
||||
["result",0,"message","new_chat_photo",0,"file_unique_id"] "AQADK6S6ki4AAzdIAwAB"
|
||||
["result",0,"message","new_chat_photo",0,"file_size"] 5939
|
||||
["result",0,"message","new_chat_photo",0,"width"] 160
|
||||
["result",0,"message","new_chat_photo",0,"height"] 160
|
||||
["result",0,"message","new_chat_photo",1,"file_id"] "AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANiAAM4SAMAARoE"
|
||||
["result",0,"message","new_chat_photo",1,"file_unique_id"] "AQADK6S6ki4AAzhIAwAB"
|
||||
["result",0,"message","new_chat_photo",1,"file_size"] 14124
|
||||
["result",0,"message","new_chat_photo",1,"width"] 320
|
||||
["result",0,"message","new_chat_photo",1,"height"] 320
|
||||
["result",0,"message","new_chat_photo",2,"file_id"] "AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANjAAM5SAMAARoE"
|
||||
["result",0,"message","new_chat_photo",2,"file_unique_id"] "AQADK6S6ki4AAzlIAwAB"
|
||||
["result",0,"message","new_chat_photo",2,"file_size"] 34052
|
||||
["result",0,"message","new_chat_photo",2,"width"] 640
|
||||
["result",0,"message","new_chat_photo",2,"height"] 640
|
|
@ -0,0 +1,21 @@
|
|||
USER: FIRST_NAME Kay
|
||||
USER: ID 123456789
|
||||
USER: LAST_NAME M
|
||||
USER: USERNAME Gnadelwartz
|
||||
CHAT: ALL_ADMIN true
|
||||
CHAT: FIRST_NAME
|
||||
CHAT: ID 123456789
|
||||
CHAT: LAST_NAME
|
||||
CHAT: TITLE Testgruppe bot only test
|
||||
CHAT: TYPE group
|
||||
CHAT: USERNAME
|
||||
CAPTION: 0
|
||||
LOCATION: LATITUDE
|
||||
LOCATION: LONGITUDE
|
||||
MESSAGE: 0 /_new_chat_photo 123456789 AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANhAAM3SAMAARoE
|
||||
MESSAGE: CAPTION
|
||||
MESSAGE: DICE
|
||||
MESSAGE: ID 123456789
|
||||
SERVICE: 0 yes
|
||||
SERVICE: NEWPHOTO AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANhAAM3SAMAARoE
|
||||
SERVICE: NEWTITLE
|
|
@ -0,0 +1,16 @@
|
|||
["ok"] true
|
||||
["result",0,"update_id"] 123456789
|
||||
["result",0,"message","message_id"] 123456789
|
||||
["result",0,"message","from","id"] 123456789
|
||||
["result",0,"message","from","is_bot"] false
|
||||
["result",0,"message","from","first_name"] "Kay"
|
||||
["result",0,"message","from","last_name"] "M"
|
||||
["result",0,"message","from","username"] "Gnadelwartz"
|
||||
["result",0,"message","from","language_code"] "de"
|
||||
["result",0,"message","chat","id"] -123456789
|
||||
["result",0,"message","chat","title"] "Testgruppe bot only test"
|
||||
["result",0,"message","chat","type"] "group"
|
||||
["result",0,"message","chat","all_members_are_administrators"] true
|
||||
["result",0,"message","date"] 1592372719
|
||||
|
||||
["result",0,"message","new_chat_title"] "new Testgruppe bot only"
|
|
@ -0,0 +1,21 @@
|
|||
USER: FIRST_NAME Kay
|
||||
USER: ID 123456789
|
||||
USER: LAST_NAME M
|
||||
USER: USERNAME Gnadelwartz
|
||||
CHAT: ALL_ADMIN true
|
||||
CHAT: FIRST_NAME
|
||||
CHAT: ID 123456789
|
||||
CHAT: LAST_NAME
|
||||
CHAT: TITLE Testgruppe bot only test
|
||||
CHAT: TYPE group
|
||||
CHAT: USERNAME
|
||||
CAPTION: 0
|
||||
LOCATION: LATITUDE
|
||||
LOCATION: LONGITUDE
|
||||
MESSAGE: 0 /_new_chat_title 123456789 new Testgruppe bot only
|
||||
MESSAGE: CAPTION
|
||||
MESSAGE: DICE
|
||||
MESSAGE: ID 123456789
|
||||
SERVICE: 0 yes
|
||||
SERVICE: NEWPHOTO
|
||||
SERVICE: NEWTITLE new Testgruppe bot only
|
|
@ -0,0 +1,27 @@
|
|||
["ok"] true
|
||||
["result",0,"update_id"] 123456789
|
||||
["result",0,"message","message_id"] 123456789
|
||||
["result",0,"message","from","id"] 123456789
|
||||
["result",0,"message","from","is_bot"] false
|
||||
["result",0,"message","from","first_name"] "Kay"
|
||||
["result",0,"message","from","last_name"] "M"
|
||||
["result",0,"message","from","username"] "Gnadelwartz"
|
||||
["result",0,"message","from","language_code"] "de"
|
||||
["result",0,"message","chat","id"] -123456789
|
||||
["result",0,"message","chat","title"] "Testgruppe bot only test"
|
||||
["result",0,"message","chat","type"] "group"
|
||||
["result",0,"message","chat","all_members_are_administrators"] true
|
||||
["result",0,"message","date"] 1592372719
|
||||
|
||||
["result",0,"message","pinned_message","message_id"] 3022
|
||||
["result",0,"message","pinned_message","from","id"] 796814662
|
||||
["result",0,"message","pinned_message","from","is_bot"] true
|
||||
["result",0,"message","pinned_message","from","first_name"] "DealOMat"
|
||||
["result",0,"message","pinned_message","from","username"] "Deal_O_Mat_bot"
|
||||
["result",0,"message","pinned_message","chat","id"] -1001220313778
|
||||
["result",0,"message","pinned_message","chat","title"] "Testgruppe bot only test"
|
||||
["result",0,"message","pinned_message","chat","type"] "supergroup"
|
||||
["result",0,"message","pinned_message","date"] 1593121152
|
||||
["result",0,"message","pinned_message","text"] "new pinned Message"
|
||||
|
||||
["result",0,"message","new_chat_title"] "new Testgruppe bot only"
|
|
@ -0,0 +1,24 @@
|
|||
USER: FIRST_NAME Kay
|
||||
USER: ID 123456789
|
||||
USER: LAST_NAME M
|
||||
USER: USERNAME Gnadelwartz
|
||||
CHAT: ALL_ADMIN true
|
||||
CHAT: FIRST_NAME
|
||||
CHAT: ID 123456789
|
||||
CHAT: LAST_NAME
|
||||
CHAT: TITLE Testgruppe bot only test
|
||||
CHAT: TYPE group
|
||||
CHAT: USERNAME
|
||||
CAPTION: 0
|
||||
LOCATION: LATITUDE
|
||||
LOCATION: LONGITUDE
|
||||
MESSAGE: 0 /_new_pinned_message 123456789 3022 new pinned Message
|
||||
MESSAGE: CAPTION
|
||||
MESSAGE: DICE
|
||||
MESSAGE: ID 123456789
|
||||
SERVICE: 0 yes
|
||||
SERVICE: NEWPHOTO
|
||||
SERVICE: NEWTITLE new Testgruppe bot only
|
||||
SERVICE: PINNED 3022
|
||||
PINNED: ID 3022
|
||||
PINNED: MESSAGE new pinned Message
|
|
@ -1,65 +0,0 @@
|
|||
["ok"] true
|
||||
["result",0,"update_id"] 123456789
|
||||
["result",0,"message","message_id"] 123456789
|
||||
["result",0,"message","from","id"] 123456789
|
||||
["result",0,"message","from","is_bot"] false
|
||||
["result",0,"message","from","first_name"] "Kay"
|
||||
["result",0,"message","from","last_name"] "M"
|
||||
["result",0,"message","from","username"] "Gnadelwartz"
|
||||
["result",0,"message","from","language_code"] "de"
|
||||
["result",0,"message","chat","id"] -123456789
|
||||
["result",0,"message","chat","title"] "Testgruppe bot only test"
|
||||
["result",0,"message","chat","type"] "group"
|
||||
["result",0,"message","chat","all_members_are_administrators"] true
|
||||
["result",0,"message","date"] 1592372719
|
||||
|
||||
["result",0,"message","left_chat_participant","id"] 123456789
|
||||
["result",0,"message","left_chat_participant","is_bot"] false
|
||||
["result",0,"message","left_chat_participant","first_name"] "Kay"
|
||||
["result",0,"message","left_chat_participant","last_name"] "M"
|
||||
["result",0,"message","left_chat_participant","username"] "Gnadelwartz"
|
||||
["result",0,"message","left_chat_member","id"] 123456789
|
||||
["result",0,"message","left_chat_member","is_bot"] false
|
||||
["result",0,"message","left_chat_member","first_name"] "Kay"
|
||||
["result",0,"message","left_chat_member","last_name"] "M"
|
||||
["result",0,"message","left_chat_member","username"] "Gnadelwartz"
|
||||
|
||||
["result",0,"message","new_chat_participant","id"] 123456789
|
||||
["result",0,"message","new_chat_participant","is_bot"] false
|
||||
["result",0,"message","new_chat_participant","first_name"] "Kay"
|
||||
["result",0,"message","new_chat_participant","last_name"] "M"
|
||||
["result",0,"message","new_chat_participant","username"] "Gnadelwartz"
|
||||
["result",0,"message","new_chat_member","id"] 123456789
|
||||
["result",0,"message","new_chat_member","is_bot"] false
|
||||
["result",0,"message","new_chat_member","first_name"] "Kay"
|
||||
["result",0,"message","new_chat_member","last_name"] "M"
|
||||
["result",0,"message","new_chat_member","username"] "Gnadelwartz"
|
||||
|
||||
["result",0,"message","new_chat_photo",0,"file_id"] "AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANhAAM3SAMAARoE"
|
||||
["result",0,"message","new_chat_photo",0,"file_unique_id"] "AQADK6S6ki4AAzdIAwAB"
|
||||
["result",0,"message","new_chat_photo",0,"file_size"] 5939
|
||||
["result",0,"message","new_chat_photo",0,"width"] 160
|
||||
["result",0,"message","new_chat_photo",0,"height"] 160
|
||||
["result",0,"message","new_chat_photo",1,"file_id"] "AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANiAAM4SAMAARoE"
|
||||
["result",0,"message","new_chat_photo",1,"file_unique_id"] "AQADK6S6ki4AAzhIAwAB"
|
||||
["result",0,"message","new_chat_photo",1,"file_size"] 14124
|
||||
["result",0,"message","new_chat_photo",1,"width"] 320
|
||||
["result",0,"message","new_chat_photo",1,"height"] 320
|
||||
["result",0,"message","new_chat_photo",2,"file_id"] "AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANjAAM5SAMAARoE"
|
||||
["result",0,"message","new_chat_photo",2,"file_unique_id"] "AQADK6S6ki4AAzlIAwAB"
|
||||
["result",0,"message","new_chat_photo",2,"file_size"] 34052
|
||||
["result",0,"message","new_chat_photo",2,"width"] 640
|
||||
["result",0,"message","new_chat_photo",2,"height"] 640
|
||||
|
||||
["result",0,"message","pinned_message","message_id"] 3022
|
||||
["result",0,"message","pinned_message","from","id"] 796814662
|
||||
["result",0,"message","pinned_message","from","is_bot"] true
|
||||
["result",0,"message","pinned_message","from","first_name"] "DealOMat"
|
||||
["result",0,"message","pinned_message","from","username"] "Deal_O_Mat_bot"
|
||||
["result",0,"message","pinned_message","chat","id"] -1001220313778
|
||||
["result",0,"message","pinned_message","chat","title"] "Testgruppe bot only test"
|
||||
["result",0,"message","pinned_message","chat","type"] "supergroup"
|
||||
["result",0,"message","pinned_message","date"] 1593121152
|
||||
["result",0,"message","pinned_message","text"] "new pinned Message"
|
||||
|
||||
["result",0,"message","new_chat_title"] "new Testgruppe bot only"
|
|
@ -10,7 +10,7 @@
|
|||
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
#
|
||||
#### $$VERSION$$ v1.30-0-g3266427
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
# include common functions and definitions
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue