Compare commits
160 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 |
207
README.html
207
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>
|
||||
|
@ -291,28 +160,28 @@ Written by Drew (@topkecleon) and Kay M (@gnadelwartz).
|
|||
<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
|
||||
|
||||
|
@ -325,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>
|
||||
|
@ -335,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>
|
||||
|
@ -371,27 +242,27 @@ It features background tasks and interactive chats, and can serve as an interfac
|
|||
<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.40-dev-34-g1440d56</h4>
|
||||
<h4>$$VERSION$$ v1.52-0-g1a83202</h4>
|
||||
</body>
|
||||
</html>
|
||||
|
|
15
README.md
15
README.md
|
@ -10,6 +10,14 @@ 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)/[JSON.awk](https://github.com/step-/JSON.awk) and the magic of sed.
|
||||
|
||||
|
@ -146,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
|
||||
|
@ -241,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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
|
11
README.txt
11
README.txt
|
@ -200,10 +200,11 @@ 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 [https://github.com/koalaman/
|
||||
shellcheck#installing]. Shellcheck is used extensively in bashbot development to ensure a
|
||||
|
@ -318,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.40-dev-34-g1440d56
|
||||
$$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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
|
||||
|
|
196
bashbot.sh
196
bashbot.sh
|
@ -30,7 +30,7 @@ BOTCOMMANDS="-h help init start stop status suspendback resumeback killb
|
|||
# 8 - curl/wget missing
|
||||
# 10 - not bash!
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
##################################################################
|
||||
|
||||
# are we running in a terminal?
|
||||
|
@ -99,11 +99,15 @@ getConfigKey() {
|
|||
[[ "$1" =~ ^[-${azAZo9},._]+$ ]] || return 3
|
||||
[ -r "${BOTCONFIG}.jssh" ] && sed -n 's/\["'"$1"'"\]\t*"\(.*\)"/\1/p' "${BOTCONFIG}.jssh" | tail -n 1
|
||||
}
|
||||
# escape / remove text characters for json strings, eg. " -> \"
|
||||
# $1 string
|
||||
# output escaped string
|
||||
# escape characters in json strings for telegram
|
||||
# $1 string, output escaped string
|
||||
JsonEscape(){
|
||||
sed 's/\([-"`´,§$%&/(){}#@!?*.\t]\)/\\\1/g' <<< "$1"
|
||||
sed -E -e 's/\r//g' -e 's/([-"`´,§$%&/(){}#@!?*.\t])/\\\1/g' <<< "${1//$'\n'/\\n}"
|
||||
}
|
||||
# clean \ from escaped json string
|
||||
# $1 string, output cleaned string
|
||||
cleanEscape(){ # remove " all \ but \n\u \n or \r
|
||||
sed -E -e 's/\\"/+/g' -e 's/\\([^nu])/\1/g' -e 's/(\r|\n)//g' <<<"$1"
|
||||
}
|
||||
# check if $1 seems a valid token
|
||||
# return true if token seems to be valid
|
||||
|
@ -157,7 +161,7 @@ debug_checks(){ {
|
|||
[ -z "$(getConfigKey "botadmin")" ] && printf "%(%c)T: %s\n" -1 "Bot admin is missing! =========="
|
||||
# call user defined debug_checks if exists
|
||||
_exec_if_function my_debug_checks "$(_date)" "${where}" "$*"
|
||||
} >>"${DEBUGLOG}"
|
||||
} 2>/dev/null >>"${DEBUGLOG}"
|
||||
}
|
||||
|
||||
# some Linux distributions (e.g. Manjaro) doesn't seem to have C locale activated by default
|
||||
|
@ -174,10 +178,11 @@ RUNDIR="$(dirname "$0")"
|
|||
MODULEDIR="${SCRIPTDIR}/modules"
|
||||
|
||||
# adjust stuff for source, use return from source without source
|
||||
alias exit_source='exit'
|
||||
exit_source() { exit "$1"; }
|
||||
if [[ "${SCRIPT}" != "${REALME}" || "$1" == "source" ]]; then
|
||||
SOURCE="yes"
|
||||
[ -z "$1" ] && alias exit_source='printf "Exit from source ...\n";return'
|
||||
SCRIPT="${REALME}"
|
||||
[ -z "$1" ] && exit_source() { printf "Exit from source ...\n"; return "$1"; }
|
||||
fi
|
||||
|
||||
# emmbeded system may claim bash but it is not
|
||||
|
@ -271,6 +276,7 @@ if [ -z "${BOTTOKEN}" ]; then
|
|||
[ -z "${admin}" ] && admin='?'
|
||||
printf '["botadmin"]\t"%s"\n' "${admin}" >> "${BOTCONFIG}.jssh"
|
||||
fi
|
||||
|
||||
# setup botacl file
|
||||
if [ ! -f "${BOTACL}" ]; then
|
||||
printf "${GREY}Create initial ${BOTACL} file.${NN}"
|
||||
|
@ -279,15 +285,14 @@ if [ -z "${BOTTOKEN}" ]; then
|
|||
# check data dir file
|
||||
if [ ! -w "${DATADIR}" ]; then
|
||||
printf "${RED}ERROR: ${DATADIR} does not exist or is not writeable!.${NN}"
|
||||
exit_source 2
|
||||
[ "$1" != "init" ] && exit_source 2 # skip on init
|
||||
fi
|
||||
# setup count file
|
||||
if [ ! -f "${COUNTFILE}.jssh" ]; then
|
||||
printf '["counted_user_chat_id"]\t"num_messages_seen"\n' >> "${COUNTFILE}.jssh"
|
||||
elif [ ! -w "${COUNTFILE}.jssh" ]; then
|
||||
printf "${RED}ERROR: Can't write to ${COUNTFILE}!.${NN}"
|
||||
printf "${RED}WARNING: Can't write to ${COUNTFILE}!.${NN}"
|
||||
ls -l "${COUNTFILE}.jssh"
|
||||
exit_source 2
|
||||
fi
|
||||
# setup blocked file
|
||||
if [ ! -f "${BLOCKEDFILE}.jssh" ]; then
|
||||
|
@ -342,6 +347,7 @@ fi
|
|||
BASHBOT_RETRY="" # retry by default
|
||||
|
||||
URL="${BASHBOT_URL:-https://api.telegram.org/bot}${BOTTOKEN}"
|
||||
FILEURL="${URL%%/bot*}/file/bot${BOTTOKEN}"
|
||||
ME_URL=${URL}'/getMe'
|
||||
|
||||
#################
|
||||
|
@ -353,7 +359,7 @@ declare -rx BOTTOKEN URL ME_URL
|
|||
declare -ax CMD
|
||||
declare -Ax UPD BOTSENT USER MESSAGE URLS CONTACT LOCATION CHAT FORWARD REPLYTO VENUE iQUERY iBUTTON
|
||||
declare -Ax SERVICE NEWMEMBER LEFTMEMBER PINNED MIGRATE
|
||||
export res CAPTION ME
|
||||
export res CAPTION ME BOTADMIN
|
||||
|
||||
|
||||
###############
|
||||
|
@ -388,16 +394,6 @@ if ! _is_function jssh_newDB; then
|
|||
exit_source 6
|
||||
fi
|
||||
|
||||
# $1 URL, $2 filename in DATADIR
|
||||
# outputs final filename
|
||||
download() {
|
||||
local empty="no.file" file="${2:-${empty}}"
|
||||
if [[ "${file}" = *"/"* ]] || [[ "${file}" = "."* ]]; then file="${empty}"; fi
|
||||
while [ -f "${DATADIR:-.}/${file}" ] ; do file="${RANDOM}-${file}"; done
|
||||
getJson "$1" >"${DATADIR:-.}/${file}" || return
|
||||
printf '%s\n' "${DATADIR:-.}/${file}"
|
||||
}
|
||||
|
||||
# $1 postfix, e.g. chatid
|
||||
# $2 prefix, back- or startbot-
|
||||
procname(){
|
||||
|
@ -425,19 +421,56 @@ killallproc() {
|
|||
debug_checks "end killallproc" "$1"
|
||||
}
|
||||
|
||||
|
||||
# $ chat $2 msg_id $3 nolog
|
||||
declare -xr DELETE_URL=${URL}'/deleteMessage'
|
||||
delete_message() {
|
||||
[ -z "$3" ] && log_update "Delete Message CHAT=$1 MSG_ID=$2"
|
||||
sendJson "$1" '"message_id": '"$2"'' "${DELETE_URL}"
|
||||
}
|
||||
|
||||
# get download url for file id, $1 file_id
|
||||
# URL path for file id, $1 file_id
|
||||
# use download_file "path" to download file
|
||||
get_file() {
|
||||
[ -z "$1" ] && return
|
||||
sendJson "" '"file_id": "'"$1"'"' "${URL}/getFile"
|
||||
printf "%s\n" "${URL}/${UPD["result,file_path"]}"
|
||||
printf "%s\n" "${UPD["result,file_path"]}"
|
||||
}
|
||||
# download file to DATADIR
|
||||
# $1 URL path, $2 proposed filename (may modified/ignored)
|
||||
# outputs final filename
|
||||
# keep old function name for backward compatibility
|
||||
alias download="download_file"
|
||||
download_file() {
|
||||
local url="$1" file="${2:-$1}"
|
||||
# old mode if full URL is given
|
||||
if [[ "${1}" =~ ^https*:// ]]; then
|
||||
# random filename if not given for http
|
||||
if [ -z "$2" ]; then
|
||||
: "$(mktemp -u -p . "XXXXXXXXXX" 2>/dev/null)"
|
||||
file="download-${_#./}"
|
||||
fi
|
||||
else
|
||||
# prefix https://api.telegram...
|
||||
url="${FILEURL}/${url}"
|
||||
fi
|
||||
# filename: replace "/" with "-", use mktemp if exist
|
||||
file="${DATADIR:-.}/${file//\//-}"
|
||||
[ -f "${file}" ] && file="$(mktemp -p "${DATADIR:-.}" "XXXXX-${file##*/}" )"
|
||||
getJson "${url}" >"${file}" || return
|
||||
# output absolute file path
|
||||
printf "%s\n" "$(cd "${file%/*}" >/dev/null 2>&1 && pwd)/${file##*/}"
|
||||
}
|
||||
# notify mycommands about errors while sending
|
||||
# $1 calling function $2 error $3 chat $4 user $5 error message $6 ... remaining args to calling function
|
||||
# calls function based on error: bashbotError{function} basbotError{error}
|
||||
# if no specific function exist try to call bashbotProcessError
|
||||
processError(){
|
||||
local func="$1" err="$2"
|
||||
[[ "${err}" != "4"* ]] && return 1
|
||||
# check for bashbotError${func} provided in mycommands
|
||||
# shellcheck disable=SC2082
|
||||
if _is_function "bashbotError_${func}"; then
|
||||
"bashbotError_${func}" "$@"
|
||||
# check for bashbotError${err} provided in mycommands
|
||||
elif _is_function "bashbotError_${err}"; then
|
||||
"bashbotError_${err}" "$@"
|
||||
# noting found, try bashbotProcessError
|
||||
else
|
||||
_exec_if_function bashbotProcessError "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# iconv used to filter out broken utf characters, if not installed fake it
|
||||
|
@ -459,9 +492,8 @@ sendJson(){
|
|||
# compose final json
|
||||
json='{'"${chat} $(iconv -f utf-8 -t utf-8 -c <<<"$2")"'}'
|
||||
if [ -n "${BASHBOTDEBUG}" ] ; then
|
||||
log_update "sendJson (${DETECTED_CURL}) CHAT=${chat#*:} JSON=${2:0:100} URL=${3##*/}"
|
||||
# mask " and \ , remove newline from json
|
||||
log_message "DEBUG sendJson ==========\n$("${JSONSHFILE}" -b -n <<<"$(sed -E -e 's/\\"/+/g' -e 's/\\/\\\\/g' -e 's/(\r|\n)//g' <<<"${json}")" 2>&1)"
|
||||
log_update "sendJson (${DETECTED_CURL}) CHAT=${chat#*:} JSON=$(cleanEscape "${json:0:100}") URL=${3##*/}"
|
||||
log_message "DEBUG sendJson ==========\n$("${JSONSHFILE}" -b -n <<<"$(cleanEscape "${json}")" 2>&1)"
|
||||
fi
|
||||
# chat id not a number
|
||||
if [[ "${chat}" == *"NAN\"," ]]; then
|
||||
|
@ -477,6 +509,37 @@ sendJson(){
|
|||
[ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "send" "${@}" &
|
||||
}
|
||||
|
||||
UPLOADDIR="${BASHBOT_UPLOAD:-${DATADIR}/upload}"
|
||||
|
||||
# $1 chat $2 file, $3 calling function
|
||||
# return final file name or empty string on error
|
||||
checkUploadFile() {
|
||||
local err file="$2"
|
||||
[[ "${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_debug "$3: CHAT=$1 FILE=$2 MSG=${BOTSENT[DESCRIPTION]}"
|
||||
return 1
|
||||
fi
|
||||
printf "%s\n" "${file}"
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# curl / wget specific functions
|
||||
|
@ -487,14 +550,14 @@ if detect_curl ; then
|
|||
# $1 URL, $2 hack: log getJson if not ""
|
||||
getJson(){
|
||||
# shellcheck disable=SC2086
|
||||
"${BASHBOT_CURL}" -sL -k ${BASHBOT_CURL_ARGS} -m "${TIMEOUT}" "$1"
|
||||
"${BASHBOT_CURL}" -sL -k ${BASHBOT_CURL_ARGS} -m "${TIMEOUT}" -K - <<<"url=$1"
|
||||
}
|
||||
# curl variant for sendJson
|
||||
# usage: "JSON" "URL"
|
||||
sendJson_do(){
|
||||
# shellcheck disable=SC2086
|
||||
"${BASHBOT_CURL}" -s -k ${BASHBOT_CURL_ARGS} -m "${TIMEOUT}"\
|
||||
-d "$1" -X POST "$2" -H "Content-Type: application/json" | "${JSONSHFILE}" -b -n 2>/dev/null
|
||||
-d "$1" -X POST -K - <<<"url=$2" -H "Content-Type: application/json" | "${JSONSHFILE}" -b -n 2>/dev/null
|
||||
}
|
||||
#$1 Chat, $2 what, $3 file, $4 URL, $5 caption
|
||||
sendUpload() {
|
||||
|
@ -503,11 +566,11 @@ if detect_curl ; then
|
|||
[ -n "${BASHBOTDEBUG}" ] &&\
|
||||
log_update "sendUpload CHAT=$1 WHAT=$2 FILE=$3 CAPT=$5"
|
||||
# shellcheck disable=SC2086
|
||||
res="$("${BASHBOT_CURL}" -s -k ${BASHBOT_CURL_ARGS} "$4" -F "chat_id=$1"\
|
||||
res="$("${BASHBOT_CURL}" -s -k ${BASHBOT_CURL_ARGS} -K - <<<"url=$4" -F "chat_id=$1"\
|
||||
-F "$2=@$3;${3##*/}" -F "caption=$5" | "${JSONSHFILE}" -b -n 2>/dev/null )"
|
||||
else
|
||||
# shellcheck disable=SC2086
|
||||
res="$("${BASHBOT_CURL}" -s -k ${BASHBOT_CURL_ARGS} "$4" -F "chat_id=$1"\
|
||||
res="$("${BASHBOT_CURL}" -s -k ${BASHBOT_CURL_ARGS} -K - <<<"url=$4" -F "chat_id=$1"\
|
||||
-F "$2=@$3;${3##*/}" | "${JSONSHFILE}" -b -n 2>/dev/null )"
|
||||
fi
|
||||
sendJsonResult "${res}" "sendUpload (curl)" "$@"
|
||||
|
@ -518,14 +581,14 @@ else
|
|||
if _exists wget; then
|
||||
getJson(){
|
||||
# shellcheck disable=SC2086
|
||||
wget --no-check-certificate -t 2 -T "${TIMEOUT}" ${BASHBOT_WGET_ARGS} -qO - "$1"
|
||||
wget --no-check-certificate -t 2 -T "${TIMEOUT}" ${BASHBOT_WGET_ARGS} -qO - -i <<<"$1"
|
||||
}
|
||||
# curl variant for sendJson
|
||||
# usage: "JSON" "URL"
|
||||
sendJson_do(){
|
||||
# shellcheck disable=SC2086
|
||||
wget --no-check-certificate -t 2 -T "${TIMEOUT}" ${BASHBOT_WGET_ARGS} -qO - --post-data="$1" \
|
||||
--header='Content-Type:application/json' "$2" | "${JSONSHFILE}" -b -n 2>/dev/null
|
||||
--header='Content-Type:application/json' -i <<<"$2" | "${JSONSHFILE}" -b -n 2>/dev/null
|
||||
}
|
||||
sendUpload() {
|
||||
log_error "Sorry, wget does not support file upload"
|
||||
|
@ -613,25 +676,25 @@ sendJsonResult(){
|
|||
# timeout, failed connection or blocked
|
||||
if [ "${BOTSENT[ERROR]}" == "999" ];then
|
||||
# check if default curl and args are OK
|
||||
if ! curl -sL -k -m 2 "${URL}" >/dev/null 2>&1 ; then
|
||||
printf "%(%c)T: BASHBOT IP Address seems blocked!\n" -1
|
||||
# user provided function to recover or notify block
|
||||
if _exec_if_function bashbotBlockRecover; then
|
||||
BASHBOT_RETRY="2"
|
||||
printf "bashbotBlockRecover returned true, retry %s ...\n" "$2"
|
||||
sendJsonRetry "$2" "${BASHBOT_RETRY}" "${@:3}"
|
||||
unset BASHBOT_RETRY
|
||||
fi
|
||||
return
|
||||
fi
|
||||
# are not blocked, default curl and args are working
|
||||
if [ -n "${BASHBOT_CURL_ARGS}" ] || [ "${BASHBOT_CURL}" != "curl" ]; then
|
||||
printf "Problem with \"%s %s\"? retry %s with default config ...\n"\
|
||||
"${BASHBOT_CURL}" "${BASHBOT_CURL_ARGS}" "$2"
|
||||
BASHBOT_RETRY="2"; BASHBOT_CURL="curl"; BASHBOT_CURL_ARGS=""
|
||||
if ! curl -sL -k -m 2 "${URL}" >/dev/null 2>&1 ; then
|
||||
printf "%(%c)T: BASHBOT IP Address seems blocked!\n" -1
|
||||
# user provided function to recover or notify block
|
||||
if _exec_if_function bashbotBlockRecover; then
|
||||
BASHBOT_RETRY="2"
|
||||
printf "bashbotBlockRecover returned true, retry %s ...\n" "$2"
|
||||
sendJsonRetry "$2" "${BASHBOT_RETRY}" "${@:3}"
|
||||
unset BASHBOT_RETRY
|
||||
fi
|
||||
# seems not blocked, try if blockrecover and default curl args working
|
||||
elif [ -n "${BASHBOT_CURL_ARGS}" ] || [ "${BASHBOT_CURL}" != "curl" ]; then
|
||||
printf "Problem with \"%s %s\"? retry %s with default config ...\n"\
|
||||
"${BASHBOT_CURL}" "${BASHBOT_CURL_ARGS}" "$2"
|
||||
BASHBOT_RETRY="2"; BASHBOT_CURL="curl"; BASHBOT_CURL_ARGS=""
|
||||
_exec_if_function bashbotBlockRecover
|
||||
sendJsonRetry "$2" "${BASHBOT_RETRY}" "${@:3}"
|
||||
unset BASHBOT_RETRY
|
||||
fi
|
||||
[ -n "${BOTSENT[ERROR]}" ] && processError "$3" "${BOTSENT[ERROR]}" "$4" "" "${BOTSENT[DESCRIPTION]}" "$5" "$6"
|
||||
fi
|
||||
fi
|
||||
} >>"${ERRORLOG}"
|
||||
|
@ -685,6 +748,16 @@ event_send() {
|
|||
done
|
||||
}
|
||||
|
||||
# cleanup activities on startup, called from startbot and resume background jobs
|
||||
# $1 action, timestamp for action is saved in config
|
||||
bot_cleanup() {
|
||||
# cleanup countfile on startup
|
||||
jssh_deleteKeyDB "CLEAN_COUNTER_DATABASE_ON_STARTUP" "${COUNTFILE}"
|
||||
[ -f "${COUNTFILE}.jssh.flock" ] && rm -f "${COUNTFILE}.jssh.flock"
|
||||
# store action time and cleanup botconfig on startup
|
||||
[ -n "$1" ] && jssh_updateKeyDB "$1" "$(_date)" "${BOTCONFIG}"
|
||||
[ -f "${BOTCONFIG}.jssh.flock" ] && rm -f "${BOTCONFIG}.jssh.flock"
|
||||
}
|
||||
|
||||
# fallback version, full version is in bin/bashbot_init.in.sh
|
||||
# initialize bot environment, user and permissions
|
||||
|
@ -726,6 +799,8 @@ fi
|
|||
# source the script with source as param to use functions in other scripts
|
||||
# do not execute if read from other scripts
|
||||
|
||||
BOTADMIN="$(getConfigKey "botadmin")"
|
||||
|
||||
if [ -z "${SOURCE}" ]; then
|
||||
##############
|
||||
# internal options only for use from bashbot and developers
|
||||
|
@ -767,7 +842,8 @@ if [ -z "${SOURCE}" ]; then
|
|||
;;
|
||||
# finally starts the read update loop, internal use only
|
||||
"startbot" )
|
||||
_exec_if_function start_bot "$2"
|
||||
_exec_if_function start_bot "$2" "polling mode"
|
||||
_exec_if_function get_updates "$2"
|
||||
debug_checks "end startbot" "$@"
|
||||
exit
|
||||
;;
|
||||
|
@ -837,7 +913,7 @@ if [ -z "${SOURCE}" ]; then
|
|||
# shellcheck disable=SC2086
|
||||
if kill ${BOTPID}; then
|
||||
# inform botadmin about stop
|
||||
send_normal_message "$(getConfigKey "botadmin")" "Bot ${ME} stopped ..." &
|
||||
send_normal_message "${BOTADMIN}" "Bot ${ME} polling mode stopped ..." &
|
||||
printf "${GREEN}OK. Bot stopped successfully.${NN}"
|
||||
else
|
||||
printf "${RED}An error occurred while stopping bot.${NN}"
|
||||
|
@ -850,7 +926,7 @@ if [ -z "${SOURCE}" ]; then
|
|||
exit
|
||||
;;
|
||||
# suspend, resume or kill background jobs
|
||||
"suspendb"*|"resumeb"*|"killb"*)
|
||||
"suspendb"*|"resumeb"*|'restartb'*|"killb"*)
|
||||
_is_function job_control || { printf "${RED}Module background is not available!${NN}"; exit 3; }
|
||||
ME="$(getConfigKey "botname")"
|
||||
job_control "$1"
|
||||
|
|
|
@ -21,7 +21,7 @@ USAGE='any_command.sh [-h|--help] [--force|--reference] bot_command args ...'
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 30.01.2021 10:24
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
|
@ -68,7 +68,7 @@ fi
|
|||
# ready, do stuff here -----
|
||||
COMMAND="$1"
|
||||
if [ "$2" == "BOTADMIN" ]; then
|
||||
ARG1="${BOT_ADMIN}"
|
||||
ARG1="${BOTADMIN}"
|
||||
else
|
||||
ARG1="$2"
|
||||
fi
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 18.12.2020 12:27
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
############
|
||||
|
@ -21,8 +21,8 @@
|
|||
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"
|
||||
|
@ -59,11 +59,14 @@ UPLOADDIR="${BASHBOT_VAR%/bin*}"
|
|||
FILE_REGEX="${UPLOADDIR}/.*"
|
||||
|
||||
# get and check ADMIN and NAME
|
||||
BOT_ADMIN="$(getConfigKey "botadmin")"
|
||||
BOT_NAME="$(getConfigKey "botname")"
|
||||
ME="${BOT_NAME}"
|
||||
[[ -z "${BOT_ADMIN}" || "${BOT_ADMIN}" == "?" ]] && printf "%s\n" "${ORANGE}Warning: Botadmin not set, send bot command${NC} /start"
|
||||
[[ -z "${BOT_NAME}" ]] && printf "%s\n" "${ORANGE}Warning: Botname not set, run bashbot.sh botname"
|
||||
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; }
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
#
|
||||
# USAGE: source bashbot_init.inc.sh
|
||||
#
|
||||
# DESCRIPTION: extend / overwrite bashbot initialisation
|
||||
# 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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
# shellcheck disable=SC2059
|
||||
|
||||
|
@ -54,23 +54,29 @@ bot_init() {
|
|||
[ -r "${addons}" ] && source "${addons}" "init" "${DEBUG}"
|
||||
done
|
||||
printf "Done.\n"
|
||||
# ask for bashbot user
|
||||
# shellcheck disable=SC2153
|
||||
runuser="${RUNUSER}"; [ "${UID}" = "0" ] && runuser="nobody"
|
||||
# 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%:*}"
|
||||
[ -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" && "${touser}" != "${runuser}" ]]; then
|
||||
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" ]; then
|
||||
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"
|
||||
|
@ -98,19 +104,19 @@ bot_init() {
|
|||
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 \{\} +
|
||||
chown -Rf "${chown}" . ./*
|
||||
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 '/^[# ]*bashbot=/ s|bashbot=.*$|bashbot="cd '"${PWD}"'; '"${PWD}"'/'"${0##*/}"'"|' "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"
|
||||
|
|
|
@ -17,7 +17,7 @@ USAGE='bashbot_stats.sh [-h|--help] [debug]'
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 23.12.2020 20:34
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
# set bashbot environment
|
||||
|
@ -27,7 +27,7 @@ source "${0%/*}/bashbot_env.inc.sh" "$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[*]}
|
||||
|
|
|
@ -20,7 +20,7 @@ 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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
|
@ -34,7 +34,7 @@ print_help "$1"
|
|||
####
|
||||
# ready, do stuff here -----
|
||||
if [ "$1" == "BOTADMIN" ]; then
|
||||
CHAT="${BOT_ADMIN}"
|
||||
CHAT="${BOTADMIN}"
|
||||
else
|
||||
CHAT="$1"
|
||||
fi
|
||||
|
|
|
@ -26,7 +26,7 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" "text|url" ...'
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 21.01.2021 08:10
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
|
@ -40,7 +40,7 @@ print_help "$1"
|
|||
####
|
||||
# ready, do stuff here -----
|
||||
if [ "$1" == "BOTADMIN" ]; then
|
||||
CHAT="${BOT_ADMIN}"
|
||||
CHAT="${BOTADMIN}"
|
||||
else
|
||||
CHAT="$1"
|
||||
fi
|
||||
|
|
|
@ -23,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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
|
@ -55,7 +55,7 @@ print_help "$1"
|
|||
####
|
||||
# ready, do stuff here -----
|
||||
if [ "$1" == "BOTADMIN" ]; then
|
||||
CHAT="${BOT_ADMIN}"
|
||||
CHAT="${BOTADMIN}"
|
||||
else
|
||||
CHAT="$1"
|
||||
fi
|
||||
|
|
|
@ -20,7 +20,7 @@ USAGE='kickban_user.sh [-h|--help] [-u|--unban] "CHAT[ID]" "USER[ID]" [debug]'
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 25.01.2021 20:34
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
|
|
|
@ -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
|
|
@ -15,12 +15,12 @@ USAGE='process_update.sh [-h|--help] [debug] [<file]'
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 30.01.2021 19:14
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
# parse args
|
||||
COMMAND="process_update"
|
||||
COMMAND="process_multi_updates"
|
||||
|
||||
# set bashbot environment
|
||||
source "${0%/*}/bashbot_env.inc.sh" "debug" # debug
|
||||
|
@ -31,12 +31,11 @@ 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)"
|
||||
|
||||
# assign to bashbot ARRAY
|
||||
Json2Array 'UPD' <<<"${UPDATE}"
|
||||
|
||||
# process telegram update
|
||||
"${COMMAND}" "0" "$1"
|
||||
"${COMMAND}" "$1"
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ USAGE='promote_user.sh [-h|--help] "CHAT[ID]" "USER[ID]" "right[:true|false]" ..
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 25.01.2021 22:34
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
|
|
|
@ -28,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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
|
@ -91,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"
|
||||
|
|
|
@ -26,7 +26,7 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "message" "text|url" ...'
|
|||
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
|
||||
# CREATED: 18.01.2021 11:34
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
|
@ -40,7 +40,7 @@ print_help "$1"
|
|||
####
|
||||
# ready, do stuff here -----
|
||||
if [ "$1" == "BOTADMIN" ]; then
|
||||
CHAT="${BOT_ADMIN}"
|
||||
CHAT="${BOTADMIN}"
|
||||
else
|
||||
CHAT="$1"
|
||||
fi
|
||||
|
|
|
@ -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 +0,0 @@
|
|||
edit_message.sh
|
|
@ -25,7 +25,7 @@ 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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
|
@ -39,7 +39,7 @@ print_help "$1"
|
|||
####
|
||||
# ready, do stuff here -----
|
||||
if [ "$1" == "BOTADMIN" ]; then
|
||||
CHAT="${BOT_ADMIN}"
|
||||
CHAT="${BOTADMIN}"
|
||||
else
|
||||
CHAT="$1"
|
||||
fi
|
||||
|
|
|
@ -8,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
|
||||
#
|
||||
|
@ -22,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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
####
|
||||
|
@ -41,6 +45,10 @@ case "$1" in
|
|||
SEND="send_html_message"
|
||||
shift
|
||||
;;
|
||||
"stdin"|"-")
|
||||
FILE="stdin"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
|
||||
# set bashbot environment
|
||||
|
@ -50,13 +58,16 @@ 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
|
||||
print_result
|
||||
|
|
17
commands.sh
17
commands.sh
|
@ -15,7 +15,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.40-0-gf9dab50
|
||||
#### $$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
|
||||
|
@ -94,10 +98,9 @@ if [ -z "$1" ] || [[ "$1" == *"debug"* ]];then
|
|||
###################
|
||||
# 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
|
||||
|
||||
###################
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#
|
||||
# Description: run all tests, exit after failed test
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#############################################################
|
||||
|
||||
#shellcheck disable=SC1090
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#
|
||||
# Description: common stuff for all dev scripts
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#############################################################
|
||||
|
||||
# magic to ensure that we're always inside the root of our application,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# works together with git pre-push.sh and ADD all changed files since last push
|
||||
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
#shellcheck disable=SC1090
|
||||
source "${0%/*}/dev.inc.sh"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
##############################################################
|
||||
|
||||
# download JSON.sh
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
# this has to run once atfer git clone
|
||||
# and every time we create new hooks
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
#shellcheck disable=SC1090
|
||||
source "${0%/*}/dev.inc.sh"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#
|
||||
# Options: --notest - skip tests
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$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,10 +1,13 @@
|
|||
STANDALONE
|
||||
data-bot-bash/*
|
||||
webhook-fifo
|
||||
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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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,7 +91,7 @@ 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
|
||||
|
|
|
@ -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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
# shellcheck disable=SC2028,SC2016,SC1117
|
||||
|
||||
infile="bashbot.sh"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# list of additional files to check from shellcheck
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
bashbot.rc
|
||||
mycommands.conf
|
||||
mycommands.sh.clean
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
# shellcheck disable=SC2016
|
||||
#
|
||||
# Easy Versioning in git:
|
||||
|
@ -44,8 +44,14 @@ VERSION="$(git describe --tags --long)"
|
|||
printf "Update to version %s ...\n" "${VERSION}"
|
||||
|
||||
# only regular files, ignore .dot files/dirs, e.g. .git .gitinore in BASEDIR
|
||||
FILES="$(find ./* -type f)"
|
||||
[ "$1" != "" ] && FILES="$*"
|
||||
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
|
||||
|
|
|
@ -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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
|
|
|
@ -30,7 +30,9 @@ 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 ...
|
||||
|
@ -44,7 +46,7 @@ Have FUN!
|
|||
│ ├── kickban_user.sh # kick/unban user from given chat
|
||||
│ ├── promote_user.sh # promote/dente user rights in given chat
|
||||
│ │
|
||||
│ └── bashbot_env.inc.sh # sourced from scripts, adapt locations 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
|
||||
|
@ -55,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
|
||||
│
|
||||
|
@ -127,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"
|
||||
|
@ -150,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
|
||||
|
@ -172,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
|
||||
|
@ -185,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
|
||||
|
@ -212,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
|
||||
|
@ -238,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
|
||||
|
@ -250,10 +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 used for interaction with the user,
|
||||
they contain the following variables only:
|
||||
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.
|
||||
|
||||
* `${iQUERY}`: Current inline query
|
||||
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.
|
||||
|
||||
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
|
||||
|
@ -261,9 +279,9 @@ they contain the following variables only:
|
|||
* `${iQUERY[LAST_NAME]}`: User's last name
|
||||
|
||||
|
||||
|
||||
### Callback button messages
|
||||
Callback button messages special messages swedn from callback buttons,
|
||||
they contain the following variables only:
|
||||
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
|
||||
|
@ -282,6 +300,8 @@ they contain the following variables only:
|
|||
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.
|
||||
|
@ -372,5 +392,5 @@ send_action "${CHAT[ID]}" "action"
|
|||
#### [Prev Create Bot](1_firstbot.md)
|
||||
#### [Next Advanced Usage](3_advanced.md)
|
||||
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$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
|
||||
|
@ -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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
|
|
|
@ -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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
|
|
|
@ -176,8 +176,22 @@ send_album "$(getConfigKey "botadmin")" "http://www.rrr.de/slider/main-image1.jp
|
|||
##### send_sticker
|
||||
`send_sticker` sends a sticker using a `file_id` to send a sticker that exists on the Telegram servers.
|
||||
|
||||
*usage:* send_sticker "$CHAT[ID]" "file_id"
|
||||
*usage:* send_sticker "CHAT[ID]" "file_id"
|
||||
|
||||
##### send_dice
|
||||
`send_dice` send an animated emoji and returns a value (_e.g. points shown on die_).
|
||||
|
||||
*usage:* send_dice "CHAT[ID]" "emoji"
|
||||
|
||||
Emoji must be one of '🎲', '🎯', '🏀', '⚽', '🎰' or ":game_die:" ":dart:" ":basketball:" ":soccer:" :slot_machine:".
|
||||
Dice can have values 1-6 for '🎲' and '🎯', values 1-5 for '🏀' and '⚽', and values 1-64 for '🎰'. Defaults to '🎲'
|
||||
|
||||
*example:*
|
||||
```bash
|
||||
# send die and output points
|
||||
send_dice "${CHAT[ID]}" ":game_die:"
|
||||
[ "${BOTSENT[OK]}" = "true" ] && send_markdownv2_message "${CHAT[ID]}" "*Congratulation* you got *${BOTSENT[RESULT]} Point(s)*."
|
||||
```
|
||||
|
||||
----
|
||||
|
||||
|
@ -294,10 +308,10 @@ echo ${BOTSEND[ID]}
|
|||
567
|
||||
|
||||
# add one button row
|
||||
edit_inline_keyboard "${CHAT[ID]}" "567" "button 1|http://rrr.de" "button 2|http://rrr.de"
|
||||
edit_inline_buttons "${CHAT[ID]}" "567" "button 1|http://rrr.de" "button 2|http://rrr.de"
|
||||
|
||||
# change buttons
|
||||
edit_inline_keyboard "${CHAT[ID]}" "567" "Success edit_inline_keyboard|http://rrr.de"
|
||||
edit_inline_buttons "${CHAT[ID]}" "567" "Success edit_inline_buttons|http://rrr.de"
|
||||
|
||||
# delete button by replace whole message
|
||||
edit_markdownv2_message "${CHAT[ID]}" "*HI* this is a _markdown_ message inline *removed*..."
|
||||
|
@ -394,7 +408,7 @@ An URL Button opens the given URL, a CALLBACK button sends an update the bot mus
|
|||
send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" '[{"text":"Visit my Shop", "url":"https://dealz.rrr.de"}]'
|
||||
|
||||
# send_inline_button
|
||||
send_inline_keyboard "${CHAT[ID]}" "message" '[{"text":"button 1", url"":"http://rrr.de"}, {"text":"button 2", "url":"http://rrr.de"} ]'
|
||||
send_inline_keyboard "${CHAT[ID]}" "message" '[{"text":"button 1", "url":"http://rrr.de"}, {"text":"button 2", "url":"http://rrr.de"} ]'
|
||||
|
||||
# multiple button rows
|
||||
send_inline_keyboard "${CHAT[ID]}" "message" '[{"text":"b1", "url":"http://rrr.de"}, {"text":"b2", "url":"http://rrr.de"}], [{"text":"b3", "url":"http://rrr.de"}, "text":"b4", "url":"http://rrr.de"}]'
|
||||
|
@ -534,6 +548,85 @@ edit_html_message "${CHAT[ID]}" "${saved-id}" "this is <b>html</b> text"
|
|||
*usage:* edit_message_caption "CHAT[ID]" "MESSAGE-ID" "caption"
|
||||
|
||||
|
||||
----
|
||||
|
||||
### Get files from Telegram
|
||||
|
||||
##### download_file
|
||||
`download_file` download a file to `DATADIR` and returns the local `path` to the file on disc, main use is to download files send to chats.
|
||||
I tried to be as compatible as possible with old function `download`.
|
||||
|
||||
*usage:* download_file path_to_ile prosed_filename
|
||||
|
||||
*alias*: download
|
||||
|
||||
*Note:* You must use `download_file` to download `URLS[...]` or `SERVICE[NEWPHOTO]` URLs from Telegram server.
|
||||
|
||||
*example:*
|
||||
```bash
|
||||
########
|
||||
# download from Telegram server
|
||||
# photo received in a chat
|
||||
photo="${URLS[PHOTO]}")"
|
||||
echo "$photo" -> photo/file_1234.jpg
|
||||
|
||||
# first download
|
||||
file="$(download_file "${photo}"
|
||||
echo "$file" -> ./data-bot-bash/photo-file_1234.jpg
|
||||
|
||||
# second download
|
||||
file="$(download_file "${photo}"
|
||||
echo "$file" -> ./data-bot-bash/jkdfhi-photo-file_1234.jpg
|
||||
|
||||
ls data-bot-bash/*.jpg
|
||||
photo-file_1234.jpg jkdfhi-photo-file_1234.jpg
|
||||
|
||||
|
||||
########
|
||||
# download from other sources (full URL)
|
||||
file="$(download "https://avatars.githubusercontent.com/u/13046303")"
|
||||
echo "$file" -> ./data-bot-bash/download-askjgftGJGdh1Z
|
||||
|
||||
file="$(download "https://avatars.githubusercontent.com/u/13046303" "avatar.jpg")"
|
||||
echo "$file" -> ./data-bot-bash/avatar.jpg
|
||||
|
||||
file="$(download "https://avatars.githubusercontent.com/u/13046303" "avatar.jpg")"
|
||||
echo "$file" -> ./data-bot-bash/jhsdf-avatar.jpg
|
||||
|
||||
ls data-bot-bash/
|
||||
avatar.jpg jhsdf-avatar.jpg download-askjgftGJGdh1Z
|
||||
|
||||
|
||||
#######
|
||||
# manually download files to current directory (not recommended)
|
||||
getJson "${FILEURL}/${photo}" >"downloaded_photo.jpg"
|
||||
getJson "https://avatars.githubusercontent.com/u/13046303" >"avatar.jpg"
|
||||
|
||||
ls -F
|
||||
JSON.sh/ bin/ modules/ data-bot-bash/
|
||||
avatar.jpg bashbot.sh* botconfig.jssh commands.sh count.jssh downloaded_photo.jpg mycommands.sh ...
|
||||
|
||||
```
|
||||
|
||||
##### get_file
|
||||
`get_file` get the `path` to a file on Telegram server by it's `file_id`. File `path` is only valid for use with your bot token.
|
||||
|
||||
*usage:* url="$(get_file "file_id")"
|
||||
|
||||
*example*:
|
||||
|
||||
```bash
|
||||
# download file by file_id
|
||||
file_id="kjhdsfhkj-kjshfbsdbfkjhsdkfjn"
|
||||
|
||||
path="$(get_file "${file_id}")"
|
||||
file="$(download_file "${path}")"
|
||||
|
||||
# one line
|
||||
file="$(download_file "$(get_file "${file_id}")")"
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Manage Group
|
||||
|
@ -558,6 +651,15 @@ with description "Bad Request: chat description is not modified"
|
|||
*usage:* set_chat_description "CHAT[ID]" "new chat description"
|
||||
|
||||
|
||||
##### set_chat_photo
|
||||
`set_chat_photo` sets a new profile photo for the chat, can't be changed for private chat.
|
||||
Photo must be a local image file in a supported format (_.jpg, .jpeg, .png, .gif, .bmp, .tiff_)
|
||||
|
||||
Same location and naming restrictions as with `send_file` apply.
|
||||
|
||||
*usage:* set_chat_photo "CHAT[ID]" "file"
|
||||
|
||||
|
||||
##### new_chat_invite
|
||||
`new_chat_invite` generate a new invite link for a chat; any previously generated link is revoked.
|
||||
Returns the new invite link as String on success.
|
||||
|
@ -571,7 +673,6 @@ Returns the new invite link as String on success.
|
|||
|
||||
|
||||
##### pin_chat_message
|
||||
# $1 chat, $2 message_id
|
||||
`pin_chat_message` add a message to the list of pinned messages in a chat.
|
||||
|
||||
*usage:* pin_chat_message "CHAT[ID]" "message_id"
|
||||
|
@ -595,6 +696,13 @@ Returns the new invite link as String on success.
|
|||
*usage:* delete_chat_stickers "CHAT[ID]"
|
||||
|
||||
|
||||
##### set_chatadmin_title
|
||||
`set_chatadmin_title` set a custom title for an administrator in a supergroup promoted by the bot.
|
||||
Admin title can be 0-16 characters long, emoji are not allowed.
|
||||
|
||||
*usage:* set_chatadmin_title "CHAT[ID]" "USER[ID]" "admin title"
|
||||
|
||||
|
||||
----
|
||||
|
||||
### User Access Control
|
||||
|
@ -718,7 +826,7 @@ fi
|
|||
|
||||
----
|
||||
|
||||
### Inline Queries - answer direct queries to bot
|
||||
### Inline Query
|
||||
Inline Queries allows users to interact with your bot directly without sending extra commands.
|
||||
As an answer to an inline query you can send back one or more results to the Telegram client.
|
||||
The Telegram client will then show the results to the user and let him select one.
|
||||
|
@ -899,11 +1007,11 @@ Usually a message is automatically forwarded from within `commands.sh`, but you
|
|||
|
||||
### jsshDB
|
||||
|
||||
Since output generated by `JSON.sh` is so easy to use in bash, bashbot uses the format for a simple keys/value file store also.
|
||||
Output generated by `JSON.sh` can easily converted to bash associative arrays. Therefore Bashbot use this format for key/value file store too.
|
||||
|
||||
#### fast and slow operations
|
||||
|
||||
jsshDB files are flat text files containing key/value pairs in the `JSON.sh` format.
|
||||
jsshDB files are flat text files containing key/value pairs in `JSON.sh` format.
|
||||
Key/value pairs appearing later in the file overwrites earlier key/value pairs, Bashbot use this behavior to implement "fast replace" file operations.
|
||||
|
||||
"fast functions" add a new key/value pair to the end of a file without deleting an existing one, this is fast but over time the file grows to infinity.
|
||||
|
@ -934,9 +1042,13 @@ ARRAY["key"]="value"
|
|||
ARRAY["key,subkey"]="value2"
|
||||
```
|
||||
|
||||
For keys the following charatcsers are allowed: `a-z A-Z 0-9 _ .`, multiple keys must be separated by `,`.
|
||||
Only the following characters are allowed for keys: `a-z A-Z 0-9 _ .`, multiple keys must be separated by `,`.
|
||||
Keys contaiing other characters will be discarded when written to a file.
|
||||
|
||||
To delete (unset) a key/value pair in memory you can `unset ARRAY["abc"]` but this will not delete the key/value
|
||||
pair when using `jssh_updateDB` to update a file. Therefore the special value `${JSSHDB_UNSET}` exists, see `jssh_updateDB`
|
||||
|
||||
|
||||
```bash
|
||||
ARRAY["abc"]="abc" # OK
|
||||
ARRAY["abx###"]="abc" # works in bash but will not saved to file
|
||||
|
@ -949,7 +1061,6 @@ cat file.jssh
|
|||
|
||||
```
|
||||
|
||||
*Hint*: Try `tr -dc "[:alnum:],.\r\n"` to strip invalid characters from key.
|
||||
```bash
|
||||
# strip key containing invalid characters
|
||||
KEY="123abcABC,.#?(<>123ÄÖ*%&§"
|
||||
|
@ -1027,7 +1138,7 @@ Something wrong with data-bot-bash/../../../somevalues
|
|||
|
||||
##### jssh_writeDB
|
||||
Write content of an ARRAY into jsshDB file. ARRAY name must be declared with `declare -A ARRAY` before calling writeDB.
|
||||
"DB" file MUST exist or nothing is written.
|
||||
if "DB" file does not exist nothing is written.
|
||||
|
||||
Note: Existing content is overwritten.
|
||||
|
||||
|
@ -1084,15 +1195,16 @@ jssh_printDB READVALUES
|
|||
```
|
||||
|
||||
##### jssh_updateDB
|
||||
Update/Add content of an ARRAY into a jsshDB file. ARRAY name must be declared with `declare -A ARRAY` before calling updateDB.
|
||||
"DB" file MUST exist or nothing is written.
|
||||
|
||||
Note: Existing content not in ARRAY is kept in file.
|
||||
`jssh_updateDB updates key/value pairs of an ARRAY in a jsshDB file. ARRAY name must be declared with `declare -A ARRAY` before calling updateDB.
|
||||
if "DB" file does not exist nothing is written.
|
||||
|
||||
*usage:* jssh_updateDB "ARRAY" "filename"
|
||||
|
||||
*usage:* jssh_updateDB_async "ARRAY" "filename"
|
||||
|
||||
`jssh_updateDB` update new or changed keys/value pairs only, it will not delete an existing key/value pair.
|
||||
To delete an existing key/value pair you must assign the "unset value" `${JSSJDB_UNSET}` to it instead.
|
||||
|
||||
*example:*
|
||||
```bash
|
||||
# continued example from writeDB
|
||||
|
@ -1103,18 +1215,30 @@ MYVALUES["newvalue"]="this is new"
|
|||
jssh_updateDB "MYVALUES" "${DATADIR:-.}/myvalues"
|
||||
|
||||
# show what's written
|
||||
cat ${DATADIR:-.}/myvalues".jssh
|
||||
["value1"] "value1"
|
||||
["loveit"] "value2"
|
||||
["whynot"] "value3"
|
||||
["newvalue"] "this is new"
|
||||
|
||||
# now writeDB
|
||||
cat "$DBfile"
|
||||
jssh_writeDB "MYVALUES" "${DATADIR:-.}/myvalues"
|
||||
#######
|
||||
# update does not delete key/value pairs
|
||||
# uset in bash and update file
|
||||
unset MYVALUES["newvalue"]
|
||||
jssh_updateDB "MYVALUES" "${DATADIR:-.}/myvalues"
|
||||
|
||||
# show what's written, ups!
|
||||
cat "$DBfile"
|
||||
["newvalue"] "this is new"
|
||||
["value1"] "value1"
|
||||
["loveit"] "value2"
|
||||
["whynot"] "value3"
|
||||
["newvalue"] "this is new" # value exists!
|
||||
|
||||
# use JSSHDB_UNSET value
|
||||
MYVALUES["newvalue"]="${JSSHDB_UNSET}"
|
||||
jssh_updateDB "MYVALUES" "${DATADIR:-.}/myvalues"
|
||||
|
||||
["value1"] "value1"
|
||||
["loveit"] "value2"
|
||||
["whynot"] "value3"
|
||||
|
||||
```
|
||||
|
||||
|
@ -1398,20 +1522,6 @@ Do not use them in other files e.g. `bashbot.sh`, modules, addons etc.
|
|||
|
||||
### Helper functions
|
||||
|
||||
##### download
|
||||
Download the given URL and returns the final filename in TMPDIR. If the given filename exists,the filename is prefixed with a
|
||||
random number. Filename is not allowed to contain '/' or '..'.
|
||||
|
||||
*usage:* download URL filename
|
||||
|
||||
*example:*
|
||||
```bash
|
||||
file="$(download "https://avatars.githubusercontent.com/u/13046303" "avatar.jpg")"
|
||||
echo "$file" -> ./data-bot-bash/avatar.jpg
|
||||
file="$(download "https://avatars.githubusercontent.com/u/13046303" "avatar.jpg")"
|
||||
echo "$file" -> ./data-bot-bash/12345-avatar.jpg
|
||||
```
|
||||
|
||||
##### _exec_if_function
|
||||
Returns true, even if the given function does not exist. Return false if function exist but returns false.
|
||||
|
||||
|
@ -1506,26 +1616,11 @@ killallproc
|
|||
|
||||
----
|
||||
|
||||
##### get_file
|
||||
*usage:* url="$(get_file "CHAT[ID]" "message")"
|
||||
|
||||
----
|
||||
|
||||
##### JsonDecode
|
||||
Outputs decoded string to STDOUT
|
||||
|
||||
*usage:* JsonDecode "string"
|
||||
|
||||
##### JsonGetString
|
||||
Reads JSON from STDIN and Outputs found String to STDOUT
|
||||
|
||||
*usage:* JsonGetString `"path","to","string"`
|
||||
|
||||
##### JsonGetValue
|
||||
Reads JSON from STDIN and Outputs found Value to STDOUT
|
||||
|
||||
*usage:* JsonGetValue `"path","to","value"`
|
||||
|
||||
|
||||
##### Json2Array
|
||||
Read JSON.sh style data from STDIN and assign to given ARRAY
|
||||
|
@ -1578,5 +1673,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca
|
|||
#### [Prev Best Practice](5_practice.md)
|
||||
#### [Next Notes for Developers](7_develop.md)
|
||||
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
|
|
|
@ -387,5 +387,5 @@ fi
|
|||
|
||||
#### [Prev Function Reference](6_reference.md)
|
||||
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
|
|
|
@ -60,6 +60,6 @@ plus use of keyboards in private chats. It's an extended version of mycommands.s
|
|||
|
||||
**Webhook** contains instructions on how use webhook API to get updates from telegram instead polling Telegram server.
|
||||
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
######
|
||||
# parameters
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# file: run_filename
|
||||
# background job to display all new files in WATCHDIR
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
########################################################################
|
||||
|
||||
######
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
# AUTHOR: KayM (), kay@rrr.de
|
||||
# DATE: 19.12.2020 19:03
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#
|
||||
# shellcheck disable=SC2154
|
||||
# shellcheck disable=SC2034
|
||||
|
|
|
@ -1,63 +1,75 @@
|
|||
#### [Examples](../README.md)
|
||||
|
||||
## Bashtbot webhook example
|
||||
## Bashbot webhook example
|
||||
|
||||
### Webhooks
|
||||
### Webhook
|
||||
|
||||
Bashbot default mode is to poll Telegram server for updates but Telegram offers also webhook
|
||||
as a more efficient method to deliver updates.
|
||||
If your server is reachable from the Internet you can use the webhook method described here.
|
||||
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.
|
||||
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.
|
||||
|
||||
Prepare Apache to forward webhook to Bashbot:
|
||||
Setup webhook with Apache:
|
||||
|
||||
- install bashbot as described in [Bashbot Installation](../../doc/0_install.md)
|
||||
- create file `data-bot-bash/webhook-fifo`
|
||||
- run `bashbot.sh init` to setup bashbot to run as same user as Apache (_e.g. www_)
|
||||
- go to apache web root and create directory `telegram/<your_bot_token>`
|
||||
- copy all files from `examples/webhook` to new directory and change to it
|
||||
- write bashbot installation directory as first line to file `BASHBOT_HOME`
|
||||
- execute `php index.php`
|
||||
- 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>
|
||||
|
||||
Every call to webhook `https://<yourservername>/telegram/<your_bot_token>/` will execute
|
||||
`index.php` and write received JSON to file `data-bot-bash/webhook-fifo`.
|
||||
E.g. the URL `https://<yourservername>/telegram/<your_bot_token>/?json={"test":"me"}`
|
||||
will append `{"test":"me"}` to the file `data-bot-bash/webhook-fifo`.
|
||||
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 Apache is ready to forward data to Bashbot.
|
||||
Now your Server is ready to receive updates from Telegram.
|
||||
|
||||
|
||||
#### Simple update processing
|
||||
#### Default webhook processing
|
||||
|
||||
To configure `Simple update processing` delete the file `data-bot-bash/webhook-fifo` after your webhook is working.
|
||||
All webhook calls are now forwarded to `bin/process_update.sh` for processing.
|
||||
This is the testet and supported default method for processing Telegram updates over webhook.
|
||||
|
||||
To start `Simple processing ` enable webhook on Telegram (_see below_).
|
||||
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.
|
||||
|
||||
Every incoming Telegram update load Bashbot once for processing one command. Even it seems overkill to load
|
||||
Bashbot on every incoming update, it's more responsive and create less server load for low traffic bots.
|
||||
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.
|
||||
|
||||
If your bot uses `addons` or `BASHBOT_EVENTs` you can't use `Simple processing`.
|
||||
Nevertheles there are some limitations compared to polling mode:
|
||||
- no startup actions
|
||||
- `addons` and `TIMER_EVENTS` are not working
|
||||
|
||||
*Note:* `Simple processing` works without running `bashbot.sh start`.
|
||||
Interactive and background jobs are working as of Bashbot Version 1.51.
|
||||
|
||||
#### Full webhook processing
|
||||
|
||||
#### High traffic processing
|
||||
Full webhook processing use an external script to imitate Bashbot polling mode with webhook.
|
||||
|
||||
#### CURRENTLY NOT IMPLEMENTED
|
||||
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>`
|
||||
|
||||
High traffic processing writes Telegram updates to the named pipe `data-bot-bash/webhook-fifo`
|
||||
and Bashbot poll them, this is much more efficient than polling Telegram server.
|
||||
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'
|
||||
|
||||
To switch from `Simple processing` to `High traffic processing` start bashbot as `bashbot.sh start-webhook`.
|
||||
Stop bashbot with `bashbot.sh stop` to switch back to `Simple processing`
|
||||
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
|
||||
#### 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`.
|
||||
|
@ -73,8 +85,16 @@ After you enable webhook to deliver Telegram updates it's no more possible to po
|
|||
|
||||
To stop delivering of Telegram updates via webhook run `bin/any_command.sh delete_webhook`.
|
||||
|
||||
**Important**: Only https connections with a valid certificate chain are allowed as endpoint for webhook.
|
||||
**Important**: Telegram will refuse to deliver updates if your webhook has no valid SSL certificate chain.
|
||||
|
||||
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### 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
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* @license http://www.wtfpl.net/txt/copying/ WTFPLv2
|
||||
* @since 30.01.2021 20:24
|
||||
*
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
***********************************************************/
|
||||
|
||||
// bashbot home dir
|
||||
|
@ -26,10 +26,26 @@
|
|||
}
|
||||
}
|
||||
|
||||
// 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';
|
||||
// fifo endpoint
|
||||
$fifo=$BASHBOT_HOME.'/data-bot-bash/webhook-fifo';
|
||||
// default fifo endpoint
|
||||
$fifo=$BASHBOT_HOME.'/data-bot-bash/webhook-fifo-'.$botname;
|
||||
|
||||
// prepeare read, e.g. run from CLI
|
||||
$data='';
|
||||
|
@ -50,7 +66,7 @@
|
|||
if ($data == '') { $data = implode(" ",$_GET); }
|
||||
}
|
||||
// uncomment to save last received JSON
|
||||
// file_put_contents($json_file, $data);
|
||||
// file_put_contents($json_file, str_replace(array("\n", "\r"), '',$data). PHP_EOL));
|
||||
|
||||
// prepare for writing
|
||||
if ($data == '') {
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
{"update_id":665220889,
|
||||
"message":{"message_id":760,"from":{"id":586928566,"is_bot":false,"first_name":"Kay","last_name":"M","username":"KayM","language_code":"de"},"chat":{"id":589682731,"first_name":"Kay","last_name":"M","username":"KayM","type":"private"},"date":1612029749,"text":"/info","entities":[{"offset":0,"length":5,"type":"bot_command"}]}}
|
||||
{"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"}]}}
|
||||
|
|
|
@ -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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
# will be automatically sourced from bashbot
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
# shellcheck disable=SC1117,SC2059
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
|
||||
# will be automatically sourced from bashbot
|
||||
|
||||
|
@ -46,6 +46,10 @@ 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_update "Start background job CHAT=$1 JOB=${fifo##*/} CMD=${2##*/} $4 $5"
|
||||
|
@ -62,9 +66,9 @@ start_proc() {
|
|||
[ -z "$2" ] && return
|
||||
[ -x "${2%% *}" ] || return 1
|
||||
local fifo; fifo="${DATADIR:-.}/$(procname "$1")"
|
||||
log_update "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_update "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}";
|
||||
}
|
||||
|
@ -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,20 +143,20 @@ 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
|
||||
|
|
|
@ -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.40-0-gf9dab50
|
||||
#### $$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"
|
||||
|
@ -63,11 +73,11 @@ chat_member_count() {
|
|||
}
|
||||
|
||||
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() {
|
||||
|
@ -93,7 +103,7 @@ promote_chat_member() {
|
|||
*"invite"*) arg="can_invite_users";;
|
||||
*"restrict"*) arg="can_restrict_members";;
|
||||
*"promote"*) arg="can_promote_members";;
|
||||
*) [ -n "${BASHBOTDEBUG}" ] && debug_log "${FUNCNAME[0]}: unknown promotion ${arg}"
|
||||
*) [ -n "${BASHBOTDEBUG}" ] && log_debug "promote_chat_member: unknown promotion CHAT=${chat} USER=${user} PROM=${arg}"
|
||||
continue;;
|
||||
esac
|
||||
# compose json
|
||||
|
@ -137,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.40-0-gf9dab50
|
||||
#### $$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
|
||||
|
@ -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
|
||||
|
@ -88,7 +90,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
|
|||
[ -z "$2" ] && return 1
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -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//,/\",\"}" "${_//\"/\\\"}"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# File: processUpdates.sh
|
||||
# Note: DO NOT EDIT! this file will be overwritten on update
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
##################################################################
|
||||
|
||||
##############
|
||||
|
@ -43,25 +43,38 @@ delete_webhook() {
|
|||
}
|
||||
|
||||
################
|
||||
# processing of updates starts here
|
||||
# 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 num="$1" debug="$2"
|
||||
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
|
||||
# check for users / groups to ignore, inform them ...
|
||||
jssh_updateArray_async "BASHBOTBLOCKED" "${BLOCKEDFILE}"
|
||||
[ -n "${USER[ID]}" ] && [[ -n "${BASHBOTBLOCKED[${USER[ID]}]}" || -n "${BASHBOTBLOCKED[${CHAT[ID]}]}" ]] && return
|
||||
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
|
||||
|
@ -82,7 +95,11 @@ process_update() {
|
|||
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[*]//bot*:}"; printf "%s" "${_//[A-Z-]}")" >>"${UPDATELOG}"
|
||||
"${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
|
||||
|
@ -128,7 +145,6 @@ process_inline_query() {
|
|||
}
|
||||
|
||||
process_inline_button() {
|
||||
# debugging for impelemetation
|
||||
local num="$1"
|
||||
iBUTTON[DATA]="${UPD["result,${num},callback_query,data"]}"
|
||||
iBUTTON[CHAT_ID]="${UPD["result,${num},callback_query,message,chat,id"]}"
|
||||
|
@ -148,7 +164,14 @@ process_message() {
|
|||
# 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"]}")"
|
||||
|
@ -212,9 +235,6 @@ process_message() {
|
|||
VENUE[FOURSQUARE]="${UPD["result,${num},message,venue,foursquare_id"]}"
|
||||
fi
|
||||
|
||||
# Caption
|
||||
CAPTION="$(JsonDecode "${UPD["result,${num},message,caption"]}")"
|
||||
|
||||
# Location
|
||||
LOCATION[LONGITUDE]="${UPD["result,${num},message,location,longitude"]}"
|
||||
LOCATION[LATITUDE]="${UPD["result,${num},message,location,latitude"]}"
|
||||
|
@ -229,7 +249,6 @@ process_message() {
|
|||
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"]}"
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
MESSAGE[0]="/_new_chat_member ${NEWMEMBER[ID]} ${NEWMEMBER[USERNAME]:=${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]}}"
|
||||
fi
|
||||
# left chat member
|
||||
|
@ -240,16 +259,15 @@ process_message() {
|
|||
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"]}"
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
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"]}")"
|
||||
[ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[NEWTITLE]}" ] &&\
|
||||
[ -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"]}")"
|
||||
[ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[NEWPHOTO]}" ] &&\
|
||||
[ -n "${SERVICE[NEWPHOTO]}" ] &&\
|
||||
MESSAGE[0]="/_new_chat_photo ${USER[ID]} ${SERVICE[NEWPHOTO]}"
|
||||
fi
|
||||
# pinned message
|
||||
|
@ -257,8 +275,7 @@ process_message() {
|
|||
SERVICE[PINNED]="${UPD["result,${num},message,pinned_message,message_id"]}"
|
||||
PINNED[ID]="${SERVICE[PINNED]}"
|
||||
PINNED[MESSAGE]="$(JsonDecode "${UPD["result,${num},message,pinned_message,text"]}")"
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
MESSAGE[0]="/_new_pinned_message ${USER[ID]} ${PINNED[ID]} ${PINNED[MESSAGE]}"
|
||||
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
|
||||
|
@ -267,34 +284,36 @@ process_message() {
|
|||
# CHAT is already migrated, so set new chat id
|
||||
[ "${CHAT[ID]}" = "${MIGRATE[FROM]}" ] && CHAT[ID]="${MIGRATE[FROM]}"
|
||||
SERVICE[MIGRATE]="${MIGRATE[FROM]} ${MIGRATE[TO]}"
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
MESSAGE[0]="/_migrate_group ${SERVICE[MIGRATE]}"
|
||||
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 -r CMD <<<"${MESSAGE[0]}" && CMD[0]="${CMD[0]%%@*}"
|
||||
[[ "${MESSAGE[0]}" == "/"* ]] && read -ra CMD <<<"${MESSAGE[0]}" && CMD[0]="${CMD[0]%%@*}"
|
||||
# everything went well
|
||||
return 0
|
||||
}
|
||||
|
||||
#########################
|
||||
# main get updates loop, should never terminate
|
||||
# bot startup actions, call before start polling or webhook loop
|
||||
declare -A BASHBOTBLOCKED
|
||||
start_bot() {
|
||||
local DEBUGMSG
|
||||
# startup message
|
||||
DEBUGMSG="Start BASHBOT updates in Mode \"${1:-normal}\" =========="
|
||||
DEBUGMSG="BASHBOT startup actions, mode set to \"${1:-normal}\" =========="
|
||||
log_update "${DEBUGMSG}"
|
||||
# redirect to Debug.log
|
||||
# shellcheck disable=SC2153
|
||||
[[ "$1" == *"debug" ]] && exec &>>"${DEBUGLOG}"
|
||||
log_debug "${DEBUGMSG}"; DEBUGMSG="$1"
|
||||
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 -delete
|
||||
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
|
||||
|
@ -311,28 +330,22 @@ start_bot() {
|
|||
# shellcheck disable=SC2064
|
||||
trap "kill -9 $!; exit" EXIT INT HUP TERM QUIT
|
||||
fi
|
||||
# cleanup countfile on startup
|
||||
jssh_deleteKeyDB "CLEAN_COUNTER_DATABASE_ON_STARTUP" "${COUNTFILE}"
|
||||
[ -f "${COUNTFILE}.jssh.flock" ] && rm -f "${COUNTFILE}.jssh.flock"
|
||||
# store start time and cleanup botconfig on startup
|
||||
jssh_updateKeyDB "startup" "$(_date)" "${BOTCONFIG}"
|
||||
[ -f "${BOTCONFIG}.jssh.flock" ] && rm -f "${BOTCONFIG}.jssh.flock"
|
||||
# cleanup on start
|
||||
bot_cleanup "startup"
|
||||
# read blocked users
|
||||
jssh_readDB_async "BASHBOTBLOCKED" "${BLOCKEDFILE}"
|
||||
# inform botadmin about start
|
||||
send_normal_message "$(getConfigKey "botadmin")" "Bot $(getConfigKey "botname") started ..." &
|
||||
##########
|
||||
# bot is ready, start processing updates ...
|
||||
get_updates "${DEBUGMSG}"
|
||||
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")"
|
||||
|
@ -346,8 +359,6 @@ get_updates(){
|
|||
log_error "Recovered from timeout/broken/no connection, continue with telegram updates"
|
||||
# calculate next sleep interval
|
||||
((nextsleep+= stepsleep , nextsleep= nextsleep>maxsleep ?maxsleep:nextsleep))
|
||||
# escape bash $ expansion bug
|
||||
UPDATE="${UPDATE//$/\\$}"
|
||||
# warn if webhook is set
|
||||
if grep -q '^\["error_code"\] 409' <<<"${UPDATE}"; then
|
||||
[ "${OFFSET}" != "-999" ] && nextsleep="${stepsleep}"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
# shellcheck disable=SC1117
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$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,8 +166,10 @@ 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
|
||||
|
@ -177,8 +212,10 @@ _button_row() {
|
|||
# raw inline functions, for special use
|
||||
# $1 CHAT $2 message-id $3 keyboard
|
||||
edit_inline_keyboard() {
|
||||
sendJson "$1" '"message_id":'"$2"', "reply_markup": {"inline_keyboard": [ '"$3"' ]}' "${URL}/editMessageReplyMarkup"
|
||||
# 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"
|
||||
}
|
||||
|
||||
|
||||
|
@ -186,7 +223,8 @@ edit_inline_keyboard() {
|
|||
send_inline_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 callback id, $2 text to show, alert if not empty
|
||||
|
@ -199,6 +237,8 @@ answer_callback_query() {
|
|||
# $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"
|
||||
}
|
||||
|
||||
|
||||
|
@ -229,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
|
||||
|
@ -244,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
|
||||
|
||||
|
@ -313,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"
|
||||
}
|
||||
|
||||
|
||||
|
@ -342,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
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# Author: KayM (gnadelwartz), kay@rrr.de
|
||||
# Created: 09.01.2021 07:27
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#######################################################
|
||||
|
||||
##########
|
||||
|
@ -96,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"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# License: WTFPLv2 http://www.wtfpl.net/txt/copying/
|
||||
# Author: KayM (gnadelwartz), kay@rrr.de
|
||||
#
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$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]}"
|
||||
|
@ -281,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() {
|
||||
|
@ -291,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(){
|
||||
|
@ -307,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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#######################################################
|
||||
# shellcheck disable=SC1117
|
||||
|
||||
|
@ -126,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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$VERSION$$ v1.52-1-g0dae2db
|
||||
#===============================================================================
|
||||
|
||||
# include common functions and definitions
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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.40-0-gf9dab50
|
||||
#### $$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