Merge pull request #161 from topkecleon/develop Version 1.20

Version 1.2
This commit is contained in:
Kay Marquardt 2020-12-25 21:49:44 +01:00 committed by GitHub
commit 74ab0c24fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
69 changed files with 1395 additions and 764 deletions

2
.gitignore vendored
View File

@ -6,7 +6,7 @@
/botconf* /botconf*
/botacl* /botacl*
/botown* /botown*
ˆ.jssh *.jssh
*.save *.save
*.log *.log
*.swp *.swp

View File

@ -6,6 +6,136 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>Bashbot README</title> <title>Bashbot README</title>
<style> <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;} code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;} span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;} span.underline{text-decoration: underline;}
@ -74,6 +204,7 @@
code span.va { color: #19177c; } /* Variable */ code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */ code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */ code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
</style> </style>
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
@ -160,10 +291,9 @@ Written by Drew (@topkecleon) and Kay M (@gnadelwartz).
<p>In addition you need a <a href="https://telegram.org">Telegram client</a> and a mobile phone to <a href="https://telegramguide.com/create-a-telegram-account/">register an account</a>. If you don't want to register for Telegram you should stop reading here ;-)</p> <p>In addition you need a <a href="https://telegram.org">Telegram client</a> and a mobile phone to <a href="https://telegramguide.com/create-a-telegram-account/">register an account</a>. If you don't want to register for Telegram you should stop reading here ;-)</p>
<p>After you're registered to Telegram send a message to <a href="https://telegram.me/botfather">@botfather</a>, <a href="doc/1_firstbot.md">create a new Telegram Bot token</a> and write it down. You need the token to install the bot.</p> <p>After you're registered to Telegram send a message to <a href="https://telegram.me/botfather">@botfather</a>, <a href="doc/1_firstbot.md">create a new Telegram Bot token</a> and write it down. You need the token to install the bot.</p>
<p>Now open a terminal and check if bash is installed:</p> <p>Now open a terminal and check if bash is installed:</p>
<pre><code>which bash &amp;&amp; echo &quot;bash seems available...&quot; <pre><code>which bash &amp;&amp; echo &quot;bash seems available...&quot;</code></pre>
</code></pre>
<p>Create a new directory, change to it: <code>mkdir tbb; cd tbb</code> and download the latest '*.tar.gz' file from <a href="https://github.com/topkecleon/telegram-bot-bash/releases">https://github.com/topkecleon/telegram-bot-bash/releases</a>. This can be done with the commands:</p> <p>Create a new directory, change to it: <code>mkdir tbb; cd tbb</code> and download the latest '*.tar.gz' file from <a href="https://github.com/topkecleon/telegram-bot-bash/releases">https://github.com/topkecleon/telegram-bot-bash/releases</a>. This can be done with the commands:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1"></a><span class="fu">wget</span> -q https://github.com/<span class="va">$(</span><span class="fu">wget</span> -q https://github.com/topkecleon/telegram-bot-bash/releases/latest -O - <span class="kw">|</span> <span class="fu">egrep</span> <span class="st">&#39;/.*/.*/.*tar.gz&#39;</span> -o<span class="va">)</span></span></code></pre></div> <div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">wget</span> <span class="at">-q</span> https://github.com/<span class="va">$(</span><span class="fu">wget</span> <span class="at">-q</span> https://github.com/topkecleon/telegram-bot-bash/releases/latest <span class="at">-O</span> <span class="at">-</span> <span class="kw">|</span> <span class="fu">egrep</span> <span class="st">&#39;/.*/.*/.*tar.gz&#39;</span> <span class="at">-o</span><span class="va">)</span></span></code></pre></div>
<p>Extract the '*.tar.gz' file and change to bashbot directory: <code>tar -xzf *.tar.gz; cd telegram-bot-bash</code>, install bashbot: <code>./bashbot.sh init</code> and enter your bot token when asked. All other questions can be answered by hitting the &lt;Return&gt; key.</p> <p>Extract the '*.tar.gz' file and change to bashbot directory: <code>tar -xzf *.tar.gz; cd telegram-bot-bash</code>, install bashbot: <code>./bashbot.sh init</code> and enter your bot token when asked. All other questions can be answered by hitting the &lt;Return&gt; key.</p>
<p>That's all, now you can start your bot with <code>./bashbot.sh start</code> and send him messages:</p> <p>That's all, now you can start your bot with <code>./bashbot.sh start</code> and send him messages:</p>
<pre><code>/start <pre><code>/start
@ -177,8 +307,7 @@ You are Botadmin
/info /info
This is bashbot, the Telegram bot written entirely in bash. 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. It features background tasks and interactive chats, and can serve as an interface for CLI programs.</code></pre>
</code></pre>
<p>For more Information on how to install, customize and use your new bot, read the <a href="#Documentation">Documentation</a></p> <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> <h3>Log files</h3>
<p>Since version 0.96 bashbot log commands received/send and connection errors. If you start bashbot in debug mode bash stdout, stderr and all send/received telegram message are logged also.</p> <p>Since version 0.96 bashbot log commands received/send and connection errors. If you start bashbot in debug mode bash stdout, stderr and all send/received telegram message are logged also.</p>
@ -188,8 +317,7 @@ It features background tasks and interactive chats, and can serve as an interfac
│   ├── ERROR.log # connection errors from / to telegram API │   ├── ERROR.log # connection errors from / to telegram API
│   │ │   │
│   ├── DEBUG.log # stdout/stderr of you bot (debug mode enabled) │   ├── DEBUG.log # stdout/stderr of you bot (debug mode enabled)
│   └── MESSAGE.log # full text of all message send/received (debug mode enabled) │   └── MESSAGE.log # full text of all message send/received (debug mode enabled)</code></pre>
</code></pre>
<hr /> <hr />
<h2>Security Considerations</h2> <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>Running a Telegram Bot means it is connected to the public and you never know what's send to your Bot.</p>
@ -200,18 +328,19 @@ It features background tasks and interactive chats, and can serve as an interfac
<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> <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> <h3>Use printf whenever possible</h3>
<p>If you're writing a script and it is taking external input (from the user as arguments or file system...), you shouldn't use echo to display it. <a href="https://unix.stackexchange.com/a/6581">Use printf whenever possible</a></p> <p>If you're writing a script and it is taking external input (from the user as arguments or file system...), you shouldn't use echo to display it. <a href="https://unix.stackexchange.com/a/6581">Use printf whenever possible</a></p>
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1"></a> <span class="co"># very simple</span></span> <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="co"># very simple</span></span>
<span id="cb5-2"><a href="#cb5-2"></a> <span class="bu">echo</span> <span class="st">&quot;text with variables. PWD=</span><span class="va">$PWD</span><span class="st">&quot;</span></span> <span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a> <span class="bu">echo</span> <span class="st">&quot;text with variables. PWD=</span><span class="va">$PWD</span><span class="st">&quot;</span></span>
<span id="cb5-3"><a href="#cb5-3"></a> <span class="bu">printf</span> <span class="st">&#39;%s\n&#39;</span> <span class="st">&quot;text with variables. PWD=</span><span class="va">$PWD</span><span class="st">&quot;</span></span> <span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a> <span class="bu">printf</span> <span class="st">&#39;%s\n&#39;</span> <span class="st">&quot;text with variables. PWD=</span><span class="va">$PWD</span><span class="st">&quot;</span></span>
<span id="cb5-4"><a href="#cb5-4"></a> <span class="ex">-</span><span class="op">&gt;</span> text with variables. PWD=/home/xxx</span> <span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a> <span class="bu">printf</span> <span class="st">&#39;text with variables. PWD=%s\n&#39;</span> <span class="st">&quot;</span><span class="va">$PWD</span><span class="st">&quot;</span></span>
<span id="cb5-5"><a href="#cb5-5"></a></span> <span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a> <span class="ex">-</span><span class="op">&gt;</span> text with variables. PWD=/home/xxx</span>
<span id="cb5-6"><a href="#cb5-6"></a> <span class="co"># more advanced</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"></a> <span class="va">FLOAT=</span><span class="st">&quot;1.2346777892864&quot;</span> <span class="va">INTEGER=</span><span class="st">&quot;12345.123&quot;</span></span> <span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a> <span class="co"># more advanced</span></span>
<span id="cb5-8"><a href="#cb5-8"></a> <span class="bu">echo</span> <span class="st">&quot;text with variabeles. float=</span><span class="va">$FLOAT</span><span class="st">, integer=</span><span class="va">$INTEGER</span><span class="st">, PWD=</span><span class="va">$PWD</span><span class="st">&quot;</span></span> <span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a> <span class="va">FLOAT=</span><span class="st">&quot;1.2346777892864&quot;</span> <span class="va">INTEGER=</span><span class="st">&quot;12345.123&quot;</span></span>
<span id="cb5-9"><a href="#cb5-9"></a> <span class="ex">-</span><span class="op">&gt;</span>text with variables. float=1.2346777892864, integer=12345.123, PWD=/home/xxx</span> <span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a> <span class="bu">echo</span> <span class="st">&quot;float=</span><span class="va">$FLOAT</span><span class="st">, integer=</span><span class="va">$INTEGER</span><span class="st">, PWD=</span><span class="va">$PWD</span><span class="st">&quot;</span></span>
<span id="cb5-10"><a href="#cb5-10"></a></span> <span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a> <span class="ex">-</span><span class="op">&gt;</span> float=1.2346777892864, integer=12345.123, PWD=/home/xxx</span>
<span id="cb5-11"><a href="#cb5-11"></a> <span class="bu">printf</span> <span class="st">&quot;text with variables. float=%.2f, integer=%d, PWD=%s\n&quot;</span> <span class="st">&quot;&quot;</span> <span class="st">&quot;</span><span class="va">$INTEGER</span><span class="st">&quot;</span> <span class="st">&quot;</span><span class="va">$PWD</span><span class="st">&quot;</span></span> <span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-12"><a href="#cb5-12"></a> <span class="ex">-</span><span class="op">&gt;</span>text with variables. float=1.23, integer=12345, PWD=/home/xxx</span></code></pre></div> <span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a> <span class="bu">printf</span> <span class="st">&quot;text with variables. float=%.2f, integer=%d, PWD=%s\n&quot;</span> <span class="st">&quot;</span><span class="va">$FLOAT</span><span class="st">&quot;</span> <span class="st">&quot;</span><span class="va">$INTEGER</span><span class="st">&quot;</span> <span class="st">&quot;</span><span class="va">$PWD</span><span class="st">&quot;</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a> <span class="ex">-</span><span class="op">&gt;</span> float=1.23, integer=12345, PWD=/home/xxx</span></code></pre></div>
<h3>Do not use #!/usr/bin/env bash</h3> <h3>Do not use #!/usr/bin/env bash</h3>
<p><strong>We stay with /bin/bash shebang, because it's more save from security perspective.</strong></p> <p><strong>We stay with /bin/bash shebang, because it's more save from security perspective.</strong></p>
<p>Use of a fixed path to the system provided bash makes it harder for attackers or users to place alternative versions of bash and avoids using a possibly broken, mangled or compromised bash executable.</p> <p>Use of a fixed path to the system provided bash makes it harder for attackers or users to place alternative versions of bash and avoids using a possibly broken, mangled or compromised bash executable.</p>
@ -241,38 +370,40 @@ It features background tasks and interactive chats, and can serve as an interfac
<h3>Can I send messages from CLI and scripts?</h3> <h3>Can I send messages from CLI and scripts?</h3>
<p>Of course, you can send messages from CLI 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 stop the bot with <code>./bashbot.sh stop</code>.</p> <p>Of course, you can send messages from CLI 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 stop the bot with <code>./bashbot.sh stop</code>.</p>
<p>Run the following commands in your bash shell or script while you are in the installation directory:</p> <p>Run the following commands in your bash shell or script while you are in the installation directory:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1"></a><span class="co"># prepare bash / script to send commands</span></span> <div class="sourceCode" id="cb6"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="co"># prepare bash / script to send commands</span></span>
<span id="cb6-2"><a href="#cb6-2"></a><span class="bu">export</span> <span class="va">BASHBOT_HOME=</span><span class="st">&quot;</span><span class="va">$(</span><span class="bu">pwd</span><span class="va">)</span><span class="st">&quot;</span></span> <span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="bu">export</span> <span class="va">BASHBOT_HOME=</span><span class="st">&quot;</span><span class="va">$(</span><span class="bu">pwd</span><span class="va">)</span><span class="st">&quot;</span></span>
<span id="cb6-3"><a href="#cb6-3"></a><span class="bu">source</span> ./bashbot.sh source</span> <span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="bu">source</span> ./bashbot.sh source</span>
<span id="cb6-4"><a href="#cb6-4"></a></span> <span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-5"><a href="#cb6-5"></a><span class="co"># send me a test message</span></span> <span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="co"># send me a test message</span></span>
<span id="cb6-6"><a href="#cb6-6"></a><span class="ex">send_message</span> <span class="st">&quot;</span><span class="va">$(</span><span class="ex">getConfigKey</span> <span class="st">&quot;botadmin&quot;</span><span class="va">)</span><span class="st">&quot;</span> <span class="st">&quot;test&quot;</span></span> <span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a><span class="ex">send_message</span> <span class="st">&quot;</span><span class="va">$(</span><span class="ex">getConfigKey</span> <span class="st">&quot;botadmin&quot;</span><span class="va">)</span><span class="st">&quot;</span> <span class="st">&quot;test&quot;</span></span>
<span id="cb6-7"><a href="#cb6-7"></a></span> <span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-8"><a href="#cb6-8"></a><span class="co"># send me output of a system command</span></span> <span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="co"># send me output of a system command</span></span>
<span id="cb6-9"><a href="#cb6-9"></a><span class="ex">send_message</span> <span class="st">&quot;</span><span class="va">$(</span><span class="ex">getConfigKey</span> <span class="st">&quot;botadmin&quot;</span><span class="va">)</span><span class="st">&quot;</span> <span class="st">&quot;</span><span class="va">$(</span><span class="fu">df</span> -h<span class="va">)</span><span class="st">&quot;</span></span></code></pre></div> <span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a><span class="ex">send_message</span> <span class="st">&quot;</span><span class="va">$(</span><span class="ex">getConfigKey</span> <span class="st">&quot;botadmin&quot;</span><span class="va">)</span><span class="st">&quot;</span> <span class="st">&quot;</span><span class="va">$(</span><span class="fu">df</span> <span class="at">-h</span><span class="va">)</span><span class="st">&quot;</span></span></code></pre></div>
<p>For more information see <a href="doc/8_custom.md">Expert Use</a></p> <p>For more information see <a href="doc/8_custom.md">Expert Use</a></p>
<h3>Blocked by telegram?</h3> <h3>Blocked by telegram?</h3>
<p>This may happen if to many or wrong requests are sent to api.telegram.org, e.g. using a invalid token or not existing API calls. If the block stay for longer time you can ask telegram service to unblock your IP-Adress.</p> <p>This may happen if to many or wrong requests are sent to api.telegram.org, e.g. using a invalid token or not existing API calls. If the block stay for longer time you can ask telegram service to unblock your IP-Adress.</p>
<p>You can check with curl or wget if you are blocked by Telegram:</p> <p>You can check with curl or wget if you are blocked by Telegram:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1"></a><span class="ex">curl</span> -m 10 https://api.telegram.org/bot</span> <div class="sourceCode" id="cb7"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-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="cb7-2"><a href="#cb7-2"></a><span class="co">#curl: (28) Connection timed out after 10001 milliseconds</span></span> <span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="co">#curl: (28) Connection timed out after 10001 milliseconds</span></span>
<span id="cb7-3"><a href="#cb7-3"></a></span> <span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-4"><a href="#cb7-4"></a><span class="fu">wget</span> -t 1 -T 10 https://api.telegram.org/bot</span> <span id="cb7-4"><a href="#cb7-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="cb7-5"><a href="#cb7-5"></a><span class="co">#Connecting to api.telegram.org (api.telegram.org)|46.38.243.234|:443... failed: Connection timed out.</span></span></code></pre></div> <span id="cb7-5"><a href="#cb7-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="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-7"><a href="#cb7-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">&quot;your IP seems blocked by telegram&quot;</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="co">#your IP seems blocked by telegram</span></span></code></pre></div>
<p>Since Version 0.96 bashbot offers the option to recover from broken connections (aka blocked). Therefore you can provide a function named <code>bashbotBlockRecover()</code> in <code>mycommands.sh</code>. If the function exists it is called every time when a broken connection is detected.</p> <p>Since Version 0.96 bashbot offers the option to recover from broken connections (aka blocked). Therefore you can provide a function named <code>bashbotBlockRecover()</code> in <code>mycommands.sh</code>. If the function exists it is called every time when a broken connection is detected.</p>
<p>Possible actions are: Check if network is working, change IP-Adress or simply wait some time.</p> <p>Possible actions are: Check if network is working, change IP-Adress or simply wait some time.</p>
<p>If everything seems OK return 0 for retry or any non 0 value to give up.</p> <p>If everything seems OK return 0 for retry or any non 0 value to give up.</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1"></a><span class="co"># called when bashbot sedn command failed because we can not connect to telegram</span></span> <div class="sourceCode" id="cb8"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="co"># called when bashbot sedn command failed because we can not connect to telegram</span></span>
<span id="cb8-2"><a href="#cb8-2"></a><span class="co"># return 0 to retry, return non 0 to give up</span></span> <span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="co"># return 0 to retry, return non 0 to give up</span></span>
<span id="cb8-3"><a href="#cb8-3"></a><span class="fu">bashbotBlockRecover()</span> <span class="kw">{</span></span> <span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="fu">bashbotBlockRecover()</span> <span class="kw">{</span></span>
<span id="cb8-4"><a href="#cb8-4"></a> <span class="co"># place your commands to unblock here, e.g. change IP-Adess or simply wait</span></span> <span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a> <span class="co"># place your commands to unblock here, e.g. change IP-Adess or simply wait</span></span>
<span id="cb8-5"><a href="#cb8-5"></a> <span class="fu">sleep</span> 60 <span class="kw">&amp;&amp;</span> <span class="bu">return</span> 0 <span class="co"># may be temporary</span></span> <span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a> <span class="fu">sleep</span> 60 <span class="kw">&amp;&amp;</span> <span class="cf">return</span> <span class="dv">0</span> <span class="co"># may be temporary</span></span>
<span id="cb8-6"><a href="#cb8-6"></a> <span class="bu">return</span> 1 </span> <span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a> <span class="cf">return</span> <span class="dv">1</span> </span>
<span id="cb8-7"><a href="#cb8-7"></a> <span class="kw">}</span></span> <span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a> <span class="er">}</span></span></code></pre></div>
<span id="cb8-8"><a href="#cb8-8"></a></span></code></pre></div>
<p>@Gnadelwartz</p> <p>@Gnadelwartz</p>
<h2>That's it all guys!</h2> <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> <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.1-0-ge835bbc</h4> <h4>$$VERSION$$ v1.20-0-g2ab00a2</h4>
</body> </body>
</html> </html>

View File

@ -152,15 +152,16 @@ you shouldn't use echo to display it. [Use printf whenever possible](https://uni
# very simple # very simple
echo "text with variables. PWD=$PWD" echo "text with variables. PWD=$PWD"
printf '%s\n' "text with variables. PWD=$PWD" printf '%s\n' "text with variables. PWD=$PWD"
printf 'text with variables. PWD=%s\n' "$PWD"
-> text with variables. PWD=/home/xxx -> text with variables. PWD=/home/xxx
# more advanced # more advanced
FLOAT="1.2346777892864" INTEGER="12345.123" FLOAT="1.2346777892864" INTEGER="12345.123"
echo "text with variabeles. float=$FLOAT, integer=$INTEGER, PWD=$PWD" echo "float=$FLOAT, integer=$INTEGER, PWD=$PWD"
->text with variables. float=1.2346777892864, integer=12345.123, PWD=/home/xxx -> float=1.2346777892864, integer=12345.123, PWD=/home/xxx
printf "text with variables. float=%.2f, integer=%d, PWD=%s\n" "" "$INTEGER" "$PWD" printf "text with variables. float=%.2f, integer=%d, PWD=%s\n" "$FLOAT" "$INTEGER" "$PWD"
->text with variables. float=1.23, integer=12345, PWD=/home/xxx -> float=1.23, integer=12345, PWD=/home/xxx
``` ```
### Do not use #!/usr/bin/env bash ### Do not use #!/usr/bin/env bash
@ -238,6 +239,9 @@ curl -m 10 https://api.telegram.org/bot
wget -t 1 -T 10 https://api.telegram.org/bot wget -t 1 -T 10 https://api.telegram.org/bot
#Connecting to api.telegram.org (api.telegram.org)|46.38.243.234|:443... failed: Connection timed out. #Connecting to api.telegram.org (api.telegram.org)|46.38.243.234|:443... failed: Connection timed out.
nc -w 2 api.telegram.org 443 || echo "your IP seems blocked by telegram"
#your IP seems blocked by telegram
``` ```
Since Version 0.96 bashbot offers the option to recover from broken connections (aka blocked). Therefore you can provide a function Since Version 0.96 bashbot offers the option to recover from broken connections (aka blocked). Therefore you can provide a function
@ -265,4 +269,4 @@ bashbotBlockRecover() {
If you feel that there's something missing or if you found a bug, feel free to submit a pull request! If you feel that there's something missing or if you found a bug, feel free to submit a pull request!
#### $$VERSION$$ v1.1-0-ge835bbc #### $$VERSION$$ v1.20-0-g2ab00a2

View File

@ -204,16 +204,17 @@ possible](https://unix.stackexchange.com/a/6581)
# very simple # very simple
echo "text with variables. PWD=$PWD" echo "text with variables. PWD=$PWD"
printf '%s\n' "text with variables. PWD=$PWD" printf '%s\n' "text with variables. PWD=$PWD"
printf 'text with variables. PWD=%s\n' "$PWD"
-> text with variables. PWD=/home/xxx -> text with variables. PWD=/home/xxx
# more advanced # more advanced
FLOAT="1.2346777892864" INTEGER="12345.123" FLOAT="1.2346777892864" INTEGER="12345.123"
echo "text with variabeles. float=$FLOAT, integer=$INTEGER, PWD=$PWD" echo "float=$FLOAT, integer=$INTEGER, PWD=$PWD"
->text with variables. float=1.2346777892864, integer=12345.123, PWD=/home/xxx -> float=1.2346777892864, integer=12345.123, PWD=/home/xxx
printf "text with variables. float=%.2f, integer=%d, PWD=%s\n" "" "$INTEGER" printf "text with variables. float=%.2f, integer=%d, PWD=%s\n" "$FLOAT"
"$PWD" "$INTEGER" "$PWD"
->text with variables. float=1.23, integer=12345, PWD=/home/xxx -> float=1.23, integer=12345, PWD=/home/xxx
``` ```
### Do not use #!/usr/bin/env bash ### Do not use #!/usr/bin/env bash
@ -323,6 +324,9 @@ curl -m 10 https://api.telegram.org/bot
wget -t 1 -T 10 https://api.telegram.org/bot wget -t 1 -T 10 https://api.telegram.org/bot
#Connecting to api.telegram.org (api.telegram.org)|46.38.243.234|:443... #Connecting to api.telegram.org (api.telegram.org)|46.38.243.234|:443...
failed: Connection timed out. failed: Connection timed out.
nc -w 2 api.telegram.org 443 || echo "your IP seems blocked by telegram"
#your IP seems blocked by telegram
``` ```
Since Version 0.96 bashbot offers the option to recover from broken connections Since Version 0.96 bashbot offers the option to recover from broken connections
@ -355,4 +359,4 @@ wait
If you feel that there's something missing or if you found a bug, feel free to If you feel that there's something missing or if you found a bug, feel free to
submit a pull request! submit a pull request!
#### $$VERSION$$ v1.1-0-ge835bbc #### $$VERSION$$ v1.20-0-g2ab00a2

View File

@ -4,7 +4,7 @@
# this addon counts how many files, e.g. stickers, are sent to # this addon counts how many files, e.g. stickers, are sent to
# a chat and takes actions if threshold is reached # a chat and takes actions if threshold is reached
# #
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# used events: # used events:
# #

View File

@ -4,7 +4,7 @@
# Addons can register to bashbot events at startup # Addons can register to bashbot events at startup
# by providing their name and a callback per event # by providing their name and a callback per event
# #
#### $$VERSION$$ v1.2-dev-13-g2a5d47d #### $$VERSION$$ v1.20-0-g2ab00a2
# #
# If an event occurs each registered event function is called. # If an event occurs each registered event function is called.
# #

View File

@ -1,7 +1,11 @@
#!/bin/sh #!/bin/sh
# description: Start or stop telegram-bash-bot # description: Start or stop telegram-bash-bot
# #
#### $$VERSION$$ v1.2-dev-13-g2a5d47d # example service script to run bashbot in background as specified user
#
# tested on: ubuntu, opensuse, debian
#
#### $$VERSION$$ v1.20-0-g2ab00a2
# shellcheck disable=SC2009 # shellcheck disable=SC2009
# shellcheck disable=SC2181 # shellcheck disable=SC2181
@ -25,7 +29,7 @@ runcmd="echo Dry run:" # not activated until you edit lines below
# edit the next line to fit the user you want to run bashbot, e.g. nobody: # edit the next line to fit the user you want to run bashbot, e.g. nobody:
runas="nobody" runas="nobody"
# uncomment one of the following lines to fit your system # uncomment one of the example lines to fit your system
# runcmd="su $runas -s /bin/bash -c " # runasuser with *su* # runcmd="su $runas -s /bin/bash -c " # runasuser with *su*
# runcmd="runuser $runas -s /bin/bash -c " # runasuser with *runuser* # runcmd="runuser $runas -s /bin/bash -c " # runasuser with *runuser*

View File

@ -11,7 +11,7 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.2-dev-25-g0b64af7 #### $$VERSION$$ v1.20-0-g2ab00a2
# #
# Exit Codes: # Exit Codes:
# - 0 success (hopefully) # - 0 success (hopefully)
@ -22,13 +22,14 @@
# - 5 cannot connect to telegram bot # - 5 cannot connect to telegram bot
# - 6 mandatory module not found # - 6 mandatory module not found
# - 7 can't get bottoken # - 7 can't get bottoken
# - 8 curl/wget missing
# - 10 not bash! # - 10 not bash!
# shellcheck disable=SC2140,SC2031,SC2120,SC1091 # shellcheck disable=SC2140,SC2031,SC2120,SC1091,SC1117
# emmbeded system may claim bash but it is not # emmbeded system may claim bash but it is not
# check for bash like ARRAY handlung # check for bash like ARRAY handlung
if ! (unset a; set -A a a; eval "a=(a b)"; eval '[ -n "${a[1]}" ]'; ) > /dev/null 2>&1; then if ! (unset a; set -A a a; eval "a=(a b)"; eval '[ -n "${a[1]}" ]'; ) > /dev/null 2>&1; then
echo "iError: Current shell does not support ARRAY's, may be busbox ash shell. pls install a real bash!"; echo "Error: Current shell does not support ARRAY's, may be busbox ash shell. pls install a real bash!";
exit 10 exit 10
fi fi
@ -42,30 +43,36 @@ if [ -t 1 ] && [ -n "$TERM" ]; then
NC='\e[0m' NC='\e[0m'
fi fi
# we need some bash 4+ features, check for old bash by feature # telegram uses utf-8 characters, check if we have an utf-8 charset
if [ "$(echo -e "\u1111")" == "\u1111" ]; then if [ "${LANG}" = "${LANG%[Uu][Tt][Ff]*}" ]; then
echo -e "${ORANGE}Warning: Unicode '\uxxxx' seems not supported, install a more current bash.${NC}" echo -e "${ORANGE}Warning: Telegram uses utf-8, but looks like you are using non utf-8 locale:${NC} ${LANG}"
fi fi
# we need some bash 4+ features, check for old bash by feature
if [ "$({ LC_ALL=C.utf-8 echo -e "\u1111"; } 2>/dev/null)" = "\u1111" ]; then
echo -e "${ORANGE}Warning: Missing unicode '\uxxxx' support, missing C.utf-8 locale or to old bash version.${NC}"
fi
# some important helper functions # some important helper functions
# returns true if command exist # returns true if command exist
_exists() { _exists() {
[ "$(LC_ALL=C type -t "${1}")" = "file" ] [ "$(type -t "${1}")" = "file" ]
} }
# execute function if exists # execute function if exists
_exec_if_function() { _exec_if_function() {
[ "$(LC_ALL=C type -t "${1}")" != "function" ] && return 1 [ "$(type -t "${1}")" != "function" ] && return 1
"$@" "$@"
} }
# returns true if function exist # returns true if function exist
_is_function() { _is_function() {
[ "$(LC_ALL=C type -t "${1}")" = "function" ] [ "$(type -t "${1}")" = "function" ]
} }
# round $1 in international notation! , returns float with $2 decimal digits # round $1 in international notation! , returns float with $2 decimal digits
# if $2 is not given or is not a positive number zero is assumed # if $2 is not given or is not a positive number zero is assumed
_round_float() { _round_float() {
local digit="${2}"; [[ "${2}" =~ ^[0-9]+$ ]] || digit="0" local digit="${2}"; [[ "${2}" =~ ^[0-9]+$ ]] || digit="0"
LC_ALL=C printf "%.${digit}f" "${1}" { LC_ALL=C.utf-8 printf "%.${digit}f" "${1}"; } 2>/dev/null
} }
setConfigKey() { setConfigKey() {
[[ "$1" =~ ^[-a-zA-Z0-9,._]+$ ]] || return 3 [[ "$1" =~ ^[-a-zA-Z0-9,._]+$ ]] || return 3
@ -83,16 +90,17 @@ check_token(){
return 1 return 1
} }
# log $1 to ERRORLOG with date # log $1 to ERRORLOG with date
log_error(){ log_error(){ printf "%s: %b\n" "$(date)" "$*" >>"${ERRORLOG}"; }
printf "%s: %s\n" "$(date)" "$*" >>"${ERRORLOG}" log_debug(){ printf "%s: %b\n" "$(date)" "$*" >>"${DEBUGLOG}"; }
} log_message(){ printf "\n%s: %b\n" "$(date)" "$*" >>"${MESSAGELOG}"; }
log_update(){ printf "%s: %b\n" "$(date)" "$*" >>"${UPDATELOG}"; }
# additional tests if we run in debug mode # additional tests if we run in debug mode
export BASHBOTDEBUG export BASHBOTDEBUG
# debug should always last argument # debug should always last argument
[[ "${BASH_ARGV[0]}" == *"debug"* ]] && BASHBOTDEBUG="yes" [[ "${BASH_ARGV[0]}" == *"debug"* ]] && BASHBOTDEBUG="yes"
# $1 where $2 command $3 may debug # $1 where $2 command $3 may debug
# shellcheck disable=SC2094 # shellcheck disable=SC2094
debug_checks(){ debug_checks(){ {
[ -z "${BASHBOTDEBUG}" ] && return [ -z "${BASHBOTDEBUG}" ] && return
local DATE WHERE MYTOKEN; DATE="$(date)"; WHERE="${1}"; shift local DATE WHERE MYTOKEN; DATE="$(date)"; WHERE="${1}"; shift
printf "%s: debug_checks: %s: bashbot.sh %s\n" "${DATE}" "${WHERE}" "${@##*/}" printf "%s: debug_checks: %s: bashbot.sh %s\n" "${DATE}" "${WHERE}" "${@##*/}"
@ -104,7 +112,13 @@ debug_checks(){
[ -z "$(getConfigKey "botadmin")" ] && printf "%s: %s\n" "${DATE}" "Bot admin is missing! ==========" [ -z "$(getConfigKey "botadmin")" ] && printf "%s: %s\n" "${DATE}" "Bot admin is missing! =========="
# call user defined debug_checks if exists # call user defined debug_checks if exists
_exec_if_function my_debug_checks "${DATE}" "${WHERE}" "$*" _exec_if_function my_debug_checks "${DATE}" "${WHERE}" "$*"
} >>"${DEBUGLOG}" } >>"${DEBUGLOG}"
}
# some linux, e.g. manajro seems not to have C locale activated by default
if _exists locale && [ "$(locale -a | grep -c -e "^C$" -e "^C.utf8$")" -lt 2 ]; then
echo -e "${ORANGE}Warning: locale ${NC}${GREY}C${NC}${ORANGE} and/or ${NC}${GREY}C.utf8${NC}${ORANGE} seems missing, use \"${NC}${GREY}locale -a${NC}${ORANGE}\" to show what locales are installed on your system.${NC}"
fi
# get location and name of bashbot.sh # get location and name of bashbot.sh
SCRIPT="$0" SCRIPT="$0"
@ -119,7 +133,7 @@ if [ "${SCRIPT}" != "${REALME}" ] || [ "$1" = "source" ]; then
SOURCE="yes" SOURCE="yes"
fi fi
BOTCOMMANDS="start, stop, status, help, init, stats, broadcast, suspendback, resumeback, killback" BOTCOMMANDS="start, stop, status, help, init, suspendback, resumeback, killback"
[[ -z "$1" && -z "${SOURCE}" ]] && echo -e "${ORANGE}Available commands: ${GREY}${BOTCOMMANDS}${NC}" && exit [[ -z "$1" && -z "${SOURCE}" ]] && echo -e "${ORANGE}Available commands: ${GREY}${BOTCOMMANDS}${NC}" && exit
if [ "$1" = "help" ]; then if [ "$1" = "help" ]; then
HELP="${BASHBOT_HOME:-.}/README" HELP="${BASHBOT_HOME:-.}/README"
@ -168,16 +182,13 @@ COUNTFILE="${BASHBOT_VAR:-.}/count"
LOGDIR="${RUNDIR:-.}/logs" LOGDIR="${RUNDIR:-.}/logs"
# assume everything already set up correctly if TOKEN is set # assume everything already set up correctly if TOKEN is set
if [ -z "${BOTTOKEN}" ]; then if [[ -z "${BOTTOKEN}" && ! -f "${BOTCONFIG}.jssh" ]]; then
# BOTCONFIG does not exist, create # BOTCONFIG does not exist, create
[ ! -f "${BOTCONFIG}.jssh" ] &&
printf '["bot_config_key"]\t"config_key_value"\n' >>"${BOTCONFIG}.jssh" printf '["bot_config_key"]\t"config_key_value"\n' >>"${BOTCONFIG}.jssh"
# do we have already a token?
if [ -z "$(getConfigKey "bottoken")" ]; then
# convert old token # convert old token
if [ -r "${TOKENFILE}" ]; then if [ -r "${TOKENFILE}" ]; then
token="$(< "${TOKENFILE}")" token="$(< "${TOKENFILE}")"
# no old token available ask user # no old token, ask user
elif [ -z "${CLEAR}" ] && [ "$1" != "init" ]; then elif [ -z "${CLEAR}" ] && [ "$1" != "init" ]; then
echo "Running headless, set BOTTOKEN or run ${SCRIPT} init first!" echo "Running headless, set BOTTOKEN or run ${SCRIPT} init first!"
exit 2 exit 2
@ -188,7 +199,6 @@ if [ -z "${BOTTOKEN}" ]; then
read -r token read -r token
fi fi
[ -n "${token}" ] && printf '["bottoken"]\t"%s"\n' "${token}" >> "${BOTCONFIG}.jssh" [ -n "${token}" ] && printf '["bottoken"]\t"%s"\n' "${token}" >> "${BOTCONFIG}.jssh"
fi
# no botadmin, setup botadmin # no botadmin, setup botadmin
if [ -z "$(getConfigKey "botadmin")" ]; then if [ -z "$(getConfigKey "botadmin")" ]; then
@ -238,45 +248,48 @@ if [ -z "${BOTTOKEN}" ]; then
fi fi
fi fi
if [ ! -d "${LOGDIR}" ] || [ ! -w "${LOGDIR}" ]; then if [[ ! -d "${LOGDIR}" || ! -w "${LOGDIR}" ]]; then
LOGDIR="${RUNDIR:-.}" LOGDIR="${RUNDIR:-.}"
fi fi
DEBUGLOG="${LOGDIR}/DEBUG.log" DEBUGLOG="${LOGDIR}/DEBUG.log"
ERRORLOG="${LOGDIR}/ERROR.log" ERRORLOG="${LOGDIR}/ERROR.log"
UPDATELOG="${LOGDIR}/BASHBOT.log" UPDATELOG="${LOGDIR}/BASHBOT.log"
MESSAGELOG="${LOGDIR}/MESSAGE.log"
debug_checks "start SOURCE=${SOURCE:-no}" "$@" debug_checks "start SOURCE=${SOURCE:-no}" "$@"
# read BOTTOKEN from bot database if not set # read BOTTOKEN from bot database if not set
if [ -z "${BOTTOKEN}" ]; then if [ -z "${BOTTOKEN}" ]; then
BOTTOKEN="$(getConfigKey "bottoken")" BOTTOKEN="$(getConfigKey "bottoken")"
if [ -z "${BOTTOKEN}" ]; then if [ -z "${BOTTOKEN}" ]; then
BOTERROR="Warning: can't get bot token, try to recover working config" BOTERROR="Warning: can't get bot token, try to recover working config..."
echo -e "${ORANGE}${BOTERROR}${NC}" echo -e "${ORANGE}${BOTERROR}${NC} \c"
if [ -r "${BOTCONFIG}.jssh.ok" ]; then if [ -r "${BOTCONFIG}.jssh.ok" ]; then
log_error "${BOTERROR}" log_error "${BOTERROR}"
cp "${BOTCONFIG}.jssh.ok" "${BOTCONFIG}.jssh" cp "${BOTCONFIG}.jssh.ok" "${BOTCONFIG}.jssh"; echo "OK"
BOTTOKEN="$(getConfigKey "bottoken")" BOTTOKEN="$(getConfigKey "bottoken")"
else else
echo -e "${RED}Error: Missing bot token! remove ${BOTCONFIG}.jssh and run \"bashbot.sh init\" may fix it.${NC}" echo -e "\n${RED}Error: Missing bot token! remove ${BOTCONFIG}.jssh and run \"bashbot.sh init\" may fix it.${NC}"
exit 7 exit 7
fi fi
fi fi
fi fi
# BOTTOKEN format checks # BOTTOKEN format checks
if ! check_token "${BOTTOKEN}"; then if ! check_token "${BOTTOKEN}"; then
echo -e "${ORANGE}Warning: your bottoken may incorrect. it should have the following format:${NC}" echo -e "${ORANGE}Warning: your bottoken may incorrect. it should have the following format:${NC}"
echo -e "${GREY}123456789${RED}:${GREY}Aa-Zz_0Aa-Zz_1Aa-Zz_2Aa-Zz_3Aa-Zz_4${ORANGE} => ${NC}\c" echo -e "${GREY}123456789${RED}:${GREY}Aa-Zz_0Aa-Zz_1Aa-Zz_2Aa-Zz_3Aa-Zz_4${ORANGE} => ${NC}\c"
echo -e "${GREY}8-10 digits${RED}:${GREY}35 alphanumeric characters + '_-'${NC}" echo -e "${GREY}8-10 digits${RED}:${GREY}35 alphanumeric characters + '_-'${NC}"
echo -e "${ORANGE}Your current token is: '${GREY}^$(cat -ve <<<"${BOTTOKEN//:/${RED}:${GREY}}")${ORANGE}'${NC}" echo -e "${ORANGE}Your current token is: '${GREY}^$(cat -ve <<<"${BOTTOKEN//:/${RED}:${GREY}}")${ORANGE}'${NC}"
[[ ! "${BOTTOKEN}" =~ ^[0-9]{8,10}: ]] &&\ if [[ ! "${BOTTOKEN}" =~ ^[0-9]{8,10}: ]]; then
echo -e "${ORANGE}Possible problem in the digits part, len is $(($(wc -c <<<"${BOTTOKEN%:*}")-1))${NC}" echo -e "${ORANGE}Possible problem in the digits part, len is $(($(wc -c <<<"${BOTTOKEN%:*}")-1))${NC}"
[ -n "$(getConfigKey "botid")" ] && echo -e "${GREY}Did you mean: \"${NC}$(getConfigKey "botid")${GREY}\" ?${NC}"
fi
[[ ! "${BOTTOKEN}" =~ :[a-zA-Z0-9_-]{35}$ ]] &&\ [[ ! "${BOTTOKEN}" =~ :[a-zA-Z0-9_-]{35}$ ]] &&\
echo -e "${ORANGE}Possible problem in the characters part, len is $(($(wc -c <<<"${BOTTOKEN#*:}")-1))${NC}" echo -e "${ORANGE}Possible problem in the characters part, len is $(($(wc -c <<<"${BOTTOKEN#*:}")-1))${NC}"
fi fi
################## ##################
# here we start with the real stuff # here we start with the real stuff
BASHBOT_RETRY="" # retry by default BASHBOT_RETRY="" # retry by default
@ -295,8 +308,8 @@ declare -rx BOTTOKEN URL ME_URL UPD_URL GETFILE_URL
declare -ax CMD declare -ax CMD
declare -Ax UPD BOTSENT USER MESSAGE URLS CONTACT LOCATION CHAT FORWARD REPLYTO VENUE iQUERY declare -Ax UPD BOTSENT USER MESSAGE URLS CONTACT LOCATION CHAT FORWARD REPLYTO VENUE iQUERY
declare -Ax SERVICE NEWMEMBER LEFTMEMBER PINNED declare -Ax SERVICE NEWMEMBER LEFTMEMBER PINNED MIGRATE
export res CAPTION export res CAPTION ME
################## ##################
@ -375,7 +388,7 @@ killallproc() {
# $ chat $2 msg_id $3 nolog # $ chat $2 msg_id $3 nolog
declare -xr DELETE_URL=$URL'/deleteMessage' declare -xr DELETE_URL=$URL'/deleteMessage'
delete_message() { delete_message() {
[ -z "$3" ] && printf "%s: Delete Message CHAT=%s MSG_ID=%s\n" "$(date)" "${1}" "${2}" >>"${UPDATELOG}" [ -z "$3" ] && log_update "Delete Message CHAT=${1} MSG_ID=${2}"
sendJson "${1}" '"message_id": '"${2}"'' "${DELETE_URL}" sendJson "${1}" '"message_id": '"${2}"'' "${DELETE_URL}"
} }
@ -385,14 +398,19 @@ get_file() {
printf '%s\n' "${URL}"/"$(JsonGetString <<< "${res}" '"result","file_path"')" printf '%s\n' "${URL}"/"$(JsonGetString <<< "${res}" '"result","file_path"')"
} }
# curl is preferred, try detect curl even not in PATH
# return TRUE if curl is found or custom curl detected # return TRUE if curl is found or custom curl detected
# return FALSE if no curl is found or wget is forced by BASHBOT_WGET # return FALSE if no curl is found or wget is forced by BASHBOT_WGET
# sets BASHBOT_CURL to point to curl # sets BASHBOT_CURL to point to curl
DETECTED_CURL="curl"
function detect_curl() { function detect_curl() {
# custom curl command # custom curl command
[ -n "${BASHBOT_CURL}" ] && return 0 [ -n "${BASHBOT_CURL}" ] && return 0
# use wget # use wget
[ -n "${BASHBOT_WGET}" ] && return 1 if [ -n "${BASHBOT_WGET}" ]; then
DETECTED_CURL="wget"
return 1
fi
# default use curl in PATH # default use curl in PATH
BASHBOT_CURL="curl" BASHBOT_CURL="curl"
_exists curl && return 0 _exists curl && return 0
@ -405,48 +423,72 @@ function detect_curl() {
fi fi
done done
# curl not in PATH and not in usual locations # curl not in PATH and not in usual locations
DETECTED_CURL="wget"
local warn="Warning: Curl not detected, try fallback to wget! pls install curl or adjust BASHBOT_CURL/BASHBOT_WGET environment variables." local warn="Warning: Curl not detected, try fallback to wget! pls install curl or adjust BASHBOT_CURL/BASHBOT_WGET environment variables."
printf "%s: %s\n" "$(date)" "${warn}" >>"${UPDATELOG}" log_update "${warn}"; [ -n "${BASHBOTDEBUG}" ] && log_debug "${warn}"
[ -n "${BASHBOTDEBUG}" ] && printf "%s: %s\n" "$(date)" "${warn}" >>"${DEBUGLOG}"
return 1 return 1
} }
# iconv used to filter out broken utf characters, if not installed fake it # iconv used to filter out broken utf characters, if not installed fake it
if ! _exists iconv; then if ! _exists iconv; then
printf "%s: %s\n" "$(date)" "Warning: iconv not installed, pls imstall iconv!" >>"${UPDATELOG}" log_update "Warning: iconv not installed, pls imstall iconv!"
function iconv() { cat; } function iconv() { cat; }
fi fi
TIMEOUT="${BASHBOT_TIMEOUT}" TIMEOUT="${BASHBOT_TIMEOUT}"
[[ "$TIMEOUT" =~ ^[0-9]+$ ]] || TIMEOUT="20" [[ "$TIMEOUT" =~ ^[0-9]+$ ]] || TIMEOUT="20"
# usage: sendJson "chat" "JSON" "URL"
sendJson(){
local json chat=""
if [ -n "${1}" ]; then
chat='"chat_id":'"${1}"','
[[ "${1}" == *[!0-9-]* ]] && chat='"chat_id":"'"${1}"' NAN",' # chat id not a number!
fi
# 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##*/}"
log_message "DEBUG sendJson ==========\n$("${JSONSHFILE}" -b -n <<<"${json}" 2>&1)"
fi
# chat id not a number
if [[ "${chat}" == *"NAN\"," ]]; then
sendJsonResult "$(printf '["ok"]\tfalse\n["error_code"]\t400\n["description"]\t"Bad Request: chat id not a number"\n')"\
"sendJson (NAN)" "$@"
return
fi
# OK here we go ...
# route to curl/wget specific function
res="$(sendJson_do "${json}" "${3}")"
# check telegram response
sendJsonResult "${res}" "sendJson (${DETECTED_CURL})" "$@"
[ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "send" "${@}" &
}
#
# curl / wget specific functions
#
if detect_curl ; then if detect_curl ; then
# here we have curl ----
[ -z "${BASHBOT_CURL}" ] && BASHBOT_CURL="curl" [ -z "${BASHBOT_CURL}" ] && BASHBOT_CURL="curl"
# simple curl or wget call, output to stdout
getJson(){ getJson(){
[[ -n "${BASHBOTDEBUG}" && -n "${3}" ]] && printf "%s: getJson (curl) URL=%s\n" "$(date)" "${1##*/}" >>"${DEBUGLOG}" [[ -n "${BASHBOTDEBUG}" && -n "${3}" ]] && log_debug "getJson (curl) URL=${1##*/}"
# shellcheck disable=SC2086 # shellcheck disable=SC2086
"${BASHBOT_CURL}" -sL -k ${BASHBOT_CURL_ARGS} -m "${TIMEOUT}" "$1" "${BASHBOT_CURL}" -sL -k ${BASHBOT_CURL_ARGS} -m "${TIMEOUT}" "$1"
} }
# usage: sendJson "chat" "JSON" "URL" # curl variant for sendJson
sendJson(){ # usage: "JSON" "URL"
local chat=""; sendJson_do(){
[ -n "${1}" ] && chat='"chat_id":'"${1}"','
[ -n "${BASHBOTDEBUG}" ] &&\
printf "%s: sendJson (curl) CHAT=%s JSON=%s URL=%s\n" "$(date)" "${1}" "${2:0:100}" "${3##*/}" >>"${UPDATELOG}"
# shellcheck disable=SC2086 # shellcheck disable=SC2086
res="$("${BASHBOT_CURL}" -s -k ${BASHBOT_CURL_ARGS} -m "${TIMEOUT}"\ "${BASHBOT_CURL}" -s -k ${BASHBOT_CURL_ARGS} -m "${TIMEOUT}"\
-d '{'"${chat} $(iconv -f utf-8 -t utf-8 -c <<<$2)"'}' -X POST "${3}" \ -d "${1}" -X POST "${2}" -H "Content-Type: application/json" | "${JSONSHFILE}" -b -n 2>/dev/null
-H "Content-Type: application/json" | "${JSONSHFILE}" -b -n 2>/dev/null )"
sendJsonResult "${res}" "sendJson (curl)" "$@"
[ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "send" "${@}" &
} }
#$1 Chat, $2 what, $3 file, $4 URL, $5 caption #$1 Chat, $2 what, $3 file, $4 URL, $5 caption
sendUpload() { sendUpload() {
[ "$#" -lt 4 ] && return [ "$#" -lt 4 ] && return
if [ -n "$5" ]; then if [ -n "$5" ]; then
[ -n "${BASHBOTDEBUG}" ] &&\ [ -n "${BASHBOTDEBUG}" ] &&\
printf "%s: sendUpload CHAT=%s WHAT=%s FILE=%s CAPT=%s\n" "$(date)" "${1}" "${2}" "${3}" "${4}" >>"${UPDATELOG}" log_update "sendUpload CHAT=${1} WHAT=${2} FILE=${3} CAPT=${5}"
# shellcheck disable=SC2086 # shellcheck disable=SC2086
res="$("${BASHBOT_CURL}" -s -k ${BASHBOT_CURL_ARGS} "$4" -F "chat_id=$1"\ res="$("${BASHBOT_CURL}" -s -k ${BASHBOT_CURL_ARGS} "$4" -F "chat_id=$1"\
-F "$2=@$3;${3##*/}" -F "caption=$5" | "${JSONSHFILE}" -b -n 2>/dev/null )" -F "$2=@$3;${3##*/}" -F "caption=$5" | "${JSONSHFILE}" -b -n 2>/dev/null )"
@ -459,29 +501,34 @@ if detect_curl ; then
[ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "upload" "$@" & [ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "upload" "$@" &
} }
else else
# simple curl or wget call outputs result to stdout # NO curl, try wget
if _exists wget; then
getJson(){ getJson(){
[[ -n "${BASHBOTDEBUG}" && -z "${3}" ]] && printf "%s: getJson (wget) URL=%s\n" "$(date)" "${1##*/}" >>"${DEBUGLOG}" [[ -n "${BASHBOTDEBUG}" && -z "${3}" ]] && log_debug "getJson (wget) URL=${1##*/}"
# shellcheck disable=SC2086 # 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 - "$1"
} }
# usage: sendJson "chat" "JSON" "URL" # curl variant for sendJson
sendJson(){ # usage: "JSON" "URL"
local chat=""; sendJson_do(){
[ -n "${1}" ] && chat='"chat_id":'"${1}"','
[ -n "${BASHBOTDEBUG}" ] &&\
printf "%s: sendJson (wget) CHAT=%s JSON=%s URL=%s\n" "$(date)" "${1}" "${2:0:100}" "${3##*/}" >>"${UPDATELOG}"
# shellcheck disable=SC2086 # shellcheck disable=SC2086
res="$(wget --no-check-certificate -t 2 -T "${TIMEOUT}" ${BASHBOT_WGET_ARGS} -qO - --post-data='{'"${chat} $(iconv -f utf-8 -t utf-8 -c <<<$2)"'}' \ wget --no-check-certificate -t 2 -T "${TIMEOUT}" ${BASHBOT_WGET_ARGS} -qO - --post-data="${1}" \
--header='Content-Type:application/json' "${3}" | "${JSONSHFILE}" -b -n 2>/dev/null )" --header='Content-Type:application/json' "${2}" | "${JSONSHFILE}" -b -n 2>/dev/null
sendJsonResult "${res}" "sendJson (wget)" "$@"
[ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "send" "${@}" &
} }
sendUpload() { sendUpload() {
log_error "Sorry, wget does not support file upload" log_error "Sorry, wget does not support file upload"
BOTSENT[OK]="false" BOTSENT[OK]="false"
[ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "upload" "$@" & [ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "upload" "$@" &
} }
else
# ups, no curl AND no wget
if [ -n "${BASHBOT_WGET}" ]; then
echo -e "${RED}Error: You set BASHBOT_WGET but no wget found!${NC}"
else
echo -e "${RED}Error: curl and wget not found, install curl!${NC}"
fi
exit 8
fi
fi fi
# retry sendJson # retry sendJson
@ -514,7 +561,7 @@ sendJsonRetry(){
sendJsonResult(){ sendJsonResult(){
local offset=0 local offset=0
BOTSENT=( ) BOTSENT=( )
[ -n "${BASHBOTDEBUG}" ] && printf "\n%s: New Result ==========\n%s\n" "$(date)" "$1" >>"${LOGDIR}/MESSAGE.log" [ -n "${BASHBOTDEBUG}" ] && log_message "New Result ==========\n$1"
BOTSENT[OK]="$(JsonGetLine '"ok"' <<< "${1}")" BOTSENT[OK]="$(JsonGetLine '"ok"' <<< "${1}")"
if [ "${BOTSENT[OK]}" = "true" ]; then if [ "${BOTSENT[OK]}" = "true" ]; then
BOTSENT[ID]="$(JsonGetValue '"result","message_id"' <<< "${1}")" BOTSENT[ID]="$(JsonGetValue '"result","message_id"' <<< "${1}")"
@ -522,9 +569,10 @@ sendJsonResult(){
# hot path everything OK! # hot path everything OK!
else else
# oops something went wrong! # oops something went wrong!
if [ "${res}" != "" ]; then if [ "${1}" != "" ]; then
BOTSENT[ERROR]="$(JsonGetValue '"error_code"' <<< "${1}")" BOTSENT[ERROR]="$(JsonGetValue '"error_code"' <<< "${1}")"
BOTSENT[DESCRIPTION]="$(JsonGetString '"description"' <<< "${1}")" BOTSENT[DESCRIPTION]="$(JsonGetString '"description"' <<< "${1}")"
grep -qs -F '"parameters","retry_after"' <<< "${1}" &&\
BOTSENT[RETRY]="$(JsonGetValue '"parameters","retry_after"' <<< "${1}")" BOTSENT[RETRY]="$(JsonGetValue '"parameters","retry_after"' <<< "${1}")"
else else
BOTSENT[OK]="false" BOTSENT[OK]="false"
@ -593,9 +641,15 @@ title2Json(){
printf '%s\n' "${title}${caption}${desc}${markup}${keyboard}" printf '%s\n' "${title}${caption}${desc}${markup}${keyboard}"
} }
# get bot name # get bot name and id from telegram
getBotName() { getBotName() {
getJson "$ME_URL" | "${JSONSHFILE}" -b -n 2>/dev/null | JsonGetString '"result","username"' declare -A BOTARRAY
Json2Array 'BOTARRAY' <<<"$(getJson "$ME_URL" | "${JSONSHFILE}" -b -n 2>/dev/null)"
[ -z "${BOTARRAY["result","username"]}" ] && return 1
# save botname and id
setConfigKey "botname" "${BOTARRAY["result","username"]}"
setConfigKey "botid" "${BOTARRAY["result","id"]}"
echo "${BOTARRAY["result","username"]}"
} }
# pure bash implementation, done by KayM (@gnadelwartz) # pure bash implementation, done by KayM (@gnadelwartz)
@ -626,7 +680,7 @@ JsonGetValue() {
# processing of updates starts here # processing of updates starts here
process_updates() { process_updates() {
local max num debug="$1" local max num debug="$1"
max="$(sed <<< "${UPDATE}" '/\["result",[0-9]*\]/!d' | tail -1 | sed 's/\["result",//g;s/\].*//g')" max="$(grep -F ',"update_id"]' <<< "${UPDATE}" | tail -1 | cut -d , -f 2 )"
Json2Array 'UPD' <<<"${UPDATE}" Json2Array 'UPD' <<<"${UPDATE}"
for ((num=0; num<=max; num++)); do for ((num=0; num<=max; num++)); do
process_client "$num" "${debug}" process_client "$num" "${debug}"
@ -637,7 +691,7 @@ process_client() {
local num="$1" debug="$2" local num="$1" debug="$2"
pre_process_message "${num}" pre_process_message "${num}"
# log message on debug # log message on debug
[[ -n "${debug}" ]] && printf "\n%s: New Message ==========\n%s\n" "$(date)" "$UPDATE" >>"${LOGDIR}/MESSAGE.log" [[ -n "${debug}" ]] && log_message "New Message ==========\n$(grep -F '["result",'"${num}" <<<"${UPDATE}")"
# check for users / groups to ignore # check for users / groups to ignore
jssh_updateArray_async "BASHBOTBLOCKED" "${BLOCKEDFILE}" jssh_updateArray_async "BASHBOTBLOCKED" "${BLOCKEDFILE}"
@ -802,7 +856,7 @@ pre_process_message(){
local num="${1}" local num="${1}"
# unset everything to not have old values # unset everything to not have old values
CMD=( ); iQUERY=( ); MESSAGE=(); CHAT=(); USER=(); CONTACT=(); LOCATION=(); unset CAPTION CMD=( ); iQUERY=( ); MESSAGE=(); CHAT=(); USER=(); CONTACT=(); LOCATION=(); unset CAPTION
REPLYTO=( ); FORWARD=( ); URLS=(); VENUE=( ); SERVICE=( ); NEWMEMBER=( ); LEFTMEMBER=( ); PINNED=( ) REPLYTO=( ); FORWARD=( ); URLS=(); VENUE=( ); SERVICE=( ); NEWMEMBER=( ); LEFTMEMBER=( ); PINNED=( ); MIGRATE=( )
iQUERY[ID]="${UPD["result",${num},"inline_query","id"]}" iQUERY[ID]="${UPD["result",${num},"inline_query","id"]}"
CHAT[ID]="${UPD["result",${num},"message","chat","id"]}" CHAT[ID]="${UPD["result",${num},"message","chat","id"]}"
USER[ID]="${UPD["result",${num},"message","from","id"]}" USER[ID]="${UPD["result",${num},"message","from","id"]}"
@ -846,7 +900,7 @@ process_message() {
[ -z "${USER[USERNAME]}" ] && USER[USERNAME]="${USER[FIRST_NAME]} ${USER[LAST_NAME]}" [ -z "${USER[USERNAME]}" ] && USER[USERNAME]="${USER[FIRST_NAME]} ${USER[LAST_NAME]}"
# in reply to message from # in reply to message from
if grep -qs -e '\["result",'"${num}"',"message","reply_to_message"' <<<"${UPDATE}"; then if [ -n "${UPD["result",${num},"message","reply_to_message","from","id"]}" ]; then
REPLYTO[UID]="${UPD["result",${num},"message","reply_to_message","from","id"]}" REPLYTO[UID]="${UPD["result",${num},"message","reply_to_message","from","id"]}"
REPLYTO[0]="$(JsonDecode "${UPD["result",${num},"message","reply_to_message","text"]}")" REPLYTO[0]="$(JsonDecode "${UPD["result",${num},"message","reply_to_message","text"]}")"
REPLYTO[ID]="${UPD["result",${num},"message","reply_to_message","message_id"]}" REPLYTO[ID]="${UPD["result",${num},"message","reply_to_message","message_id"]}"
@ -856,7 +910,7 @@ process_message() {
fi fi
# forwarded message from # forwarded message from
if grep -qs -e '\["result",'"${num}"',"message","forward_from"' <<<"${UPDATE}"; then if [ -n "${UPD["result",${num},"message","forward_from","id"]}" ]; then
FORWARD[UID]="${UPD["result",${num},"message","forward_from","id"]}" FORWARD[UID]="${UPD["result",${num},"message","forward_from","id"]}"
FORWARD[ID]="${MESSAGE[ID]}" # same as message ID FORWARD[ID]="${MESSAGE[ID]}" # same as message ID
FORWARD[FIRST_NAME]="$(JsonDecode "${UPD["result",${num},"message","forward_from","first_name"]}")" FORWARD[FIRST_NAME]="$(JsonDecode "${UPD["result",${num},"message","forward_from","first_name"]}")"
@ -864,7 +918,7 @@ process_message() {
FORWARD[USERNAME]="$(JsonDecode "${UPD["result",${num},"message","forward_from","username"]}")" FORWARD[USERNAME]="$(JsonDecode "${UPD["result",${num},"message","forward_from","username"]}")"
fi fi
# get file URL from telegram # get file URL from telegram, check for any of them!
if grep -qs -e '\["result",'"${num}"',"message","[avpsd].*,"file_id"\]' <<<"${UPDATE}"; then if grep -qs -e '\["result",'"${num}"',"message","[avpsd].*,"file_id"\]' <<<"${UPDATE}"; then
URLS[AUDIO]="$(get_file "${UPD["result",${num},"message","audio","file_id"]}")" URLS[AUDIO]="$(get_file "${UPD["result",${num},"message","audio","file_id"]}")"
URLS[DOCUMENT]="$(get_file "${UPD["result",${num},"message","document","file_id"]}")" URLS[DOCUMENT]="$(get_file "${UPD["result",${num},"message","document","file_id"]}")"
@ -873,17 +927,17 @@ process_message() {
URLS[VIDEO]="$(get_file "${UPD["result",${num},"message","video","file_id"]}")" URLS[VIDEO]="$(get_file "${UPD["result",${num},"message","video","file_id"]}")"
URLS[VOICE]="$(get_file "${UPD["result",${num},"message","voice","file_id"]}")" URLS[VOICE]="$(get_file "${UPD["result",${num},"message","voice","file_id"]}")"
fi fi
# Contact # Contact, must have phone_number
if grep -qs -e '\["result",'"${num}"',"message","contact"' <<<"${UPDATE}"; then if [ -n "${UPD["result",${num},"message","contact","phone_number"]}" ]; then
CONTACT[FIRST_NAME]="$(JsonDecode "${UPD["result",${num},"message","contact","first_name"]}")"
CONTACT[USER_ID]="$(JsonDecode "${UPD["result",${num},"message","contact","user_id"]}")" CONTACT[USER_ID]="$(JsonDecode "${UPD["result",${num},"message","contact","user_id"]}")"
CONTACT[FIRST_NAME]="$(JsonDecode "${UPD["result",${num},"message","contact","first_name"]}")"
CONTACT[LAST_NAME]="$(JsonDecode "${UPD["result",${num},"message","contact","last_name"]}")" CONTACT[LAST_NAME]="$(JsonDecode "${UPD["result",${num},"message","contact","last_name"]}")"
CONTACT[NUMBER]="${UPD["result",${num},"message","contact","phone_number"]}" CONTACT[NUMBER]="${UPD["result",${num},"message","contact","phone_number"]}"
CONTACT[VCARD]="$(JsonGetString '"result",'"${num}"',"message","contact","vcard"' <<<"${UPDATE}")" CONTACT[VCARD]="$(JsonGetString '"result",'"${num}"',"message","contact","vcard"' <<<"${UPDATE}")"
fi fi
# vunue # venue, must have a position
if grep -qs -e '\["result",'"${num}"',"message","venue"' <<<"${UPDATE}"; then if [ -n "${UPD["result",${num},"message","venue","location","longitude"]}" ]; then
VENUE[TITLE]="$(JsonDecode "${UPD["result",${num},"message","venue","title"]}")" VENUE[TITLE]="$(JsonDecode "${UPD["result",${num},"message","venue","title"]}")"
VENUE[ADDRESS]="$(JsonDecode "${UPD["result",${num},"message","venue","address"]}")" VENUE[ADDRESS]="$(JsonDecode "${UPD["result",${num},"message","venue","address"]}")"
VENUE[LONGITUDE]="${UPD["result",${num},"message","venue","location","longitude"]}" VENUE[LONGITUDE]="${UPD["result",${num},"message","venue","location","longitude"]}"
@ -898,8 +952,10 @@ process_message() {
LOCATION[LONGITUDE]="${UPD["result",${num},"message","location","longitude"]}" LOCATION[LONGITUDE]="${UPD["result",${num},"message","location","longitude"]}"
LOCATION[LATITUDE]="${UPD["result",${num},"message","location","latitude"]}" LOCATION[LATITUDE]="${UPD["result",${num},"message","location","latitude"]}"
# service messages # service messages, group or channel only!
if grep -qs -e '\["result",'"${num}"',"message","new_chat_member' <<<"${UPDATE}"; then if [[ "${CHAT[ID]}" == "-"* ]] ; then
# new chat member
if [ -n "${UPD["result",${num},"message","new_chat_member","id"]}" ]; then
SERVICE[NEWMEMBER]="${UPD["result",${num},"message","new_chat_member","id"]}" SERVICE[NEWMEMBER]="${UPD["result",${num},"message","new_chat_member","id"]}"
NEWMEMBER[ID]="${SERVICE[NEWMEMBER]}" NEWMEMBER[ID]="${SERVICE[NEWMEMBER]}"
NEWMEMBER[FIRST_NAME]="$(JsonDecode "${UPD["result",${num},"message","new_chat_member","first_name"]}")" NEWMEMBER[FIRST_NAME]="$(JsonDecode "${UPD["result",${num},"message","new_chat_member","first_name"]}")"
@ -909,7 +965,8 @@ process_message() {
[ -z "${MESSAGE[0]}" ] &&\ [ -z "${MESSAGE[0]}" ] &&\
MESSAGE[0]="/_new_chat_member ${NEWMEMBER[ID]} ${NEWMEMBER[USERNAME]:=${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]}}" MESSAGE[0]="/_new_chat_member ${NEWMEMBER[ID]} ${NEWMEMBER[USERNAME]:=${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]}}"
fi fi
if grep -qs -e '\["result",'"${num}"',"message","left_chat_member' <<<"${UPDATE}"; then # left chat member
if [ -n "${UPD["result",${num},"message","left_chat_member","id"]}" ]; then
SERVICE[LEFTMEMBER]="${UPD["result",${num},"message","left_chat_member","id"]}" SERVICE[LEFTMEMBER]="${UPD["result",${num},"message","left_chat_member","id"]}"
LEFTMEMBER[ID]="${SERVICE[LEFTMEBER]}" LEFTMEMBER[ID]="${SERVICE[LEFTMEBER]}"
LEFTMEMBER[FIRST_NAME]="$(JsonDecode "${UPD["result",${num},"message","left_chat_member","first_name"]}")" LEFTMEMBER[FIRST_NAME]="$(JsonDecode "${UPD["result",${num},"message","left_chat_member","first_name"]}")"
@ -919,6 +976,7 @@ process_message() {
[ -z "${MESSAGE[0]}" ] &&\ [ -z "${MESSAGE[0]}" ] &&\
MESSAGE[0]="/_left_chat_member ${LEFTMEMBER[ID]} ${LEFTMEMBER[USERNAME]:=${LEFTMEMBER[FIRST_NAME]} ${LEFTMEMBER[LAST_NAME]}}" MESSAGE[0]="/_left_chat_member ${LEFTMEMBER[ID]} ${LEFTMEMBER[USERNAME]:=${LEFTMEMBER[FIRST_NAME]} ${LEFTMEMBER[LAST_NAME]}}"
fi fi
# chat title / photo, check for any of them!
if grep -qs -e '\["result",'"${num}"',"message","new_chat_[tp]' <<<"${UPDATE}"; then if grep -qs -e '\["result",'"${num}"',"message","new_chat_[tp]' <<<"${UPDATE}"; then
SERVICE[NEWTITLE]="$(JsonDecode "${UPD["result",${num},"message","new_chat_title"]}")" SERVICE[NEWTITLE]="$(JsonDecode "${UPD["result",${num},"message","new_chat_title"]}")"
[ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[NEWTITLE]}" ] &&\ [ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[NEWTITLE]}" ] &&\
@ -927,15 +985,25 @@ process_message() {
[ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[NEWPHOTO]}" ] &&\ [ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[NEWPHOTO]}" ] &&\
MESSAGE[0]="/_new_chat_photo ${USER[ID]} ${SERVICE[NEWPHOTO]}" MESSAGE[0]="/_new_chat_photo ${USER[ID]} ${SERVICE[NEWPHOTO]}"
fi fi
if grep -qs -e '\["result",'"${num}"',"message","pinned_message' <<<"${UPDATE}"; then # pinned message
SERVICE[PINNED]="$(JsonDecode "${UPD["result",${num},"message","pinned_message","message_id"]}")" if [ -n "${UPD["result",${num},"message","pinned_message","message_id"]}" ]; then
SERVICE[PINNED]="${UPD["result",${num},"message","pinned_message","message_id"]}"
PINNED[ID]="${SERVICE[PINNED]}" PINNED[ID]="${SERVICE[PINNED]}"
PINNED[MESSAGE]="$(JsonDecode "${UPD["result",${num},"message","pinned_message","text"]}")" PINNED[MESSAGE]="$(JsonDecode "${UPD["result",${num},"message","pinned_message","text"]}")"
[ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[PINNED]}" ] &&\ [ -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 fi
# migrate to super group
if [ -n "${UPD["result",${num},"message","migrate_to_chat_id"]}" ]; then
MIGRATE[TO]="${UPD["result",${num},"message","migrate_to_chat_id"]}"
MIGRATE[FROM]="${UPD["result",${num},"message","migrate_from_chat_id"]}"
SERVICE[MIGRATE]="${MIGRATE[FROM]} ${MIGRATE[TO]}"
[ -z "${MESSAGE[0]}" ] &&\
MESSAGE[0]="/_migrate_group ${SERVICE[MIGRATE]}"
fi
# set SERVICE to yes if a service message was received # set SERVICE to yes if a service message was received
[[ "${SERVICE[*]}" =~ ^[[:blank:]]*$ ]] || SERVICE[0]="yes" [[ "${SERVICE[*]}" =~ ^[[:blank:]]*$ ]] || SERVICE[0]="yes"
fi
# split message in command and args # split message in command and args
[[ "${MESSAGE[0]}" == "/"* ]] && read -r CMD <<<"${MESSAGE[0]}" && CMD[0]="${CMD[0]%%@*}" [[ "${MESSAGE[0]}" == "/"* ]] && read -r CMD <<<"${MESSAGE[0]}" && CMD[0]="${CMD[0]%%@*}"
@ -946,6 +1014,7 @@ process_message() {
######################### #########################
# main get updates loop, should never terminate # main get updates loop, should never terminate
declare -A BASHBOTBLOCKED declare -A BASHBOTBLOCKED
export BASHBOT_UPDATELOG="${BASHBOT_UPDATELOG-nolog}" # allow to be ""
start_bot() { start_bot() {
local DEBUGMSG ADMIN OFFSET=0 local DEBUGMSG ADMIN OFFSET=0
# adaptive sleep defaults # adaptive sleep defaults
@ -953,12 +1022,12 @@ start_bot() {
local stepsleep="${BASHBOT_SLEEP_STEP:-100}" local stepsleep="${BASHBOT_SLEEP_STEP:-100}"
local maxsleep="${BASHBOT_SLEEP:-5000}" local maxsleep="${BASHBOT_SLEEP:-5000}"
# startup message # startup message
DEBUGMSG="$(date): Start BASHBOT updates in Mode \"${1:-normal}\" ==========" DEBUGMSG="Start BASHBOT updates in Mode \"${1:-normal}\" =========="
printf "%s\n" "${DEBUGMSG}" >>"${UPDATELOG}" log_update "${DEBUGMSG}"
# redirect to Debug.log # redirect to Debug.log
[[ "${1}" == *"debug" ]] && exec &>>"${DEBUGLOG}" [[ "${1}" == *"debug" ]] && exec &>>"${DEBUGLOG}"
printf "%s\n" "${DEBUGMSG}"; DEBUGMSG="${1}" log_debug "${DEBUGMSG}"; DEBUGMSG="${1}"
[[ "${DEBUGMSG}" == "xdebug"* ]] && set -x [[ "${DEBUGMSG}" == "xdebug"* ]] && set -x && unset BASHBOT_UPDATELOG
# cleaup old pipes and empty logfiles # cleaup old pipes and empty logfiles
find "${DATADIR}" -type p -delete find "${DATADIR}" -type p -delete
find "${DATADIR}" -size 0 -name "*.log" -delete find "${DATADIR}" -size 0 -name "*.log" -delete
@ -994,7 +1063,7 @@ start_bot() {
# adaptive sleep in ms rounded to next 0.1 s # adaptive sleep in ms rounded to next 0.1 s
sleep "$(_round_float "${nextsleep}e-3" "1")" sleep "$(_round_float "${nextsleep}e-3" "1")"
# get next update # get next update
UPDATE="$(getJson "${UPD_URL}${OFFSET}" "nolog" 2>/dev/null | "${JSONSHFILE}" -b -n 2>/dev/null | iconv -f utf-8 -t utf-8 -c)" UPDATE="$(getJson "${UPD_URL}${OFFSET}" "${BASHBOT_UPDATELOG}" 2>/dev/null | "${JSONSHFILE}" -b -n 2>/dev/null | iconv -f utf-8 -t utf-8 -c)"
# did we get an response? # did we get an response?
if [ -n "${UPDATE}" ]; then if [ -n "${UPDATE}" ]; then
# we got something, do processing # we got something, do processing
@ -1014,8 +1083,15 @@ start_bot() {
else else
# oops, something bad happened, wait maxsleep*10 # oops, something bad happened, wait maxsleep*10
(( nextsleep=nextsleep*2 , nextsleep= nextsleep>maxsleep*10 ?maxsleep*10:nextsleep )) (( nextsleep=nextsleep*2 , nextsleep= nextsleep>maxsleep*10 ?maxsleep*10:nextsleep ))
[ "${OFFSET}" = "-999" ] &&\ # second time, report problem
if [ "${OFFSET}" = "-999" ]; then
log_error "Repeated timeout/broken/no connection on telegram update, sleep $(_round_float "${nextsleep}e-3")s" log_error "Repeated timeout/broken/no connection on telegram update, sleep $(_round_float "${nextsleep}e-3")s"
# try to recover
if _is_function bashbotBlockRecover && [ -z "$(getJson "${ME_URL}")" ]; then
log_error "Try to recover, calling bashbotBlockRecover ..."
bashbotBlockRecover >>"${ERRORLOG}"
fi
fi
OFFSET="-999" OFFSET="-999"
fi fi
done done
@ -1072,6 +1148,15 @@ bot_init() {
find . -name '*.jssh*' -exec chmod u+w \{\} + find . -name '*.jssh*' -exec chmod u+w \{\} +
echo "Done." echo "Done."
fi fi
# ask to check bottoken online
if [ -z "$(getConfigKey "botid")" ]; then
echo -e "Seems to be your first init. Should I verify your bot token online? (y/N) N\b\c"
read -r ANSWER
if [[ "${ANSWER}" =~ ^[Yy] ]]; then
echo -e "${GREEN}Contacting telegram to verify your bot token ...${NC}"
$0 botname
fi
fi
# check if botconf if seems valid # check if botconf if seems valid
echo -e "${GREEN}This is your bot config:${NC}" echo -e "${GREEN}This is your bot config:${NC}"
sed 's/^/\t/' "${BOTCONFIG}.jssh" | grep -vF '["bot_config_key"]' sed 's/^/\t/' "${BOTCONFIG}.jssh" | grep -vF '["bot_config_key"]'
@ -1094,6 +1179,7 @@ if ! _is_function send_message ; then
exit 1 exit 1
fi fi
# get location of JSON.sh, download if not exist
JSONSHFILE="${BASHBOT_JSONSH:-${SCRIPTDIR}/JSON.sh/JSON.sh}" JSONSHFILE="${BASHBOT_JSONSH:-${SCRIPTDIR}/JSON.sh/JSON.sh}"
[[ "${JSONSHFILE}" != *"/JSON.sh" ]] && echo -e "${RED}ERROR: \"${JSONSHFILE}\" ends not with \"JSONS.sh\".${NC}" && exit 3 [[ "${JSONSHFILE}" != *"/JSON.sh" ]] && echo -e "${RED}ERROR: \"${JSONSHFILE}\" ends not with \"JSONS.sh\".${NC}" && exit 3
@ -1105,12 +1191,19 @@ if [ ! -f "${JSONSHFILE}" ]; then
chmod +x "${JSONSHFILE}" chmod +x "${JSONSHFILE}"
fi fi
# check if JSON.awk exist and has x flag
JSONAWKFILE="${JSONSHFILE%.sh}.awk"
if [ -x "${JSONAWKFILE}" ] && _exists awk ; then
JSONSHFILE="JsonAwk"; JsonAwk() { "${JSONAWKFILE}" -v "BRIEF=8" -v "STRICT=0" -; }
fi
# source the script with source as param to use functions in other scripts # source the script with source as param to use functions in other scripts
# do not execute if read from other scripts # do not execute if read from other scripts
if [ -z "${SOURCE}" ]; then if [ -z "${SOURCE}" ]; then
############## ##############
# internal options only for use from bashbot and developers # internal options only for use from bashbot and developers
# shellcheck disable=SC2221,SC2222
case "${1}" in case "${1}" in
# update botname when starting only # update botname when starting only
"botname"|"start"*) "botname"|"start"*)
@ -1159,8 +1252,8 @@ if [ -z "${SOURCE}" ]; then
exit exit
;; ;;
# print usage stats # print usage stats
"count") echo -e "${RED}Command ${GREY}count${RED} is deprecated, use ${GREY}stats{$RED}instead.${NC}";&
"stats") "stats")
echo -e "${ORANGE}stats deprecated, see bin/bashbot_stats --help${NC}"
ME="$(getConfigKey "botname")" ME="$(getConfigKey "botname")"
declare -A STATS declare -A STATS
jssh_readDB_async "STATS" "${COUNTFILE}" jssh_readDB_async "STATS" "${COUNTFILE}"
@ -1196,23 +1289,8 @@ if [ -z "${SOURCE}" ]; then
;; ;;
# send message to all users # send message to all users
'broadcast') 'broadcast')
ME="$(getConfigKey "botname")" echo -e "${ORANGE}Broadcast is a separate command now, see ${BASHBOT_HOME:-.}/bin/send_broadcast.sh --help${NC}"
declare -A SENDALL "${BASHBOT_HOME:-.}"/bin/send_broadcast.sh --help
shift
jssh_readDB_async "SENDALL" "${COUNTFILE}"
echo -e "Sending broadcast message to all users of ${ME} \c"
for MSG in ${!SENDALL[*]}
do
[[ ! "${MSG}" =~ ^[0-9-]*$ ]] && continue
(( USERS++ ))
if [ -n "$*" ]; then
send_message "${MSG}" "$*"
echo -e ".\c"
sleep 0.1
fi
done
echo -e "\nMessage \"$*\" sent to ${USERS} users."
debug_checks "end $1" "$@"
exit exit
;; ;;
# does what it says # does what it says
@ -1249,7 +1327,6 @@ if [ -z "${SOURCE}" ]; then
debug_checks "end start" "$@" debug_checks "end start" "$@"
;; ;;
# does what it says # does what it says
"kill") echo -e "${RED}Command ${GREY}kill${RED} is deprecated, use ${GREY}stop{$RED}instead.${NC}";&
"stop") "stop")
ME="$(getConfigKey "botname")" ME="$(getConfigKey "botname")"
SESSION="${ME:-_bot}-startbot" SESSION="${ME:-_bot}-startbot"

64
bin/bashbot_env.inc.sh Normal file
View File

@ -0,0 +1,64 @@
#!/bin/bash
#===============================================================================
#
# FILE: bashbot_env.inc.sh
#
# USAGE: source bashbot_env.inc.sh [debug]
#
# DESCRIPTION: set bashbot environment for all scripts in this directory
#
# OPTIONS: $1 - will be forwarded ro bashbot, e.g. debug
#
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 18.12.2020 12:27
#
#### $$VERSION$$ v1.20-0-g2ab00a2
#===============================================================================
############
# set where your bashbot lives
export BASHBOT_HOME BASHBOT_ETC BASHBOT_VAR FILE_REGEX
# default: one dir up
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"
BASHBOT_VAR="${BASHBOT_HOME}"
BASHBOT_ETC="${BASHBOT_HOME}"
#####
# if files are not readable, eviroment is wrong or bashbot is not initialized
# source bashbot
if [ ! -r "${BASHBOT_HOME}/bashbot.sh" ]; then
echo "Bashbot.sh not found in \"${BASHBOT_HOME}\""
exit 4
else
# shellcheck disable=SC1090
source "${BASHBOT_HOME}/bashbot.sh" source "$1"
fi
# overwrite bot FILE regex to BASHBOT_ETC
# change this to the location you want to allow file uploads from
FILE_REGEX="${BASHBOT_ETC%/bin*}/.*"
# check for botconfig.jssh readable
if [ ! -r "${BASHBOT_ETC}/botconfig.jssh" ]; then
echo "Bashbot config file in \"${BASHBOT_ETC}\" does not exist or is not readable."
exit 3
fi
# check for count.jssh readable
if [ ! -r "${BASHBOT_VAR}/count.jssh" ]; then
echo "Bashbot count file in \"${BASHBOT_VAR}\" does not exist or is not readable. Did you run bashbot init?"
exit 3
fi
# get and check ADMIN and NAME
BOT_ADMIN="$(getConfigKey "botadmin")"
BOT_NAME="$(getConfigKey "botname")"
[[ -z "${BOT_ADMIN}" || "${BOT_ADMIN}" == "?" ]] && echo -e "${ORANGE}Warning: Botadmin not set, did you forget to sent command${NC} /start"
[[ -z "${BOT_NAME}" ]] && echo -e "${ORANGE}Warning: Botname not set, did you ever run bashbot?"

74
bin/bashbot_stats.sh Executable file
View File

@ -0,0 +1,74 @@
#!/bin/bash
#===============================================================================
#
# FILE: bin/bashbot_stats.sh
#
# USAGE: bashbot_stats.sh [-h|--help] [debug]
#
# DESCRIPTION: output bashbot user stats
#
# OPTIONS: -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: 23.12.2020 20:34
#
#### $$VERSION$$ v1.20-0-g2ab00a2
#===============================================================================
####
# parse args
case "$1" in
"-h"*)
echo "usage: send_message [-h|--help] [debug]"
exit 1
;;
'--h'*)
sed -n '3,/###/p' <"$0"
exit 1
;;
esac
# set bashbot environment
# shellcheck disable=SC1090
source "${0%/*}/bashbot_env.inc.sh" "$1"
####
# ready, do stuff here -----
echo -e "${GREEN}Hi I'm ${BOT_NAME}.${NC}"
declare -A STATS
jssh_readDB_async "STATS" "${COUNTFILE}"
for MSG in ${!STATS[*]}
do
[[ ! "${MSG}" =~ ^[0-9-]*$ ]] && continue
(( USERS++ ))
done
for MSG in ${STATS[*]}
do
(( MESSAGES+=MSG ))
done
if [ "${USERS}" != "" ]; then
echo -e "${GREY}A total of ${NC}${MESSAGES}${GREY} messages from ${NC}${USERS}${GREY} users are processed.${NC}"
else
echo -e "${ORANGE}No one used your bot so far ...${NC}"
fi
jssh_readDB_async "STATS" "${BLOCKEDFILE}"
for MSG in ${!STATS[*]}
do
[[ ! "${MSG}" =~ ^[0-9-]*$ ]] && continue
(( BLOCKS++ ))
done
if [ "${BLOCKS}" != "" ]; then
echo -e "${ORANGE}${BLOCKS} user(s) are blocked:${NC}${GREY}"
sort -r "${BLOCKEDFILE}.jssh"
echo -e "${NC}\c"
else
echo -e "${GREEN}No user is blocked currently ...${NC}"
fi
# show user created bot stats
_exec_if_function my_bashbot_stats "$@"

113
bin/send_broadcast.sh Executable file
View File

@ -0,0 +1,113 @@
#!/bin/bash
#===============================================================================
#
# FILE: bin/broadcast_message.sh
#
# USAGE: broadcast_message.sh [-h|--help] [--doit] [--groups|--both] [format] "message ...." [debug]
#
# DESCRIPTION: send a message to all users the bot have seen (listet in count.jssh)
#
# OPTIONS: --doit - broadcast is dangerous, simulate run without --doit
# --groups - send to groups instead of users
# --both - send to users and groups
#
# format - normal, markdown, html (optional)
# message - message to send in specified format
# if no format is givern send_message() format is used
#
# -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: 16.12.2020 16:14
#
#### $$VERSION$$ v1.20-0-g2ab00a2
#===============================================================================
####
# broadcast is dangerous, without --doit we do a dry run ...
if [ "$1" = "--doit" ]; then
DOIT="yes"
shift
fi
####
# send to users by default, --group sends groups, --both to both
SENDTO="users"
if [ "$1" = "--both" ]; then
GROUPSALSO=" and groups"
shift
elif [ "$1" = "--groups" ]; then
SENDTO="groups"
GROUPSALSO=" only"
shift
fi
####
# parse args -----------------
SEND="send_message"
case "$1" in
"nor*"|"tex*")
SEND="send_normal_message"
shift
;;
"mark"*)
SEND="send_markdownv2_message"
shift
;;
"html")
SEND="send_html_message"
shift
;;
'')
echo "missing missing arguments"
;&
"-h"*)
echo 'usage: send_message [-h|--help] [--groups|--both] [format] "message ...." [debug]'
exit 1
;;
'--h'*)
sed -n '3,/###/p' <"$0"
exit 1
;;
esac
# set bashbot environment
# shellcheck disable=SC1090
source "${0%/*}/bashbot_env.inc.sh" "$2" # $3 debug
# read in users
declare -A SENDALL
jssh_readDB_async "SENDALL" "${COUNTFILE}"
if [ -z "${SENDALL[*]}" ]; then
echo -e "${ORANGE}Countfile not found or empty,${NC} "
fi
# loop over users
echo -e "${GREEN}Sending broadcast message to all users of ${BOT_NAME}${NC}${GREY}\c"
{ # dry run
[ -z "${DOIT}" ] && echo -e "${NC}\n${ORANGE}DRY RUN! use --doit as first argument to execute broadcast...${NC}"
for USER in ${!SENDALL[*]}
do
# send to users, groups or both ...
[[ -z "${GROUPSALSO}" && "${USER}" == *"-"* ]] && continue
[[ "${SENDTO}" != "users" && "${USER}" != *"-"* ]] && continue
# ignore everything not a user or group
[[ ! "${USER}" =~ ^[0-9-]*$ ]] && continue
(( COUNT++ ))
if [ -z "${DOIT}" ]; then
echo "${SEND}" "${USER}" "$1" "$2"
else
"${SEND}" "${USER}" "$1" "$2"
echo -e ".\c" 1>&2
sleep 0.1
fi
done
echo -e "${NC}\nMessage \"$1\" sent to ${COUNT} ${SENDTO}${GROUPSALSO}."
} | more

76
bin/send_edit_message.sh Executable file
View File

@ -0,0 +1,76 @@
#!/bin/bash
#===============================================================================
#
# FILE: bin/send_message.sh
#
# USAGE: send_edit_message.sh [-h|--help] [format] "CHAT[ID]" "MESSAGE[ID]" "message ...." [debug]
#
# DESCRIPTION: replace a message in the given user/group
#
# OPTIONS: format - normal, markdown, html (optional)
# CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself
# MESSAGE[ID] - message to replace
# message - message to send in specified format
# if no format is given send_normal_message() format is used
#
# -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: 23.12.2020 16:52
#
#### $$VERSION$$ v1.20-0-g2ab00a2
#===============================================================================
####
# parse args
SEND="edit_normal_message"
case "$1" in
"nor*"|"tex*")
SEND="edit_normal_message"
shift
;;
"mark"*)
SEND="edit_markdownv2_message"
shift
;;
"html")
SEND="edit_html_message"
shift
;;
'')
echo "missing arguments"
;&
"-h"*)
echo 'usage: send_edit_message [-h|--help] [format] "CHAT[ID]" "MESSAGE[ID]" "message ..." [debug]'
exit 1
;;
'--h'*)
sed -n '3,/###/p' <"$0"
exit 1
;;
esac
# set bashbot environment
# shellcheck disable=SC1090
source "${0%/*}/bashbot_env.inc.sh" "$4" # $4 debug
####
####
# ready, do stuff here -----
if [ "$1" == "BOTADMIN" ]; then
CHAT="${BOT_ADMIN}"
else
CHAT="$1"
fi
# send message in selected format
"${SEND}" "${CHAT}" "$2" "$3"
# output send message result
jssh_printDB "BOTSENT" | sort -r

65
bin/send_file.sh Executable file
View File

@ -0,0 +1,65 @@
#!/bin/bash
#===============================================================================
#
# FILE: bin/send_file.sh
#
# USAGE: send_file.sh [-h|--help] "CHAT[ID]" "file" "caption ...." [debug]
#
# DESCRIPTION: send a file to the given user/group
#
# OPTIONS: CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself
# file - file to send, must be an absolute path or relative to pwd
# Note: must not contain .. or . and located below BASHBOT_ETC
# caption - message to send with file
#
# -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: 25.12.2020 20:24
#
#### $$VERSION$$ v1.20-0-g2ab00a2
#===============================================================================
####
# parse args
SEND="upload_file"
case "$1" in
'')
echo "missing arguments"
;&
"-h"*)
echo 'usage: send_file [-h|--help] "CHAT[ID]" "file" "caption ...." [debug]'
exit 1
;;
'--h'*)
sed -n '3,/###/p' <"$0"
exit 1
;;
esac
# set bashbot environment
# shellcheck disable=SC1090
source "${0%/*}/bashbot_env.inc.sh" "$4" # $4 debug
####
# ready, do stuff here -----
if [ "$1" == "BOTADMIN" ]; then
CHAT="${BOT_ADMIN}"
else
CHAT="$1"
fi
FILE="$2"
[[ "$2" != "/"* ]] && FILE="${PWD}/$2"
# send message in selected format
"${SEND}" "${CHAT}" "${FILE}" "$3"
# output send message result
jssh_printDB "BOTSENT" | sort -r

74
bin/send_message.sh Executable file
View File

@ -0,0 +1,74 @@
#!/bin/bash
#===============================================================================
#
# FILE: bin/send_message.sh
#
# 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)
# 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
#
# -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: 16.12.2020 11:34
#
#### $$VERSION$$ v1.20-0-g2ab00a2
#===============================================================================
####
# parse args
SEND="send_message"
case "$1" in
"nor*"|"tex*")
SEND="send_normal_message"
shift
;;
"mark"*)
SEND="send_markdownv2_message"
shift
;;
"html")
SEND="send_html_message"
shift
;;
'')
echo "missing arguments"
;&
"-h"*)
echo 'usage: send_message [-h|--help] [format] "CHAT[ID]" "message ...." [debug]'
exit 1
;;
'--h'*)
sed -n '3,/###/p' <"$0"
exit 1
;;
esac
# set bashbot environment
# shellcheck disable=SC1090
source "${0%/*}/bashbot_env.inc.sh" "$3" # $3 debug
####
# ready, do stuff here -----
if [ "$1" == "BOTADMIN" ]; then
CHAT="${BOT_ADMIN}"
else
CHAT="$1"
fi
# send message in selected format
"${SEND}" "${CHAT}" "$2"
# output send message result
jssh_printDB "BOTSENT" | sort -r

View File

@ -15,7 +15,7 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.1-0-gc0eb399 #### $$VERSION$$ v1.20-0-g2ab00a2
# #
# adjust your language setting here, e.g. when run from other user or cron. # adjust your language setting here, e.g. when run from other user or cron.
@ -38,17 +38,16 @@ It currently can send, receive and forward messages, custom keyboards, photos, a
#----------------------------- #-----------------------------
# this file *MUST* not edited! # this file *MUST* not edited!
# copy "mycommands.sh.dist" to "mycommands.sh" and change the strings there # copy "mycommands.sh.dist" to "mycommands.sh" and change the strings there
bashbot_help='Place your own commands and messages in mycommands.sh bashbot_help='
*Available commands*: *Available commands*:
*• /start*: _Start bot and get this message_. *• /start*: _Start bot and get this message_.
*• /help*: _Get this message_. *• /help*: _Get this message_.
*• /info*: _Get shorter info message about this bot_. *• /info*: _Get shorter info message about this bot_.
*• /question*: _Start interactive chat_. *• /question*: _Start interactive chat (mycommands.dist)_.
*• /cancel*: _Cancel any currently running interactive chats_. *• /cancel*: _Cancel any currently running interactive chat_.
*• /kickme*: _You will be autokicked from the chat_. *• /kickme*: _You will be autokicked from the group_.
*• /leavechat*: _The bot will leave the group with this command _. *• /leavechat*: _The bot will leave the group with this command _.
Written by Drew (@topkecleon), Daniil Gentili (@danogentili) and KayM(@gnadelwartz). Written by Drew (@topkecleon) and KayM (@gnadelwartz).
Get the code in my [GitHub](http://github.com/topkecleon/telegram-bot-bash) Get the code in my [GitHub](http://github.com/topkecleon/telegram-bot-bash)
' '
@ -66,8 +65,9 @@ fi
#---------------------------- #----------------------------
# this file *MUST* not edited! # this file *MUST* not edited!
# copy "mycommands.sh.dist" to "mycommands.sh" and change the values there # copy "mycommands.sh.dist" to "mycommands.sh" and change the values there
# defaults to no inline and nonsense home dir # defaults to no inline, all commands and nonsense home dir
export INLINE="0" export INLINE="0"
export MEONLY="0"
export FILE_REGEX="${BASHBOT_ETC}/.*" export FILE_REGEX="${BASHBOT_ETC}/.*"
@ -87,9 +87,18 @@ if [ -z "${1}" ] || [[ "${1}" == *"debug"* ]];then
# your commands are in mycommands() # your commands are in mycommands()
else else
###################
# if is bashbot is group admin it get commands sent to other bots
# set MEONLY=1 to ignore commands for other bots
if [[ "${MEONLY}" != "0" && "${MESSAGE}" == "/"* && "${MESSAGE%% *}" == *"@"* ]]; then
# here we have a command with @xyz_bot added, check if it's our bot
MYCHECK="${MESSAGE%% *}"
[ "${MYCHECK}" != "${MYCHECK%%@${ME}}" ] && return
fi
################### ###################
# user defined commands must placed in mycommands # user defined commands must placed in mycommands
_exec_if_function mycommands ! _is_function mycommands || mycommands
# run commands if true (0) is returned or if mycommands dose not exist # run commands if true (0) is returned or if mycommands dose not exist
# shellcheck disable=SC2181 # shellcheck disable=SC2181
@ -105,7 +114,10 @@ if [ -z "${1}" ] || [[ "${1}" == *"debug"* ]];then
;; ;;
'/start'*) '/start'*)
send_action "${CHAT[ID]}" "typing" send_action "${CHAT[ID]}" "typing"
user_is_botadmin "${USER[ID]}" && send_markdown_message "${CHAT[ID]}" "You are *BOTADMIN*." MYCOMMANDS="*Note*: No _mycommands.sh_ detected, copy _mycommands.dist_ or _mycommands.clean_."
[ -r "${BASHBOT_ETC:-.}/mycommands.sh" ] && MYCOMMANDS="Place your commands and messages in _mycommands.sh_"
user_is_botadmin "${USER[ID]}" &&\
send_markdownv2_message "${CHAT[ID]}" "You are *BOTADMIN*.\n${MYCOMMANDS}"
if user_is_admin "${CHAT[ID]}" "${USER[ID]}" || user_is_allowed "${USER[ID]}" "start" ; then if user_is_admin "${CHAT[ID]}" "${USER[ID]}" || user_is_allowed "${USER[ID]}" "start" ; then
send_markdown_message "${CHAT[ID]}" "${bashbot_help}" send_markdown_message "${CHAT[ID]}" "${bashbot_help}"
else else

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# this has to run once atfer git clone # this has to run once atfer git clone
# and every time we create new hooks # and every time we create new hooks
#### $$VERSION$$ v1.1-0-gc0eb399 #### $$VERSION$$ v1.20-0-g2ab00a2
# magic to ensure that we're always inside the root of our application, # magic to ensure that we're always inside the root of our application,
# no matter from which directory we'll run script # no matter from which directory we'll run script
@ -18,6 +18,9 @@ mkdir "${TESTENV}"
cp -r ./* "${TESTENV}" cp -r ./* "${TESTENV}"
cd "test" || exit 1 cd "test" || exit 1
# delete possible config
rm -f "${TESTENV}/botconfig.jssh" "${TESTENV}/botacl" 2>/dev/null
#set -e #set -e
fail=0 fail=0
tests=0 tests=0

View File

@ -3,7 +3,7 @@
# #
# works together with git pre-push.sh and ADD all changed files since last push # works together with git pre-push.sh and ADD all changed files since last push
#### $$VERSION$$ v1.1-0-gc0eb399 #### $$VERSION$$ v1.20-0-g2ab00a2
# magic to ensure that we're always inside the root of our application, # magic to ensure that we're always inside the root of our application,
# no matter from which directory we'll run script # no matter from which directory we'll run script
@ -14,21 +14,24 @@ else
echo "Sorry, no git repository $(pwd)" && exit 1 echo "Sorry, no git repository $(pwd)" && exit 1
fi fi
[ ! -f .git/.lastpush ] && echo "No push or hooks not installed, use \"git add\" instead ... Abort" && exit [ ! -f .git/.lastcommit ] && echo "No previous commit or hooks not installed, use \"git add\" instead ... Abort" && exit
FILES="$(find ./* -newer .git/.lastpush)" set +f
[ "${FILES}" = "" ] && echo "Noting changed since last push ... Abort" && exit FILES="$(find ./* -newer .git/.lastpush| grep -v -e 'DIST\/' -e 'STANDALONE\/' -e 'JSON.sh')"
set -f
# FILES="$(find ./* -newer .git/.lastpush)"
[ "${FILES}" = "" ] && echo "Noting changed since last commit ..." && exit
# run pre_commit on files # run pre_commit on files
dev/hooks/pre-commit.sh dev/hooks/pre-commit.sh
echo -n "Add files to repo: " echo -e "Add files to repo: \c"
# shellcheck disable=SC2086 # shellcheck disable=SC2086
for file in ${FILES} for file in ${FILES}
do do
[ -d "${file}" ] && continue [ -d "${file}" ] && continue
echo -n "${file} " echo -e "${file} \c"
git add "$file"
done done
git add . echo " - Done."
echo "done."

24
dev/hooks/post-commit.sh Executable file
View File

@ -0,0 +1,24 @@
#!/usr/bin/env bash
#### $$VERSION$$ v1.20-0-g2ab00a2
############
# NOTE: you MUST run install-hooks.sh again when updating this file!
# magic to ensure that we're always inside the root of our application,
# no matter from which directory we'll run script
GIT_DIR=$(git rev-parse --git-dir)
cd "$GIT_DIR/.." || exit 1
export HOOKDIR="dev/hooks"
LASTPUSH='.git/.lastcommit'
# if any command inside script returns error, exit and return that error
set -e
#echo "Running post-commit hook"
#echo "............................"
unset IFS; set -f
# note date of last push for version
touch "${LASTPUSH}"

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#### $$VERSION$$ v1.1-0-gc0eb399 #### $$VERSION$$ v1.20-0-g2ab00a2
############ ############
# NOTE: you MUST run install-hooks.sh again when updating this file! # NOTE: you MUST run install-hooks.sh again when updating this file!
@ -30,7 +30,7 @@ fi
# run shellcheck before commit # run shellcheck before commit
set +f set +f
FILES="$(find ./* -name '*.sh' | grep -v 'DIST\/' | grep -v 'STANDALONE\/')" FILES="$(find ./* -name '*.sh' | grep -v -e 'DIST\/' -e 'STANDALONE\/' -e 'JSON.sh')"
set -f set -f
FILES="${FILES} $(sed '/^#/d' <"dev/shellcheck.files")" FILES="${FILES} $(sed '/^#/d' <"dev/shellcheck.files")"
if [ "$FILES" != "" ]; then if [ "$FILES" != "" ]; then
@ -49,7 +49,7 @@ VERSION="$(git describe --tags | sed -e 's/-.*//' -e 's/v//' -e 's/,/./')"
# LOCAL version must greater than latest REMOTE release version # LOCAL version must greater than latest REMOTE release version
echo "Update Version of modified files" echo "Update Version of modified files"
if (( $(echo "${VERSION} >= ${REMOTEVER}" | bc -l) )); then if ! command -v bc &> /dev/null || (( $(echo "${VERSION} >= ${REMOTEVER}" | bc -l) )); then
# update version in bashbot files on push # update version in bashbot files on push
set +f set +f
[ -f "${LASTPUSH}" ] && LASTFILES="$(find ./* -newer "${LASTPUSH}")" [ -f "${LASTPUSH}" ] && LASTFILES="$(find ./* -newer "${LASTPUSH}")"
@ -68,7 +68,7 @@ fi
if command -v codespell &>/dev/null; then if command -v codespell &>/dev/null; then
echo "Running codespell" echo "Running codespell"
echo "............................" echo "............................"
codespell -B 1 --skip="*.log,*.html,*.txt,.git*,jsonDB-keyboard" -L "ba" codespell --skip="*.zip,*gz,*.log,*.html,*.txt,.git*,jsonDB-keyboard" -L "ba"
echo "if there are (to many) typo's shown, consider running:" echo "if there are (to many) typo's shown, consider running:"
echo "codespell -i 3 -w --skip=\"*.log,*.html,*.txt,.git*,examples\" -L \"ba\"" echo "codespell -i 3 -w --skip=\"*.log,*.html,*.txt,.git*,examples\" -L \"ba\""
else else

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#### $$VERSION$$ v1.1-0-gc0eb399 #### $$VERSION$$ v1.20-0-g2ab00a2
############ ############
# NOTE: you MUST run install-hooks.sh again when updating this file! # NOTE: you MUST run install-hooks.sh again when updating this file!

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# this has to run once atfer git clone # this has to run once atfer git clone
# and every time we create new hooks # and every time we create new hooks
#### $$VERSION$$ v1.1-0-gc0eb399 #### $$VERSION$$ v1.20-0-g2ab00a2
# magic to ensure that we're always inside the root of our application, # magic to ensure that we're always inside the root of our application,
# no matter from which directory we'll run script # no matter from which directory we'll run script
@ -15,7 +15,7 @@ fi
HOOKDIR="dev/hooks" HOOKDIR="dev/hooks"
echo -n "Installing hooks..." echo -n "Installing hooks..."
for hook in pre-commit pre-push for hook in pre-commit post-commit pre-push
do do
rm -f "${GIT_DIR}/hooks/${hook}" rm -f "${GIT_DIR}/hooks/${hook}"
if [ -f "${HOOKDIR}/${hook}.sh" ]; then if [ -f "${HOOKDIR}/${hook}.sh" ]; then

View File

@ -2,12 +2,13 @@
# file: make-distribution.sh # file: make-distribution.sh
# creates files and arcchives to dirtribute bashbot # creates files and arcchives to dirtribute bashbot
# #
#### $$VERSION$$ v1.1-0-gc0eb399 #### $$VERSION$$ v1.20-0-g2ab00a2
# magic to ensure that we're always inside the root of our application, # magic to ensure that we're always inside the root of our application,
# no matter from which directory we'll run script # no matter from which directory we'll run script
GIT_DIR=$(git rev-parse --git-dir 2>/dev/null) GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
if [ "$GIT_DIR" != "" ] ; then if [ "$GIT_DIR" != "" ] ; then
[[ "$GIT_DIR" != "/"* ]] && GIT_DIR="${PWD}/${GIT_DIR}"
cd "$GIT_DIR/.." || exit 1 cd "$GIT_DIR/.." || exit 1
else else
echo "Sorry, no git repository $(pwd)" && exit 1 echo "Sorry, no git repository $(pwd)" && exit 1
@ -17,7 +18,7 @@ VERSION="$(git describe --tags | sed -e 's/-[0-9].*//' -e 's/v//')"
DISTNAME="telegram-bot-bash" DISTNAME="telegram-bot-bash"
DISTDIR="./DIST/${DISTNAME}" DISTDIR="./DIST/${DISTNAME}"
DISTFILES="bashbot.rc bashbot.sh commands.sh mycommands.sh mycommands.sh.clean doc examples scripts modules addons LICENSE README.md README.txt README.html" DISTFILES="bashbot.rc bashbot.sh commands.sh mycommands.sh mycommands.sh.clean bin doc examples scripts modules addons LICENSE README.md README.txt README.html"
# run tests first! # run tests first!
@ -49,22 +50,31 @@ done
# dwonload JSON.sh # dwonload JSON.sh
echo "Inject JSON.sh" echo "Inject JSON.sh"
JSONSHFILE="JSON.sh/JSON.sh" JSONSHFILE="JSON.sh/JSON.sh"
if [ ! -f "${JSONSHFILE}" ]; then if [ ! -r "${JSONSHFILE}" ]; then
mkdir "JSON.sh" 2>/dev/null mkdir "JSON.sh" 2>/dev/null
curl -sL -o "${JSONSHFILE}" "https://cdn.jsdelivr.net/gh/dominictarr/JSON.sh/JSON.sh" curl -sL -o "${JSONSHFILE}" "https://cdn.jsdelivr.net/gh/dominictarr/JSON.sh/JSON.sh"
chmod +x "${JSONSHFILE}" chmod +x "${JSONSHFILE}"
fi fi
echo "Inject JSON.awk"
JSONSHFILE="JSON.sh/JSON.awk"
if [ ! -r "${JSONSHFILE}" ]; then
curl -sL -o "${JSONSHFILE}" "https://cdn.jsdelivr.net/gh/step-/JSON.awk/JSON.awk"
curl -sL -o "${JSONSHFILE%/*}/awk-patch.sh" "https://cdn.jsdelivr.net/gh/step-/JSON.awk/tool/patch-for-busybox-awk.sh"
bash "${JSONSHFILE%/*}/awk-patch.sh" "${JSONSHFILE%/*}/JSON.awk"
fi
rm -f "${JSONSHFILE%/*}"/*.bak
# make html doc # make html doc
echo "Create html doc" echo "Create html doc"
#shellcheck disable=SC1090 # shellcheck disable=SC1090,SC1091
source "$GIT_DIR/../dev/make-html.sh" source "../../dev/make-html.sh"
# create archive # create archive
cd .. || exit 1 cd .. || exit 1
echo "Create dist archives" echo "Create dist archives"
zip -rq "${DISTNAME}-${VERSION}.zip" "${DISTNAME}" # shellcheck disable=SC2046
tar -czf "${DISTNAME}-${VERSION}.tar.gz" "${DISTNAME}" zip -rq - "${DISTNAME}" --exclude $(cat "$GIT_DIR/../dev/${0##*/}.exclude") >"${DISTNAME}-${VERSION}.zip"
tar --exclude-ignore="$GIT_DIR/../dev/${0##*/}.exclude" -czf "${DISTNAME}-${VERSION}.tar.gz" "${DISTNAME}"
echo "Done!" echo "Done!"

View File

@ -0,0 +1,7 @@
data-bot-bash/*
*.jssh
botacl
*.flock
*.log
*.last
*.ok

View File

@ -5,12 +5,13 @@
# If you your bot is finished you can use make-standalone.sh to create the # 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! # the old all-in-one bashbot: bashbot.sh and commands.sh only!
# #
#### $$VERSION$$ v1.1-0-gc0eb399 #### $$VERSION$$ v1.20-0-g2ab00a2
# magic to ensure that we're always inside the root of our application, # magic to ensure that we're always inside the root of our application,
# no matter from which directory we'll run script # no matter from which directory we'll run script
GIT_DIR=$(git rev-parse --git-dir 2>/dev/null) GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
if [ "$GIT_DIR" != "" ] ; then if [ "$GIT_DIR" != "" ] ; then
[[ "$GIT_DIR" != "/"* ]] && GIT_DIR="${PWD}/${GIT_DIR}"
cd "$GIT_DIR/.." || exit 1 cd "$GIT_DIR/.." || exit 1
else else
[ ! -f "bashbot.sh" ] && echo "bashbot.sh not found in $(pwd)" && exit 1 [ ! -f "bashbot.sh" ] && echo "bashbot.sh not found in $(pwd)" && exit 1
@ -38,7 +39,7 @@ echo " ... create unified commands.sh"
{ {
# first head of commands.sh # first head of commands.sh
sed -n '0,/^if / p' commands.sh | head -n -2 sed -n '0,/^if / p' commands.sh | grep -v -F -e "___" -e "*MUST*" -e "mycommands.sh.dist" -e "mycommands.sh.clean"| head -n -2
# then mycommands from first non comment line on # then mycommands from first non comment line on
printf '\n##############################\n# my commands starts here ...\n' printf '\n##############################\n# my commands starts here ...\n'
@ -77,7 +78,7 @@ rm -rf modules
echo "Create minimized Version of bashbot.sh and commands.sh" echo "Create minimized Version of bashbot.sh and commands.sh"
sed -E -e '/(shellcheck)|(#!\/bin\/bash)/! s/^[[:space:]]*#.*//' -e 's/^[[:space:]]*//' -e '/^$/d' -e 'N;s/\\\n/ /;P;D' bashbot.sh |\ sed -E -e '/(shellcheck)|(#!\/bin\/bash)/! s/^[[:space:]]*#.*//' -e 's/^[[:space:]]*//' -e '/^$/d' -e 'N;s/\\\n/ /;P;D' bashbot.sh |\
sed 'N;s/\\\n/ /;P;D' > bashbot.sh.min sed 'N;s/\\\n/ /;P;D' > bashbot.sh.min
sed -E -e '/(shellcheck)|(#!\/bin\/bash)/! s/^[[:space:]]*#.*//' -e 's/^[[:space:]]*//' -e '/^$/d' commands.sh |\ sed -E -e '/(shellcheck)|(#!\/bin\/bash)/! s/^[[:space:]]*#.*//' -e 's/^[[:space:]]*//' -e 's/\)[[:space:]]+#.*/)/' -e '/^$/d' commands.sh |\
sed 'N;s/\\\n/ /;P;D' > commands.sh.min sed 'N;s/\\\n/ /;P;D' > commands.sh.min
chmod +x bashbot.sh.min chmod +x bashbot.sh.min

View File

@ -1,5 +1,5 @@
#!/bin/bash #!/bin/bash
# shellcheck disable=SC2028,2016 # shellcheck disable=SC2028,SC2016,SC1117
# joke hack to obfuscate bashbot.min.sh # joke hack to obfuscate bashbot.min.sh
infile="bashbot.sh" infile="bashbot.sh"

View File

@ -1,4 +1,4 @@
# list of additional files to check from shellcheck # list of additional files to check from shellcheck
#### $$VERSION$$ v1.1-0-gc0eb399 #### $$VERSION$$ v1.20-0-g2ab00a2
bashbot.rc bashbot.rc
mycommands.sh.clean mycommands.sh.clean

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# #
#### $$VERSION$$ v1.1-0-gc0eb399 #### $$VERSION$$ v1.20-0-g2ab00a2
# shellcheck disable=SC2016 # shellcheck disable=SC2016
# #
# Easy Versioning in git: # Easy Versioning in git:

View File

@ -54,8 +54,24 @@ Now you can restart your bashbot instances.
wget -q https://github.com/$(wget -q https://github.com/topkecleon/telegram-bot-bash/releases/latest -O - | egrep '/.*/.*/.*tar.gz' -o) wget -q https://github.com/$(wget -q https://github.com/topkecleon/telegram-bot-bash/releases/latest -O - | egrep '/.*/.*/.*tar.gz' -o)
``` ```
### Use JSON.awk (beta)
### Install from github [JSON.awk](https://github.com/step-/JSON.awk) is an awk port of `JSON.sh`, it provides the same functionality but is 5 times faster.
Most systems with awk can use `JSON.awk` as drop in replacement
( [gnu awk, posix awk, mawk, busybox akw](https://github.com/step-/JSON.awk#compatibility-with-awk-implementations) ).
BSD and MacOS users must install `gnu awk` and adjust the shebang, see below
After you have checked that 'JSON.awk' is working correct on your system make `JSON.awk` executable and (re)start bashbot.
Note: If you are not using the zip / tar archive, you must install `JSON.awk` manually into the same directory as 'JSON.sh`:
wget https://cdn.jsdelivr.net/gh/step-/JSON.awk/JSON.awk
wget https://cdn.jsdelivr.net/gh/step-/JSON.awk/tool/patch-for-busybox-awk.sh
bash patch-for-busybox-awk.sh
### Install bashbot from github
The first install can also be done from github, updates should always done from the zip or tar archive to avoid The first install can also be done from github, updates should always done from the zip or tar archive to avoid
overwriting your config and ```mycommands.sh``` files. overwriting your config and ```mycommands.sh``` files.
@ -169,5 +185,5 @@ The old format is supported for backward compatibility, but may fail for corner
#### [Next Create Bot](1_firstbot.md) #### [Next Create Bot](1_firstbot.md)
#### $$VERSION$$ v1.1-0-ge835bbc #### $$VERSION$$ v1.20-0-g2ab00a2

View File

@ -65,5 +65,5 @@ group. This step is up to you actually.
#### [Prev Installation](0_install.md) #### [Prev Installation](0_install.md)
#### [Next Getting started](2_usage.md) #### [Next Getting started](2_usage.md)
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2

View File

@ -29,6 +29,15 @@ Have FUN!
├── commands.sh # command dispatcher - DO NOT EDIT! ├── commands.sh # command dispatcher - DO NOT EDIT!
├── JSON.sh # bashbots JSON parser, see https://github.com/dominictarr/JSON.sh ├── JSON.sh # bashbots JSON parser, see https://github.com/dominictarr/JSON.sh
├── bin # ready to use scripts, use `scriptname --help` for help
│   ├── send_message.sh # send message to given chat
│   ├── edit_message.sh # replace given message id in given chat
│   ├── send_broadcast.sh # send message to all known chats
│   ├── send_file.sh # send file to given chat
│   ├── bashbot_stats.sh # does what it says ...
│ │
│   └── bashbot_env.inc.sh # bashbot location included from scripts, adapt if needed
├── scripts # place your bashbot interactive and background scripts here ├── scripts # place your bashbot interactive and background scripts here
│   └── interactive.sh.clean # interactive script template for new scripts │   └── interactive.sh.clean # interactive script template for new scripts
@ -77,22 +86,54 @@ Start or Stop your Bot use the following commands:
./bashbot.sh stop ./bashbot.sh stop
``` ```
### User stats ### Scripts in bin/
To count the total number of users and messages run the following command: To count the total number of users and messages run the following command:
```bash
bin/bashbot_stats.sh
``` ```
./bashbot.sh stats
```
### Sending broadcasts to all users
To send a broadcast to all of users that ever used the bot run the following command: To send a broadcast to all of users that ever used the bot run the following command:
```bash
bin/send_broadcast.sh "Hey, I just wanted to let you know that the bot's been updated!"
Sending broadcast message to all users of Deal_O_Mat_bot
DRY RUN! use --doit as first argument to execute broadcast...
...
Message "Hey, ..." sent to xxx users.
``` ```
./bashbot.sh broadcast "Hey! I just wanted to let you know that the bot's been updated!"
To send a message to one user or chat run the following command:
```bash
bin/send_message.sh "CHAT[ID]" "Hey, I just wanted to let you know that the bot's been updated!"
["OK"] "true"
["ID"] "12345"
``` ```
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!"
["OK"] "true"
["ID"] "12345"
```
To send a file to one user or chat run the following command:
```bash
bin/send_file.sh "CHAT[ID]" "funny-pic.jpg" "enjoy this picture"
["OK"] "true"
["ID"] "12346"
```
Note: to get help about a script in bin/ run `scriptname.sh --help`
---- ----
## Receive data ## Receive data
@ -186,10 +227,14 @@ e.g. if a new user joins a chat MESSAGE is set to "/_new_chat_user".
* ```${MESSAGE}```: /_new_chat_title SENDER TEXT * ```${MESSAGE}```: /_new_chat_title SENDER TEXT
* ```${SERVICE[NEWPHOTO]}```: New Chat Picture * ```${SERVICE[NEWPHOTO]}```: New Chat Picture
* ```${MESSAGE}```: /_new_chat_picture SENDER URL * ```${MESSAGE}```: /_new_chat_picture SENDER URL
* ```${SERVICE[PINNED]}```: Pinned Message structure * ```${SERVICE[PINNED]}```: Pinned MESSAGE ID
* ```${MESSAGE}```: /_new_pinned_message SENDER ID * ```${MESSAGE}```: /_new_pinned_message SENDER ID
* ```${PINNED[ID]}```: Id of pinned message * ```${PINNED[ID]}```: Id of pinned message
* ```${PINNED[MESSAGE]}```: Message text of pinned message * ```${PINNED[MESSAGE]}```: Message text of pinned message
* ```${SERVICE[MIGRATE]}```: Old and new group id
* ```${MESSAGE}```: /_migrate_group MIGRATE_FROM MIGRATE_TO
* ```${MIGRATE[FROM]}```: Old group id
* ```${MIGRATE[TO]}```: New group id
@ -205,14 +250,26 @@ they contain the following variables only:
* ```${iQUERY[FIRST_NAME]}```: User's first name * ```${iQUERY[FIRST_NAME]}```: User's first name
* ```${iQUERY[LAST_NAME]}```: User's last name * ```${iQUERY[LAST_NAME]}```: User's last name
### Send Message Results
BOTSENT is set on every send_xxx action and only valid until next send action. For more on message results see.
[Advanced Usage](3_advanced.md)
* ```$BOTSENT```: This array contains the parsed results from the last transmission to telegram.
* ```${BOTSENT[OK]}```: contains the string ```true```: after a successful transmission
* ```${BOTSENT[ID]}```: Message ID of sent message, image, file etc., if OK is true
## Usage of bashbot functions ## Usage of bashbot functions
#### sending messages #### sending messages
To send messages use the ```send_xxx_message``` functions. To send messages use the ```send_xxx_message``` functions.
To insert line brakes in a message place `\n` in the text.
To send regular text without any markdown use: To send regular text without any markdown use:
```bash ```bash
send_text_message "${CHAT[ID]}" "lol" send_normal_message "${CHAT[ID]}" "lol"
``` ```
To send text with markdown: To send text with markdown:
```bash ```bash
@ -283,5 +340,5 @@ send_action "${CHAT[ID]}" "action"
#### [Prev Create Bot](1_firstbot.md) #### [Prev Create Bot](1_firstbot.md)
#### [Next Advanced Usage](3_advanced.md) #### [Next Advanced Usage](3_advanced.md)
#### $$VERSION$$ v1.1-0-gc0eb399 #### $$VERSION$$ v1.20-0-g2ab00a2

View File

@ -106,7 +106,7 @@ echo -e "Your Message: ${test}\nbye!"
#### message formatting and keyboards #### message formatting and keyboards
The output of the script will be processed by 'send_messages', so you can not only send text, but also keyboards, files, locations and more. The output of the script will be processed by 'send_messages', so you can not only send text, but also keyboards, files, locations and more.
Each newline in the output will start an new message to the user, to insert line breaks in your message you must insert ' mynewlinestartshere ' instead of a newline.. Each newline in the output will start an new message to the userr. To have line breaks in your message you must insert ' mynewlinestartshere ' or '\n' instead.
To open up a keyboard in an interactive script, print out the keyboard layout in the following way: To open up a keyboard in an interactive script, print out the keyboard layout in the following way:
```bash ```bash
@ -134,9 +134,10 @@ echo "Text that will appear in chat? mykeyboardstartshere [ \"Yep, sure\" , \"No
``` ```
Please note that you can either send a location or a venue, not both. To send a venue add the mytitlestartshere and the myaddressstartshere keywords. Please note that you can either send a location or a venue, not both. To send a venue add the mytitlestartshere and the myaddressstartshere keywords.
New in v0.6: To insert a linebreak in your message you can insert ```mynewlinestartshere``` in your echo command: To insert a line break in your message you can insert ` mynewlinestartshere ` or `\n` in your echo command:
```bash ```bash
echo "Text that will appear in one message mynewlinestartshere with this text on a new line" echo "Text that will appear in one message mynewlinestartshere with this text on a new line"
echo "Other text message\nwith a newline" # \n instead of mynewlinestartshere
``` ```
New in v0.7: In case you must extend a message already containing a location, a file, a keyboard etc., New in v0.7: In case you must extend a message already containing a location, a file, a keyboard etc.,
@ -227,7 +228,7 @@ answer_inline_query "${iQUERY[ID]}" "cached_sticker" "identifier for the sticker
See also [answer_inline_multi, answer_inline_compose](6_reference.md#answer_inline_multi) and [mycommands.sh](../mycommands.sh) for more information. See also [answer_inline_multi, answer_inline_compose](6_reference.md#answer_inline_multi) and [mycommands.sh](../mycommands.sh) for more information.
### Handle send message errors ### Send message results
Our examples usually do not care about errors happening while sending a message, this is OK as long your bot does not send an Our examples usually do not care about errors happening while sending a message, this is OK as long your bot does not send an
massive aoumnt of messages. By default bashbot detects if a message is not sent and try to recover when possible, massive aoumnt of messages. By default bashbot detects if a message is not sent and try to recover when possible,
@ -244,6 +245,7 @@ every send action will overwrite them!
* ```$BOTSENT```: This array contains the parsed results from the last transmission to telegram. * ```$BOTSENT```: This array contains the parsed results from the last transmission to telegram.
* ```${BOTSENT[OK]}```: contains the string ```true```: after a successful transmission * ```${BOTSENT[OK]}```: contains the string ```true```: after a successful transmission
* ```${BOTSENT[ID]}```: Message ID if OK is true
* ```${BOTSENT[ERROR]}```: Error code if an error occurred * ```${BOTSENT[ERROR]}```: Error code if an error occurred
* ```${BOTSENT[DESC]}```: Description text for error * ```${BOTSENT[DESC]}```: Description text for error
* ```${BOTSENT[RETRY]}```: Seconds to wait if telegram requests throtteling. * ```${BOTSENT[RETRY]}```: Seconds to wait if telegram requests throtteling.
@ -297,5 +299,5 @@ Note: If you disable automatic retry, se above, you disable also connection prob
#### [Prev Getting started](2_usage.md) #### [Prev Getting started](2_usage.md)
#### [Next Expert Use](4_expert.md) #### [Next Expert Use](4_expert.md)
#### $$VERSION$$ v1.2-dev-14-g6ec00d4 #### $$VERSION$$ v1.20-0-g2ab00a2

View File

@ -378,5 +378,5 @@ for every poll until the maximum of BASHBOT_SLEEP ms.
#### [Prev Advanced Use](3_advanced.md) #### [Prev Advanced Use](3_advanced.md)
#### [Next Best Practice](5_practice.md) #### [Next Best Practice](5_practice.md)
#### $$VERSION$$ v1.2-dev-13-g2a5d47d #### $$VERSION$$ v1.20-0-g2ab00a2

View File

@ -158,5 +158,5 @@ The second warning is about an unused variable, this is true because in our exam
#### [Prev Best Practice](5_practice.md) #### [Prev Best Practice](5_practice.md)
#### [Next Functions Reference](6_reference.md) #### [Next Functions Reference](6_reference.md)
#### $$VERSION$$ v1.2-dev-13-g2a5d47d #### $$VERSION$$ v1.20-0-g2ab00a2

View File

@ -3,6 +3,8 @@
### Send, forward, delete messages ### Send, forward, delete messages
To insert line brakes in a message or caption you can place `\n` in the text.
##### send_action ##### send_action
```send_action``` shows users what your bot is currently doing. ```send_action``` shows users what your bot is currently doing.
@ -18,7 +20,6 @@ send_action "${CHAT[ID]}" "typing"
send_action "${CHAT[ID]}" "record_audio" send_action "${CHAT[ID]}" "record_audio"
``` ```
##### send_normal_message ##### send_normal_message
```send_normal_message``` sends text only messages to the given chat. ```send_normal_message``` sends text only messages to the given chat.
@ -32,9 +33,24 @@ send_normal_message "${CHAT[ID]}" "this is a text message"
``` ```
##### send_markdownv2_message
```send_markdownv2_message``` sends markdown v2 style messages to the given chat.
Telegram supports a new [Markdown V2 Style](https://core.telegram.org/bots/api#markdownv2-style) which
has more formatting codes and is more robust, but incompatible with old telegram markdown style.
*usage:* send_markdownv2_message "${CHAT[ID]}" "markdown message"
*example:*
```bash
send_markdownv2_message "${CHAT[ID]}" "this is a markdown message, next word is *bold*"
send_markdownv2_message "${CHAT[ID]}" "*bold* __underlined__ [text](link)"
```
##### send_markdown_message ##### send_markdown_message
```send_markdown_message``` sends markdown style messages to the given chat. ```send_markdown_message``` sends markdown style messages to the given chat.
Telegram supports a [reduced set of Markdown](https://core.telegram.org/bots/api#markdown-style) only This is the old, legacy Telegram markdown style, retained for backward compatibility.
It supports a [reduced set of Markdown](https://core.telegram.org/bots/api#markdown-style) only
*usage:* send_markdown_message "${CHAT[ID]}" "markdown message" *usage:* send_markdown_message "${CHAT[ID]}" "markdown message"
@ -46,6 +62,7 @@ send_markdown_message "${CHAT[ID]}" "this is a markdown message, next word is *
send_markdown_message "${CHAT[ID]}" "*bold* _italic_ [text](link)" send_markdown_message "${CHAT[ID]}" "*bold* _italic_ [text](link)"
``` ```
##### send_html_message ##### send_html_message
```send_html_message``` sends HTML style messages to the given chat. ```send_html_message``` sends HTML style messages to the given chat.
Telegram supports a [reduced set of HTML](https://core.telegram.org/bots/api#html-style) only Telegram supports a [reduced set of HTML](https://core.telegram.org/bots/api#html-style) only
@ -204,6 +221,72 @@ send_inline_keyboard "${CHAT[ID]}" "" '[{"text":"b 1", url"":"u 1"}, {"text":"b
*See also [Inline keyboard markup](https://core.telegram.org/bots/api/#inlinekeyboardmarkup)* *See also [Inline keyboard markup](https://core.telegram.org/bots/api/#inlinekeyboardmarkup)*
----
### Edit / Replace Messages
Edit a message means replace the content of the message in place. The message stay on the same position in the chat and keep the same
message id.
There is no need to use the same format when replace a message, e.g. a message sent with `send_normal_message` can be replaced with
`edit_markdown_message` or `edit_html_message` and vice versa.
To replace a message you must know the message id of the the original message. The best way to get the message id is to save the value of
`BOTSENT[ID]` after sending the original message.
##### edit_normal_message
```edit_normal_message``` replace a message with a text message in the given chat.
*usage:* edit_normal_message "${CHAT[ID]}" "MESSAGE-ID" "message"
*example:*
```bash
send_normal_message "${CHAT[ID]}" "this is a text message"
saved-id="${BOTSENT[ID]}"
edit_normal_message "${CHAT[ID]}" "${saved-id}" "this is another text"
```
##### edit_markdownv2_message
```edit_markdownv2_message``` replace a message with a markdown v2 message in the given chat.
*usage:* edit_markdownv2_message "${CHAT[ID]}" "MESSAGE-ID" "message"
*example:*
```bash
send_normal_message "${CHAT[ID]}" "this is a text message"
saved-id="${BOTSENT[ID]}"
edit_markdownv2_message "${CHAT[ID]}" "${saved-id}" "this is __markdown__ *V2* text"
```
##### edit_markdown_message
```edit_markdown_message``` replace a message with a markdown message in the given chat.
*usage:* edit_markdown_message "${CHAT[ID]}" "MESSAGE-ID" "message"
*example:*
```bash
send_normal_message "${CHAT[ID]}" "this is a text message"
saved-id="${BOTSENT[ID]}"
edit_markdown_message "${CHAT[ID]}" "${saved-id}" "this is *markdown* text"
```
##### edit_html_message
```edit_html_message``` replace a message with a html message in the given chat.
*usage:* edit_html_message "${CHAT[ID]}" "MESSAGE-ID" "message"
*example:*
```bash
send_normal_message "${CHAT[ID]}" "this is a text message"
saved-id="${BOTSENT[ID]}"
edit_html_message "${CHAT[ID]}" "${saved-id}" "this is <b>html</b> text"
```
---- ----
### User Access Control ### User Access Control
@ -244,6 +327,19 @@ fi
The following functions are bashbot only and not part of the Telegram API. The following functions are bashbot only and not part of the Telegram API.
##### bot_is_admin
Return true (0) if bot is admin or creator of given chat.
*usage:* bot_is_admin "${CHAT[ID]}"
*example:*
```bash
if bot_is_admin "${CHAT[ID]}"; then
send_markdown_message "${CHAT[ID]}" "*I'm admin...*"
fi
```
##### user_is_botadmin ##### user_is_botadmin
Return true (0) if user is admin of bot, user id if botadmin is read from file './botadmin'. Return true (0) if user is admin of bot, user id if botadmin is read from file './botadmin'.
@ -253,7 +349,7 @@ Return true (0) if user is admin of bot, user id if botadmin is read from file '
*example:* *example:*
```bash ```bash
_is_botadmin && send_markdown_message "${CHAT[ID]}" "You are *BOTADMIN*." user_is_botadmin "${CHAT[ID]}" && send_markdown_message "${CHAT[ID]}" "You are *BOTADMIN*."
``` ```
##### user_is_creator ##### user_is_creator
@ -272,7 +368,7 @@ Return true (0) if user is admin or creator of given chat.
*example:* *example:*
```bash ```bash
if _is_admin ; then if user_is_admin "${CHAT[ID]}" ; then
send_markdown_message "${CHAT[ID]}" "*LEAVING CHAT...*" send_markdown_message "${CHAT[ID]}" "*LEAVING CHAT...*"
leave_chat "${CHAT[ID]}" leave_chat "${CHAT[ID]}"
fi fi
@ -1049,5 +1145,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca
#### [Prev Best Practice](5_practice.md) #### [Prev Best Practice](5_practice.md)
#### [Next Notes for Developers](7_develop.md) #### [Next Notes for Developers](7_develop.md)
#### $$VERSION$$ v1.2-dev-13-g2a5d47d #### $$VERSION$$ v1.20-0-g2ab00a2

View File

@ -25,6 +25,8 @@ you can the change the level of verbosity of the debug argument:
``` ```
Logging of telegram update poll is disabled by default, also in `debug` mode. To enable it without using verbose `xdebug` mode
set `BASHBOT_UPDATELOG` to an empty value (not unset) `export BASHBOT_UPDATELOG=""`
### Modules and Addons ### Modules and Addons
**Modules** resides in ```modules/*.sh``` and are colletions of optional bashbot functions grouped by functionality. Main reason for creating modules was **Modules** resides in ```modules/*.sh``` and are colletions of optional bashbot functions grouped by functionality. Main reason for creating modules was
@ -188,7 +190,7 @@ Now have a look at the directory 'standalone', here you find the files 'bashbot.
### Setup your develop environment ### Setup your develop environment
1. install git, install [shellcheck](5_practice.md#Test-your-Bot-with-shellcheck) 1. install the commands git, [shellcheck](5_practice.md#Test-your-Bot-with-shellcheck), bc, pandoc, bc, codespell
2. setup your [environment for UTF-8](4_expert.md#Setting-up-your-Environment) 2. setup your [environment for UTF-8](4_expert.md#Setting-up-your-Environment)
3. clone your bashbot fork to a new directory ```git clone https://github.com/<YOURNAME>/telegram-bot-bash.git```, replace ```<YOURNAME>``` with your username on github 3. clone your bashbot fork to a new directory ```git clone https://github.com/<YOURNAME>/telegram-bot-bash.git```, replace ```<YOURNAME>``` with your username on github
4. create and change to your develop branch ```git checkout -b <YOURBRANCH>```, replace ```<YOURBRANCH>``` with the name you want to name it, e.g. 'develop' 4. create and change to your develop branch ```git checkout -b <YOURBRANCH>```, replace ```<YOURBRANCH>``` with the name you want to name it, e.g. 'develop'
@ -347,5 +349,5 @@ fi
#### [Prev Function Reference](6_reference.md) #### [Prev Function Reference](6_reference.md)
#### $$VERSION$$ v1.2-dev-13-g2a5d47d #### $$VERSION$$ v1.20-0-g2ab00a2

View File

@ -56,6 +56,6 @@ convert existing bots.
**jsonDB-keybords** contains a stripped down real world example from my bot showing the usage of jsonDB to store and retrieve values **jsonDB-keybords** contains a stripped down real world example from my bot showing the usage of jsonDB to store and retrieve values
plus use of keyboards in private chats. It's an extended version of mycommands.sh.dist. Messages and help are in german. plus use of keyboards in private chats. It's an extended version of mycommands.sh.dist. Messages and help are in german.
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2

View File

@ -4,7 +4,7 @@
# #
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#### $$VERSION$$ v1.2-dev-13-g2a5d47d #### $$VERSION$$ v1.20-0-g2ab00a2
###### ######
# parameters # parameters

View File

@ -2,7 +2,7 @@
# file: run_filename # file: run_filename
# background job to display content of all new files in WATCHDIR # background job to display content of all new files in WATCHDIR
# #
#### $$VERSION$$ v1.2-dev-13-g2a5d47d #### $$VERSION$$ v1.20-0-g2ab00a2
###### ######
# parameters # parameters

View File

@ -2,7 +2,7 @@
# file: run_filename # file: run_filename
# background job to display all new files in WATCHDIR # background job to display all new files in WATCHDIR
# #
#### $$VERSION$$ v1.2-dev-13-g2a5d47d #### $$VERSION$$ v1.20-0-g2ab00a2
###### ######
# parameters # parameters

View File

@ -4,7 +4,7 @@
# #
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
###### ######
# parameters # parameters

View File

@ -5,8 +5,8 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# shellcheck disable=SC1117
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# adjust your language setting here # adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment # https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment

View File

@ -2,7 +2,7 @@
# file. multibot.sh # file. multibot.sh
# description: run multiple telegram bots from one installation # description: run multiple telegram bots from one installation
# #
#### $$VERSION$$ v1.2-dev-13-g2a5d47d #### $$VERSION$$ v1.20-0-g2ab00a2
if [ "${2}" = "" ] || [ "${2}" = "-h" ]; then if [ "${2}" = "" ] || [ "${2}" = "-h" ]; then
echo "Usage: $0 botname command" echo "Usage: $0 botname command"

View File

@ -7,7 +7,7 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
SHELL=/bin/sh SHELL=/bin/sh

View File

@ -5,7 +5,7 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
###### ######
# parameters # parameters

View File

@ -1,19 +1,25 @@
#!/bin/bash #!/bin/bash
# files: mycommands.sh.dist #===============================================================================
# copy to mycommands.sh and add all your commands and functions here ...
# #
#### $$VERSION$$ v1.2-dev-13-g2a5d47d # FILE: mycommands.sh
# #
# USAGE: will be included from commands.sh
#
# DESCRIPTION: real world example with jsshDB and send_keyboard
#
# AUTHOR: KayM (), kay@rrr.de
# DATE: 19.12.2020 19:03
#
#### $$VERSION$$ v1.20-0-g2ab00a2
#===============================================================================
# shellcheck disable=SC2154 # shellcheck disable=SC2154
# shellcheck disable=SC2034 # shellcheck disable=SC2034
# within *xxx* markup we need only one \ to escape a '_', e.g. my\_stupid\_bot (stupid V1 markup)
bashbot_title='*Hallo, ich bin der @'"${ME//_/\\_}"'. Ich suche und finde Dealz!*' bashbot_title='*Hallo, ich bin der @'"${ME//_/\\_}"'. Ich suche und finde Dealz!*'
# outside *xxxx* markup we need two \\ to escape a '_', e.g. -> my\\_stupid\\_bot
bashbot_shelp="${bashbot_title}"' bashbot_shelp="${bashbot_title}"'
Schicke mir hier -> @'"${ME//_/\\\\_}"' <- einen Befehl mit *max. 50 Begriffen*. Ein Begriff muss mindesten 4 Zeichen lang sein. Schicke mir https://t.me/'"${ME//_/\\_}"' einen Befehl mit *max. 50 Begriffen*. Ein Begriff muss mindesten 4 Zeichen lang sein.
*Befehle zum Suchen / Tracken von Dealz:* *Befehle zum Suchen / Tracken von Dealz:*
/search /suche _Suche in Deals der letzen 48h, /search /suche _Suche in Deals der letzen 48h,
@ -22,139 +28,56 @@ Schicke mir hier -> @'"${ME//_/\\\\_}"' <- einen Befehl mit *max. 50 Begriffen*.
/newtrack _Tracking mit neuen Begriffen, /newtrack _Tracking mit neuen Begriffen,
z.B.:_ /newtrack Apple mavic.\*air z.B.:_ /newtrack Apple mavic.\*air
/track /addkey _zusätzlicher Begriff zum Tracken_ /track /addkey _zusätzlicher Begriff zum Tracken_
/addblack _Begriff darf nicht vorkommen_
/delkey _lösche Begriff_ /delkey _lösche Begriff_
/delblack _lösche Blacklist Begriff_
/listtrack _zeigt aktuell getrackte Begriffe_ /listtrack _zeigt aktuell getrackte Begriffe_
/delkey ALL _löscht alle Begriffe_ /delkey ALL _löscht alle Begriffe_
/stattrack _Infos zum aktiven Tracking_ /stattrack _Infos zum aktiven Tracking_
Kurzform: /such /sea /newt /tra /addk /addb /delk /delb /lst /statt
*Platzhalter in Suchbegriffen:*
*.*\* = egal/alles: 1tb*.*\*ssd
⇨ 1Tb-ssd, 1tb ssd, 1Tb Supi ssd
*.* = genau ein Zeichen: *.*tb
⇨ 1Tb, 5TB, atb, ztb
*_* = Wortanfang/end: \\_Mavic\\_
⇨ das Wort _Mavic_
Die Suche ignoriert Gross und Klein Schreibung, Satzzeichen, Klammern und "-", ebenso Links und Bilder. Mehr zu Regular Expressions (RegEx) http://www.regexe.de/hilfe.jsp
' '
bashbot_whelp="${bashbot_title}"' bashbot_commands='*Meine Befehle*:
/info _- Info zum Bot_
/suche _- Suchen und Tracken von Dealz_
/hilfe _- Hilfe zu weiteren Befehlen_
Schicke mir hier -> @'"${ME//_/\\\\_}"' <- einen Befehl mit *max. 50 Artikeln (ASIN)* zum Beobachten. Du hast eine eigene Telegram Dealgruppe? Lade mich ein und alle in der Guppe können mich nutzen:
*Befehle zum Beobachten von Amzon Artikeln*
/newwatch _Beobachten neuer Artikel_
z.B.:_ /newwatch ASIN ASIN_
/watch /addwatch _weiteren Artikel beobachten_
/delwatch _löscht Artikel aus Beobachtung_
/listwatch _zeigt aktuell beobachtete Artikel_
/delwatch ALL _löscht alle Artikel_
/notify _einmalig warten bis Verfügar_
/listnotify _zeigt aktuell wartende Artikel_
/delnotify _löscht alle wartenden Artikel_
Kurzform: /neww /wat /addw /delw /listw /noti /listn /deln
'
bashbot_examples="${bashbot_title}"'
'
bashbot_group='*#MD Amazon Deutschland only Deals*
https://t.me/joinchat/IvvRtlEPhZKmWVVc8iTD2g
*#MD Zuhause, Family & Kids und Empfehlungen*
https://t.me/joinchat/IvvRtlT4f8HuwFDiJDCWoQ '
bashbot_all="${bashbot_title}"'
---------------------------------------------------------------------
'"${bashbot_group}"'
*#DL Amazon International*
https://t.me/joinchat/IvvRtkzPaMTHFZi3CjSX8g
*#MD Amazon Warehouse Schnäppchen *
https://t.me/joinchat/IvvRthRhj5NVkcihTxDZwQ
----------------------------------------------------------------------
Was hier kommt, kommt nur hier!
*#MD Kleidung, Accessoirs & Empfehlungen*
https://t.me/joinchat/IvvRthlJ8zwC7tHyhl63Fg
*#MD Mobilfunk & Smartphones*
https://t.me/joinchat/IvvRthtqth9Svyyvnb5lAQ
*#MD Gaming, Spiele & Konsolen*
https://t.me/joinchat/IvvRthRyrsmIyMFMc7189Q
---------------------------------------------------------------------
*#MD extrem - All Dealz über 100°*
https://t.me/joinchat/IvvRtk6ehHS4ZZmtoRFU2g
*#MD Offtopic: Diskussion & Ankündigungen*
https://t.me/joinchat/IvvRthRhMcX6rDQU-pZrWw
*Du willst Dealz suchen oder abbonieren?*
Klicke hier -> @'"${ME//_/\\\\_}"' <- und schicke /start
.
' '
# uncomment the following lines to overwrite info and help messages # uncomment the following lines to overwrite info and help messages
bashbot_info="${bashbot_title}"' bashbot_info="${bashbot_title}"'
'"${bashbot_group}"'
*#MD Offtopic: Diskussion & Ankündigungen*
Hier kannst Du dich austauschen und erfährst Neues.
https://t.me/joinchat/IvvRthRhMcX6rDQU-pZrWw
*Du willst Dealz suchen oder tracken?* *Du willst Dealz suchen oder tracken?*
Klicke hier -> @'"${ME//_/\\\\_}"' <- und schicke /start Klicke hier https://t.me/'"${ME//_/\\_}"' und schicke /start
*Meine Befehle*: '"${bashbot_commands}"'
/suche _- Suchen und Tracken von Dealz_
/watch _- Beobachten von Amazon Artikeln_
/gruppen _- Liste aller Dealz Gruppen_
/hilfe _- Hilfe zu weiteren Befehlen_
*Dein '"${ME//_/-}"'* *Dein '"${ME//_/-}"'*
https://dealz.rrr.de/amzdealz.html
' '
bashbot_help="${bashbot_title}"' bashbot_help="${bashbot_title}"'
Du hast eine eigene Telegram Dealgruppe? Lade mich ein und all in der Guppe können mich nutzen: *Du willst mich weiterempfehlen?*
Schicke https://t.me/'"${ME//_/\\_}"' an deinen Telegram Kontakt und sage ihm er soll darauf klicken und /start schicken.
*verfügbare Befehle*: '"${bashbot_commands}"'
/suche _- Suchen und Tracken von Dealz_
/watch _- Beobachten von Amazon Artikeln_
/gruppen _- Liste aller Dealz Gruppen_
/info _- Info zum Bot_ *Dein '"${ME//_/-}"'*
/help _- Zeigt diese Liste_
_https://dealz.rrr.de/assets/images/rdealomat.gif_
' '
# in a regular message is no need to escape '_' # in a regular message is no need to escape '_'
SORRYADMIN="Du bist kein Gruppenadmin, diesen Befehl kannst Du nur im privaten Chat ausführen @${ME} <<- hier klicken" SORRYADMIN="Du bist kein Gruppenadmin, diesen Befehl kannst Du nur im privaten Chat ausführen @${ME} <<- hier klicken"
SORRYADMIN2="Dieser Befehl ist dem Botadmin vorbehalten, sorry."
# Set INLINE to 1 in order to receive inline queries. # Set INLINE to 1 in order to receive inline queries.
# To enable this option in your bot, send the /setinline command to @BotFather. # To enable this option in your bot, send the /setinline command to @BotFather.
INLINE="" INLINE="0"
# if your bot is group admin it get commands sent to other bots
# Set MEONLY to 1 to ignore commands sent to other bots
export MEONLY="1"
# Set to .* to allow sending files from all locations # Set to .* to allow sending files from all locations
FILE_REGEX='/home/deal-O-mat/.*' FILE_REGEX='/this_is_my_bot_path/.*'
# run curl over TOR or SOCKS # run curl over TOR or SOCKS
#export BASHBOT_CURL_ARGS="--socks5-hostname localhost" #export BASHBOT_CURL_ARGS="--socks5-hostname localhost"
@ -180,40 +103,32 @@ WELCOME_MSG="Willkommen"
export REPORT_NEWMEMBER="yes" export REPORT_NEWMEMBER="yes"
export REPORT_LEFTMEMBER="yes" export REPORT_LEFTMEMBER="yes"
export REMINDER="Del-O-Mat: https://dealz.rrr.de/amzdealz.html\n https://dealz.rrr.de/ebaydealz.html" # location of Database files
TRACKFILE="${DATADIR}/0-dealtrack" TRACKFILE="${DATADIR}/0-dealtrack"
SEARCHFILE="${DATADIR}/0-dealsearch" SEARCHFILE="${DATADIR}/0-dealsearch"
WATCHFILE="${DATADIR}/0-dealwatch" WATCHFILE="${DATADIR}/0-dealwatch"
NOTIFYFILE="${DATADIR}/0-dealnotify"
if [ "$1" = "startbot" ];then if [ "$1" = "startbot" ];then
# run once after startup when the first message is received # mark startup, triggers action on first message
my_startup(){
# send reminder on startup, random delay
send_normal_message "-10011894xxxxx" "${REMINDER}"
}
setConfigKey "startupaction" "await" setConfigKey "startupaction" "await"
# create KEYOFILE DB if not exist # create Database files on startup
jssh_newDB "${TRACKFILE}" jssh_newDB "${TRACKFILE}"
jssh_newDB "${SEARCHFILE}" jssh_newDB "${SEARCHFILE}"
jssh_newDB "${WATCHFILE}" jssh_newDB "${WATCHFILE}"
jssh_newDB "${NOTIFYFILE}"
else else
# things to do only at source, eg. after startup
if [[ "$(getConfigKey "startupaction")" != "done"* ]]; then
setConfigKey "startupaction" "done $(date)"
my_startup
fi
# your additional bashbot commands # your additional bahsbot commands
# NOTE: command can have @botname attached, you must add * in case tests... # NOTE: command can have @botname attached, you must add * in case tests...
mycommands() { mycommands() {
# action triggered on first message after startup
if [[ "$(getConfigKey "startupaction")" != "done"* ]]; then
setConfigKey "startupaction" "done $(date)"
fi
# a service Message was received # a service Message was received
local SILENCER="yes" local SILENCER="yes"
if [[ "${SERVICE}" != "" ]]; then if [[ "${SERVICE}" != "" ]]; then
# example: dleted service messages # example: dleted service messages
if [ "${SILENCER}" = "yes" ]; then if [ "${SILENCER}" = "yes" ] && bot_is_admin "${CHAT[ID]}"; then
delete_message "${CHAT[ID]}" "${MESSAGE[ID]}" delete_message "${CHAT[ID]}" "${MESSAGE[ID]}"
fi fi
fi fi
@ -222,46 +137,35 @@ else
[ -n "${REMOVEKEYBOARD}" ] && remove_keyboard "${CHAT[ID]}" "..." & [ -n "${REMOVEKEYBOARD}" ] && remove_keyboard "${CHAT[ID]}" "..." &
[[ -n "${REMOVEKEYBOARD_PRIVATE}" && "${CHAT[ID]}" == "${USER[ID]}" ]] && remove_keyboard "${CHAT[ID]}" "..." & [[ -n "${REMOVEKEYBOARD_PRIVATE}" && "${CHAT[ID]}" == "${USER[ID]}" ]] && remove_keyboard "${CHAT[ID]}" "..." &
######################
# default commands
# fix upper case first letter in commands # fix upper case first letter in commands
[[ "${MESSAGE}" =~ ^/[[:upper:]] ]] && MESSAGE="${MESSAGE:0:1}$(tr '[:upper:]' '[:lower:]' <<<"${MESSAGE:1:1}")${MESSAGE:2}" [[ "${MESSAGE}" =~ ^/[[:upper:]] ]] && MESSAGE="${MESSAGE:0:1}$(tr '[:upper:]' '[:lower:]' <<<"${MESSAGE:1:1}")${MESSAGE:2}"
######################
# default commands
case "${MESSAGE}" in case "${MESSAGE}" in
'/info'*) '/info'*)
send_action "${CHAT[ID]}" "typing" send_action "${CHAT[ID]}" "typing"
delete_message "${CHAT[ID]}" "${MESSAGE[ID]}" delete_message "${CHAT[ID]}" "${MESSAGE[ID]}"
return 0 # continue with default action send_markdownv2_message "${CHAT[ID]}" "${bashbot_info}"
return 1 # continue with default action
;; ;;
'/hel'*|'/hil'*) '/hel'*|'/hil'*)
send_action "${CHAT[ID]}" "typing" send_action "${CHAT[ID]}" "typing"
delete_message "${CHAT[ID]}" "${MESSAGE[ID]}" delete_message "${CHAT[ID]}" "${MESSAGE[ID]}"
send_markdown_message "${CHAT[ID]}" "${bashbot_help}" send_markdownv2_message "${CHAT[ID]}" "${bashbot_help}"
return 1 # break, do not continue return 1 # break, do not continue
;; ;;
'/start'*) '/start'*)
send_markdown_message "${CHAT[ID]}" "${bashbot_info}" send_markdownv2_message "${CHAT[ID]}" "${bashbot_help}"
return 1 # break, do not continue return 1 # break, do not continue
;; ;;
'/gr'*) # list groups
delete_message "${CHAT[ID]}" "${MESSAGE[ID]}"
send_action "${CHAT[ID]}" "typing"
send_markdown_message "${CHAT[ID]}" "${bashbot_all}"
return
;;
#'/test'*)
# send_normal_message "${CHAT[ID]}" "Start interactive"
# send_markdown_message "${CHAT[ID]}" "TEST: äöüß!^°_-\"-,§$%&/(){}#@?[]{}._"
# return
# ;;
# will we process edited messages also?
'/_edited_message'*) '/_edited_message'*)
#return 1 # no #return 1 # no
# but if we do, remove /edited_message # but if we do, remove /edited_message
MESSAGE="${MESSAGE#/* }" MESSAGE="${MESSAGE#/* }"
;; ;;
'/_new_chat_member'*) '/_new_chat_member'*)
if [[ -n "${WELCOME_NEWMEMBER}" && "${NEWMEMBER[ISBOT]}" != "true" ]]; then if [[ -n "${WELCOME_NEWMEMBER}" && "${NEWMEMBER[ISBOT]}" != "true" ]] && bot_is_admin "${CHAT[ID]}"; then
send_normal_message "${CHAT[ID]}"\ send_normal_message "${CHAT[ID]}"\
"${WELCOME_MSG} ${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]} (@${NEWMEMBER[USERNAME]})" "${WELCOME_MSG} ${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]} (@${NEWMEMBER[USERNAME]})"
MYSENTID="${BOTSENT[ID]}" MYSENTID="${BOTSENT[ID]}"
@ -279,8 +183,8 @@ else
########## ##########
# pre test for admin only commands # pre test for admin only commands
case "${MESSAGE}" in case "${MESSAGE}" in
# must be in private chat, group admin, or botadmin # must be private, group admin, or botadmin
'/sea'*|'/su'*|'/add'*|'/new'*|'/del'*|'/tra'*|'/wat'*|'/noti'*|'/lista'*) '/sea'*|'/su'*|'/add'*|'/new'*|'/del'*|'/tra'*)
send_action "${CHAT[ID]}" "typing" send_action "${CHAT[ID]}" "typing"
if ! user_is_admin "${CHAT[ID]}" "${USER[ID]}" ; then if ! user_is_admin "${CHAT[ID]}" "${USER[ID]}" ; then
delete_message "${CHAT[ID]}" "${MESSAGE[ID]}" delete_message "${CHAT[ID]}" "${MESSAGE[ID]}"
@ -289,21 +193,13 @@ else
{ sleep 5; delete_message "${CHAT[ID]}" "${MYSENTID}"; } & { sleep 5; delete_message "${CHAT[ID]}" "${MYSENTID}"; } &
return 1 return 1
fi fi
;;& # ok, now lets process the real command
# must be botadmin
'/delu'*)
if ! user_is_botadmin "${USER[ID]}" ; then
delete_message "${CHAT[ID]}" "${MESSAGE[ID]}"
send_markdown_message "${CHAT[ID]}" "*${SORRYADMIN2}*";
MYSENTID="${BOTSENT[ID]}"
{ sleep 5; delete_message "${CHAT[ID]}" "${MYSENTID}"; } &
return 1
fi
;; ;;
esac esac
################# #################
# search commands # search commands
#local vairable, e.g. read/write Database
local FINDKEYS OLDKEYS KEY MYSENTID local FINDKEYS OLDKEYS KEY MYSENTID
declare -a KEYARR declare -a KEYARR
declare -A SEARCHVALUES declare -A SEARCHVALUES
@ -311,69 +207,30 @@ else
################# #################
# pre processing of search commands # pre processing of search commands
case "${MESSAGE}" in case "${MESSAGE}" in
'/add'*|'/tra'*|'/noti'*) # add no arg '/add'*|'/tra'*) # add no arg
FINDKEYS="${MESSAGE#/* }" FINDKEYS="${MESSAGE#/* }"
if [ "${FINDKEYS}" = "${MESSAGE}" ]; then if [ "${FINDKEYS}" = "${MESSAGE}" ]; then
send_normal_message "${CHAT[ID]}" "Kein Begriff angegeben!" send_normal_message "${CHAT[ID]}" "Kein Begriff angegeben!"
exit exit
fi fi
;;& ;;&
'/addw'*|'/wat'*) OLDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${WATCHFILE}")"
;;&
'/add'[kbt]*|'/tra'*) OLDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${TRACKFILE}")" '/add'[kbt]*|'/tra'*) OLDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${TRACKFILE}")"
;;& ;;&
'/noti'*) OLDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${NOTIFYFILE}")"
;;&
'/addk'*|'/addt'*|'/tra'*) # add track '/addk'*|'/addt'*|'/tra'*) # add track
MESSAGE="/newtrack ${FINDKEYS} ${OLDKEYS}" MESSAGE="/newtrack ${FINDKEYS} ${OLDKEYS}"
;; ;;
'/addb'*) # add black '/delk'*) #delete key
[[ "${OLDKEYS}" != *'!'* ]] && FINDKEYS="!${FINDKEYS}"
MESSAGE="/newtrack ${OLDKEYS} ${FINDKEYS}"
;;
'/addw'*|'/wat'*) # add watch
FINDKEYS="${MESSAGE#/* }"
if [ "${FINDKEYS}" = "${MESSAGE}" ]; then
delete_message "${CHAT[ID]}" "${MESSAGE[ID]}"
send_markdown_message "${CHAT[ID]}" "${bashbot_whelp}"
return
fi
MESSAGE="/newwatch ${FINDKEYS} ${OLDKEYS}"
;;
'/noti'*) # add watch
MESSAGE="/newnotify ${FINDKEYS} ${OLDKEYS}"
;;
'/delk'*|'/delb'*) # no user search
OLDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${TRACKFILE}")" OLDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${TRACKFILE}")"
if [ "${OLDKEYS}" = "" ]; then if [ "${OLDKEYS}" = "" ]; then
send_markdown_message "${CHAT[ID]}" "*Kein Tracking aktiv!*" send_markdownv2_message "${CHAT[ID]}" "*Kein Tracking aktiv!*"
return return
fi fi
;;&
'/delw'*) # no watch
OLDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${WATCHFILE}")"
if [ "${OLDKEYS}" = "" ]; then
send_markdown_message "${CHAT[ID]}" "*Kein Product Watch aktiv!*"
return
fi
;;&
'/deln'*) # no notify
OLDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${NOTIFYFILE}")"
if [ "${OLDKEYS}" = "" ]; then
send_markdown_message "${CHAT[ID]}" "*Kein Product Notify aktiv!*"
return
fi
jssh_deleteKeyDB "${CHAT[ID]}" "${NOTIFYFILE}"
send_normal_message "${CHAT[ID]}" "Product Notify \"${OLDKEYS}\" gelöscht!"
;;
'/delk'*) #delete key
KEY="${OLDKEYS%%|!*}" KEY="${OLDKEYS%%|!*}"
FINDKEYS="${MESSAGE#/* }" FINDKEYS="${MESSAGE#/* }"
read -r -a KEYARR <<<"ALL ${KEY//|/ }" read -r -a KEYARR <<<"ALL ${KEY//|/ }"
if [ "${FINDKEYS}" = "ALL" ]; then if [ "${FINDKEYS}" = "ALL" ]; then
jssh_deleteKeyDB "${CHAT[ID]}" "${TRACKFILE}" jssh_deleteKeyDB "${CHAT[ID]}" "${TRACKFILE}"
send_markdown_message "${CHAT[ID]}" "*Tracking gelöscht!*" send_markdownv2_message "${CHAT[ID]}" "*Tracking gelöscht!*"
return return
elif [[ "${FINDKEYS}" =~ ^[0-9]+$ ]]; then elif [[ "${FINDKEYS}" =~ ^[0-9]+$ ]]; then
if [ "${#KEYARR[@]}" -lt "${FINDKEYS}" ]; then if [ "${#KEYARR[@]}" -lt "${FINDKEYS}" ]; then
@ -386,7 +243,7 @@ else
FINDKEYS="${KEYARR[*]}" FINDKEYS="${KEYARR[*]}"
if [ -z "${FINDKEYS}" ]; then if [ -z "${FINDKEYS}" ]; then
jssh_deleteKeyDB "${CHAT[ID]}" "${TRACKFILE}" jssh_deleteKeyDB "${CHAT[ID]}" "${TRACKFILE}"
send_markdown_message "${CHAT[ID]}" "*Tracking gelöscht!*" send_markdownv2_message "${CHAT[ID]}" "*Tracking gelöscht!*"
return return
else else
KEY="${OLDKEYS#*!}" KEY="${OLDKEYS#*!}"
@ -395,80 +252,15 @@ else
fi fi
fi fi
else else
OUT="Keys:\n$(printKeys "KEYARR")\n\nSchicke \"/delkey <Nr.>\" zum Löschen." OUT="$(printKeys "KEYARR")\n\nSchicke \"/delkey <Nr.>\" zum Löschen."
# send keyboard in private chats only
if [ "${CHAT[ID]}" != "${USER[ID]}" ]; then if [ "${CHAT[ID]}" != "${USER[ID]}" ]; then
send_normal_message "${CHAT[ID]}" "${OUT}" send_normal_message "${CHAT[ID]}" "${OUT}"
else else
send_keyboard "${CHAT[ID]}" "${OUT}"\ send_keyboard "${CHAT[ID]}" "${OUT}"\
'["/delkey 1","/delkey 2","/delkey 3"],["/delkey 4","/delkey 5","/delkey 6"],["/delkey 7","/delkey 8","/delkey 9"],["/delkey ALL","/delblack","/listtrack"]' '["/delkey 1","/delkey 2","/delkey 3"],["/delkey 4","/delkey 5","/delkey 6"],["/delkey 7","/delkey 8","/delkey 9"],["/delkey ALL","/delblack","/listtrack"]'
fi fi
fi return 1
;;
'/delb'*) #delete black
KEY="${OLDKEYS#*!}"
read -r -a KEYARR <<<"ALL ${KEY//|/ }"
FINDKEYS="${MESSAGE#/* }"
if [ "${KEY}" = "${OLDKEYS}" ]; then
unset FINDKEYS
unset KEYARR
KEYARR[0]="Keine Blacklist"
fi
if [[ "${FINDKEYS}" =~ ^[0-9]+$ ]]; then
if [ "${#KEYARR[@]}" -lt "${FINDKEYS}" ]; then
send_normal_message "${CHAT[ID]}" "Es gibt nur $((${#KEYARR[@]}-1)) Keys, bitte nochmal."
unset "KEYARR[${FINDKEYS}]"
else
send_normal_message "${CHAT[ID]}" "Lösche Black ${KEYARR[${FINDKEYS}]}"
unset "KEYARR[0]"
unset "KEYARR[${FINDKEYS}]"
FINDKEYS="|!${KEYARR[*]}"
[ "${FINDKEYS}" == "|!" ] && FINDKEYS=""
MESSAGE="/newt ${OLDKEYS%%|!*}${FINDKEYS}"
fi
fi
if [[ -z "${FINDKEYS}" || "${FINDKEYS:0:1}" == "/" ]]; then # output list
OUT="Blacklist:\n$(printKeys "KEYARR")\n\nSchicke \"/delblack <Nr.>\" zum Löschen."
if [ "${CHAT[ID]}" != "${USER[ID]}" ]; then
send_normal_message "${CHAT[ID]}" "${OUT}"
else
send_keyboard "${CHAT[ID]}" "${OUT}"\
'["/delblack 1","/delblack 2","/delblack 3"],["/delblack 4","/delblack 5","/delblack 6"],["/delblack 7","/delblack 8","/delblack 9"],["/delblack ALL","/delkey","/listtrack"]'
fi
fi
;;
'/delw'*) #delete watch
KEY="${OLDKEYS}"
FINDKEYS="${MESSAGE#/* }"
read -r -a KEYARR <<<"ALL ${KEY//|/ }"
if [ "${FINDKEYS}" = "ALL" ]; then
jssh_deleteKeyDB "${CHAT[ID]}" "${WATCHFILE}"
send_markdown_message "${CHAT[ID]}" "*Produkt Watch gelöscht!*"
return
elif [[ "${FINDKEYS}" =~ ^[0-9]+$ ]]; then
if [ "${#KEYARR[@]}" -lt "${FINDKEYS}" ]; then
send_normal_message "${CHAT[ID]}" "Es gibt nur $((${#KEYARR[@]}-1)) Keys, bitte nochmal."
unset FINDKEYS
else
send_normal_message "${CHAT[ID]}" "Lösche Key ${KEYARR[${FINDKEYS}]}"
unset "KEYARR[0]"
unset "KEYARR[${FINDKEYS}]"
FINDKEYS="${KEYARR[*]}"
if [ -z "${FINDKEYS}" ]; then
jssh_deleteKeyDB "${CHAT[ID]}" "${WATCHFILE}"
send_markdown_message "${CHAT[ID]}" "*Produkt Watch gelöscht!*"
return
else
MESSAGE="/neww ${FINDKEYS}"
fi
fi
else
OUT="Keys:\n$(printKeys "KEYARR")\n\nSchicke \"/delwatch <Nr.>\" zum Löschen."
if [ "${CHAT[ID]}" != "${USER[ID]}" ]; then
send_normal_message "${CHAT[ID]}" "${OUT}"
else
send_keyboard "${CHAT[ID]}" "${OUT}"\
'["/delwatch 1","/delwatch 2","/delwatch 3"],["/delwatch 4","/delwatch 5","/delwatch 6"],["/delwatch 7","/delwatch 8","/delwatch 9"],["/delwatch ALL","/listwatch"]'
fi
fi fi
;; ;;
esac esac
@ -480,9 +272,9 @@ else
FINDKEYS="${MESSAGE#/* }" FINDKEYS="${MESSAGE#/* }"
if [ "${FINDKEYS}" = "${MESSAGE}" ]; then if [ "${FINDKEYS}" = "${MESSAGE}" ]; then
delete_message "${CHAT[ID]}" "${MESSAGE[ID]}" delete_message "${CHAT[ID]}" "${MESSAGE[ID]}"
send_markdown_message "${CHAT[ID]}" "${bashbot_shelp}" send_markdownv2_message "${CHAT[ID]}" "${bashbot_shelp}"
else else
if user_is_admin "${CHAT[ID]}" "${USER[ID]}" ; then if user_is_admin "${CHAT[ID]}" "${USER[ID]}" || user_is_allowed "${USER[ID]}" "search" "${CHAT[ID]}"; then
set_keys "${FINDKEYS}" "${SEARCHFILE}" set_keys "${FINDKEYS}" "${SEARCHFILE}"
else else
send_normal_message "${CHAT[ID]}" "${SORRYADMIN}" send_normal_message "${CHAT[ID]}" "${SORRYADMIN}"
@ -491,15 +283,15 @@ else
return 1 return 1
fi fi
fi fi
return return 1
;; ;;
'/newt'*) # newtrack '/newt'*) # newtrack
FINDKEYS="${MESSAGE#/* }" FINDKEYS="${MESSAGE#/* }"
FINDKEYS="${FINDKEYS%[\" ]}" FINDKEYS="${FINDKEYS%[\" ]}"
FINDKEYS="${FINDKEYS#[\" ]}" FINDKEYS="${FINDKEYS#[\" ]}"
if [ "${FINDKEYS}" = "${MESSAGE}" ]; then if [ "${FINDKEYS}" = "" ]; then
send_markdown_message "${CHAT[ID]}" "${bashbot_shelp}" send_markdownv2_message "${CHAT[ID]}" "${bashbot_shelp}"
else else
set_keys "${FINDKEYS}" "${TRACKFILE}" set_keys "${FINDKEYS}" "${TRACKFILE}"
fi fi
@ -508,181 +300,66 @@ else
send_action "${CHAT[ID]}" "typing" send_action "${CHAT[ID]}" "typing"
FINDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${TRACKFILE}")" FINDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${TRACKFILE}")"
if [ "${FINDKEYS}" = "" ]; then if [ "${FINDKEYS}" = "" ]; then
send_markdown_message "${CHAT[ID]}" "*Kein Tracking aktiv!*" send_markdownv2_message "${CHAT[ID]}" "*Kein Tracking aktiv!*"
return return
fi fi
OUT="Tracking nach \"${FINDKEYS}\" ist aktiv." OUT="Tracking nach \"${FINDKEYS}\" ist aktiv."
# send keyboard in private chats only
if [[ "${CHAT[ID]}" != "${USER[ID]}" ]]; then if [[ "${CHAT[ID]}" != "${USER[ID]}" ]]; then
send_normal_message "${CHAT[ID]}" "${OUT}" send_normal_message "${CHAT[ID]}" "${OUT}"
else else
send_keyboard "${CHAT[ID]}" "${OUT}"\ send_keyboard "${CHAT[ID]}" "${OUT}"\
'["/delkey 1","/delkey 2","/delkey 3"],["/delkey 4","/delkey 5","/delblack 6"],["/delblack 1","/delblack 2","/delblack 3"],["/delkey","/delblack","/listtrack"]' '["/delkey 1","/delkey 2","/delkey 3"],["/delkey 4","/delkey 5","/delkey 6"],["/delkey 7","/delkey 8","/delkey 9"],["/delkey ALL","/delblack","/listtrack"]'
fi fi
return return 1
;; ;;
'/neww'*) # newwatch
FINDKEYS="${MESSAGE#/* }"
FINDKEYS="${FINDKEYS%[\" ]}"
FINDKEYS="${FINDKEYS#[\" ]}"
if [ "${FINDKEYS}" = "${MESSAGE}" ]; then
send_markdown_message "${CHAT[ID]}" "${bashbot_shelp}"
else
set_keys "${FINDKEYS}" "${WATCHFILE}"
fi
;&
'/listw'*) # listwatch
send_action "${CHAT[ID]}" "typing"
FINDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${WATCHFILE}")"
if [ "${FINDKEYS}" = "" ]; then
send_markdown_message "${CHAT[ID]}" "*Kein Produkt Watch aktiv!*"
return
fi
OUT="Produkt Watch nach \"${FINDKEYS}\" ist aktiv."
if [[ "${CHAT[ID]}" != "${USER[ID]}" ]]; then
send_normal_message "${CHAT[ID]}" "${OUT}"
else
send_keyboard "${CHAT[ID]}" "${OUT}"\
'["/delwatch 1","/delwatch 2","/delwatch 3"],["/delwatch 4","/delwatch 5","/delwatch 6"],["/delwatch 7","/delwatch 8","/delwatch 9"],["/delwatch","/delwatch ALL","/listwatch"]'
fi
return
;;
'/newn'*) # newnotify
FINDKEYS="${MESSAGE#/* }"
FINDKEYS="${FINDKEYS%[\" ]}"
FINDKEYS="${FINDKEYS#[\" ]}"
if [ "${FINDKEYS}" = "${MESSAGE}" ]; then
send_markdown_message "${CHAT[ID]}" "${bashbot_shelp}"
else
set_keys "${FINDKEYS}" "${NOTIFYFILE}"
fi
;&
'/listn'*) # listnotify
send_action "${CHAT[ID]}" "typing"
FINDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${NOTIFYFILE}")"
if [ "${FINDKEYS}" = "" ]; then
send_markdown_message "${CHAT[ID]}" "*Kein Produkt Notify aktiv!*"
return
fi
OUT="Produkt Notify nach \"${FINDKEYS}\" ist aktiv."
send_normal_message "${CHAT[ID]}" "${OUT}"
return
;;
#############################
# botadmin only commands
'/listat'*) # listalltrack
jssh_readDB "SEARCHVALUES" "${TRACKFILE}"
FINDKEYS="$(jssh_printDB "SEARCHVALUES")"
if [ "${FINDKEYS}" != "" ]; then
# shellcheck disable=SC2126
send_action "${CHAT[ID]}" "typing"
send_normal_message "${CHAT[ID]}" "All Suchaufträge:\n${FINDKEYS}"
else
send_markdown_message "${CHAT[ID]}" "*Kein Tracking aktiv!*"
fi
;;
'/listaw'*) # listall watch
jssh_readDB "SEARCHVALUES" "${WATCHFILE}"
FINDKEYS="$(jssh_printDB "SEARCHVALUES")"
if [ "${FINDKEYS}" != "" ]; then
send_action "${CHAT[ID]}" "typing"
send_normal_message "${CHAT[ID]}" "Alle Watchaufträge:\n${FINDKEYS}"
else
send_markdown_message "${CHAT[ID]}" "*Kein Produkt Watch aktiv!*"
fi
return
;;
'/delu'*) # delusersearch
KEY="${MESSAGE#/* }"; KEY="${KEY#%% *}"
if [ "${KEY}" = "${MESSAGE}" ] || [ "${KEY}" = "" ] ; then
jssh_readDB "SEARCHVALUES" "${TRACKFILE}"
FINDKEYS="$(jssh_printDB "SEARCHVALUES")"
if [ "${FINDKEYS}" != "" ]; then
send_normal_message "${CHAT[ID]}"\
"Aktive Suchaufträge:\n${FINDKEYS}\n\nSende \"/deluser ID\" zum Löschen eines Users"
else
send_markdown_message "${CHAT[ID]}" "*Kein Tracking aktiv!*"; exit
fi
exit
fi
jssh_deleteKeyDB "${KEY}" "${TRACKFILE}"
send_normal_message "${CHAT[ID]}" "Lösche Suchauftrag User ${KEY}"
jssh_readDB "SEARCHVALUES" "${TRACKFILE}"
FINDKEYS="$(jssh_printDB "SEARCHVALUES")"
if [ "${FINDKEYS}" != "" ]; then
send_normal_message "${CHAT[ID]}" "Verbliebene Suchaufträge:\n${FINDKEYS}"
else
send_markdown_message "${CHAT[ID]}" "*Kein Tracking aktiv!*"; exit
fi
return
;;
esac esac
} }
fi fi
# debug function called on start, stop of bot, interactive and background processes
# if your bot was started with debug as second argument
# $1 current date, $2 from where the function wqs called, $3 ... $n optional information
my_debug_checks() {
# example check because my bot creates a wrong file, this was becuase an empty variable
[ -f ".jssh" ] && printf "%s: %s\n" "${1}" "Ups, found file \"${PWD:-.}/.jssh\"! =========="
}
# called when bashbot sedn command failed because we can not connect to telegram
# return 0 to retry, return non 0 to give up
bashbotBlockRecover() {
# place your commnds to unblock here, e.g. change IP or simply wait
sleep 60 && return 0 # may be temporary
return 1
}
# place your processing functions here # place your processing functions here
set_keys(){ set_keys(){
local MYFIND MYKEY MYKEYF MINLEN MYCHECK MYSEARCH local MYFIND MYKEY MYKEYF MINLEN MYSEARCH
declare -A KEYARR declare -A KEYARR
MYFIND="$1" MYFIND="$1"
MYKEYF="$2" MYKEYF="$2"
MINLEN="3" MINLEN="4"
# check len of keys # check len of keys
for MYKEY in ${MYFIND}; do [ "${#MYKEY}" -lt ${MINLEN} ] && break; done for MYKEY in ${MYFIND}; do [ "${#MYKEY}" -lt ${MINLEN} ] && break; done
if [ "${#MYKEY}" -lt ${MINLEN} ]; then if [ "${#MYKEY}" -lt ${MINLEN} ]; then
send_markdown_message "${CHAT[ID]}" "*Ein Suchbegriff ist kürzer als ${MINLEN} Zeichen!*" send_markdownv2_message "${CHAT[ID]}" "*Ein Suchbegriff ist kürzer als ${MINLEN} Zeichen!*"
else else
MYFIND="$(create_pattern "${MYFIND}")" MYFIND="$(create_pattern "${MYFIND}")"
MYCHECK="$(check_pattern "${MYFIND}")"
[[ "${MESSAGE}" == "/s"* ]] &&\ [[ "${MESSAGE}" == "/s"* ]] &&\
send_normal_message "${CHAT[ID]}" "${MYCHECK}Suche nach \"${MYFIND//|/ }\" wird gestartet ..." send_normal_message "${CHAT[ID]}" "Suche nach \"${MYFIND//|/ }\" wird gestartet ..."
MYKEY="${MYFIND//[^|]}" MYKEY="${MYFIND//[^|]}"
if [ "${#MYKEY}" -gt 49 ]; then if [ "${#MYKEY}" -gt 49 ]; then
send_markdown_message "${CHAT[ID]}" "*Maximale Anzahl von 50 Begriffen erreicht!*" send_markdownv2_message "${CHAT[ID]}" "*Maximale Anzahl von 50 Begriffen erreicht!*"
elif [ "${MYFIND}" != "" ]; then elif [ "${MYFIND}" != "" ]; then
KEYARR["${CHAT[ID]}"]="${MYFIND}" KEYARR["${CHAT[ID]}"]="${MYFIND}"
jssh_updateDB "KEYARR" "${MYKEYF}" jssh_updateDB "KEYARR" "${MYKEYF}"
#jssh_insertDB "${CHAT[ID]}" "${MYFIND}" "${MYKEYF}"
else else
send_markdown_message "${CHAT[ID]}" "*Ein Begriff ist ungültig, z.B. \" , oder leer!*" send_markdownv2_message "${CHAT[ID]}" "*Ein Begriff ist ungültig, z.B. \" , oder leer!*"
fi fi
fi fi
} }
# place your processing functions here # place your processing functions here
# $1 ARRAYNAME to print
# $1 ARRAYNAME $2 command printKeys() {
printKeys() {
local key local key
declare -n ARRAY="$1" declare -n ARRAY="$1"
for key in "${!ARRAY[@]}" for key in "${!ARRAY[@]}"
do do
printf '%s - %s\n' "${key}" "${ARRAY[${key}]}" printf '%s - %s\n' "${key}" "${ARRAY[${key}]}"
done done
} }
# create a regex from space sepeareted keywords
# $1 space separated words # create a regex from space sepeareted keywords
create_pattern() { # $1 space separated words
create_pattern() {
local PATTERN KEY local PATTERN KEY
set -f set -f
for KEY in $1 for KEY in $1
@ -690,28 +367,7 @@ fi
[ "${PATTERN}" != "" ] && PATTERN="${PATTERN}|" [ "${PATTERN}" != "" ] && PATTERN="${PATTERN}|"
PATTERN="${PATTERN}${KEY}" PATTERN="${PATTERN}${KEY}"
done done
# revome blank and "
PATTERN="${PATTERN//[\" ]}"
# remove * at start
PATTERN="${PATTERN//|\*/|}"; PATTERN="${PATTERN#\*}"
# remove unneeded |
PATTERN="${PATTERN//||/|}"; PATTERN="${PATTERN#|}"; PATTERN="${PATTERN%|}"
set +f set +f
echo "${PATTERN}" echo "${PATTERN}"
} }
# check regex for common errors
# ¤1 pattern
check_pattern() {
local WARN=""
if [[ "$1" =~ ([^.\)]\*)|(^\*) ]]; then
WARN+="Meintest du evtl. '.*' ? '*' ist vorheriges Zeichen beliebig oft. "$'\n\r'
fi
if [[ "$1" =~ (^\*)|(^.\*)|([^\)]\*\|)|(\|\*)|(\|\.\*)|([^\)]\*$) ]] ; then
WARN+="Ein '.*' oder '*' an Anfang oder End ist unnötig. "$'\n\r'
fi
if [[ "$1" =~ \([^|\)]*\| ]] ; then
WARN+="Öffnende '(' ohne ')' gefunden. Klammerausdruck muss vor '|' geschlossen sein. "$'\n\r'
fi
[ -n "${WARN}" ] && printf "Potentielle Fehlerquellen:\n\r%s\n\r" "${WARN}"
}

View File

@ -4,7 +4,7 @@
# #
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
###### ######
# parameters # parameters

View File

@ -5,7 +5,7 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
###### ######
# parameters # parameters
@ -24,7 +24,7 @@ export 'LANGUAGE=C.UTF-8'
unset IFS unset IFS
# set -f # if you are paranoid use set -f to disable globbing # set -f # if you are paranoid use set -f to disable globbing
echo "Why hello there. echo "Hi, hello there.
Would you like some tea (y/n)?" Would you like some tea (y/n)?"
read -r answer <"${INPUT}" read -r answer <"${INPUT}"
[[ $answer =~ ^([yY][eE][sS]|[yY])$ ]] && echo "OK then, here you go: http://www.rivertea.com/blog/wp-content/uploads/2013/12/Green-Tea.jpg" || echo "OK then." [[ $answer =~ ^([yY][eE][sS]|[yY])$ ]] && echo "OK then, here you go: http://www.rivertea.com/blog/wp-content/uploads/2013/12/Green-Tea.jpg" || echo "OK then."
@ -34,7 +34,7 @@ until [ "$SUCCESS" = "y" ] ;do
case $answer in case $answer in
'Yass!') echo "Goody! mykeyboardendshere";SUCCESS=y;; 'Yass!') echo "Goody! mykeyboardendshere";SUCCESS=y;;
'No') echo "Well that's weird. mykeyboardendshere";SUCCESS=y;; 'No') echo "Well that's weird. mykeyboardendshere";SUCCESS=y;;
'') echo "empty answer!" && exit ;; '') echo "empty answer! Try again";;
*) SUCCESS=n;; *) SUCCESS=n;;
esac esac
done done

View File

@ -1,7 +1,7 @@
# file: botacl # file: botacl
# a user not listed here, will return false from 'user_is_allowed' # a user not listed here, will return false from 'user_is_allowed'
# #
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# Format: # Format:
# user:resource:chat # user:resource:chat

View File

@ -5,7 +5,7 @@
# to show how you can customize bashbot by only editing mycommands.sh # to show how you can customize bashbot by only editing mycommands.sh
# NOTE: this is not tested, simply copied from original source and reworked! # NOTE: this is not tested, simply copied from original source and reworked!
# #
#### $$VERSION$$ v1.2-dev-13-g2a5d47d #### $$VERSION$$ v1.20-0-g2ab00a2
# #
# shellcheck disable=SC2154 # shellcheck disable=SC2154
# shellcheck disable=SC2034 # shellcheck disable=SC2034

View File

@ -5,7 +5,7 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# #
# will be automatically sourced from bashbot # will be automatically sourced from bashbot

View File

@ -5,7 +5,7 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# will be automatically sourced from bashbot # will be automatically sourced from bashbot

View File

@ -5,7 +5,8 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.0-0-g99217c4 # shellcheck disable=SC1117
#### $$VERSION$$ v1.20-0-g2ab00a2
# will be automatically sourced from bashbot # will be automatically sourced from bashbot

View File

@ -5,7 +5,7 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.2-dev-14-g6ec00d4 #### $$VERSION$$ v1.20-0-g2ab00a2
# will be automatically sourced from bashbot # will be automatically sourced from bashbot
@ -18,6 +18,7 @@ UNBAN_URL=$URL'/unbanChatMember'
GETMEMBER_URL=$URL'/getChatMember' GETMEMBER_URL=$URL'/getChatMember'
# usage: status="$(get_chat_member_status "chat" "user")" # usage: status="$(get_chat_member_status "chat" "user")"
# $1 chat # $2 user
get_chat_member_status() { get_chat_member_status() {
sendJson "$1" '"user_id":'"$2"'' "$GETMEMBER_URL" sendJson "$1" '"user_id":'"$2"'' "$GETMEMBER_URL"
# shellcheck disable=SC2154 # shellcheck disable=SC2154
@ -42,7 +43,14 @@ user_is_creator() {
return 1 return 1
} }
# $1 chat
bot_is_admin() {
user_is_admin "$1" "$(getConfigKey "botid")"
}
# $1 chat # $2 user
user_is_admin() { user_is_admin() {
[[ -z "$1" || -z "$2" ]] && return 1
[ "${1:--}" == "${2:-+}" ] && return 0 [ "${1:--}" == "${2:-+}" ] && return 0
user_is_botadmin "$2" && return 0 user_is_botadmin "$2" && return 0
local me; me="$(get_chat_member_status "$1" "$2")" local me; me="$(get_chat_member_status "$1" "$2")"
@ -50,7 +58,9 @@ user_is_admin() {
return 1 return 1
} }
# $1 user
user_is_botadmin() { user_is_botadmin() {
[ -z "$1" ] && return 1
local admin; admin="$(getConfigKey "botadmin")"; [ -z "${admin}" ] && return 1 local admin; admin="$(getConfigKey "botadmin")"; [ -z "${admin}" ] && return 1
[[ "${admin}" == "${1}" || "${admin}" == "${2}" ]] && return 0 [[ "${admin}" == "${1}" || "${admin}" == "${2}" ]] && return 0
#[[ "${admin}" = "@*" ]] && [[ "${admin}" = "${2}" ]] && return 0 #[[ "${admin}" = "@*" ]] && [[ "${admin}" = "${2}" ]] && return 0
@ -58,6 +68,7 @@ user_is_botadmin() {
return 1 return 1
} }
# $1 user # $2 key # $3 chat
user_is_allowed() { user_is_allowed() {
[ -z "$1" ] && return 1 [ -z "$1" ] && return 1
# user can do everything # user can do everything

View File

@ -5,7 +5,7 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# #
# source from commands.sh to use jsonDB functions # source from commands.sh to use jsonDB functions
# #
@ -204,7 +204,7 @@ jssh_checkDB_async() { jssh_checkDB "$@"; }
jssh_checkDB(){ jssh_checkDB(){
local DB local DB
[ -z "$1" ] && return 1 [ -z "$1" ] && return 1
[[ "$1" = *'..'* ]] && return 2 [[ "$1" = *'../.'* ]] && return 2
if [[ "$1" == "${BASHBOT_VAR:-.}"* ]] || [[ "$1" == "${BASHBOT_DATA:-.}"* ]]; then if [[ "$1" == "${BASHBOT_VAR:-.}"* ]] || [[ "$1" == "${BASHBOT_DATA:-.}"* ]]; then
DB="${1}.jssh" DB="${1}.jssh"
else else
@ -296,7 +296,7 @@ jssh_countKeyDB_async() {
fi fi
} }
# updatie key/value in place to jsshDB # update key/value in place to jsshDB
# $1 key name, can only contain -a-zA-Z0-9,._ # $1 key name, can only contain -a-zA-Z0-9,._
# $2 key value # $2 key value
# $3 filename (must exist!), must be relative to BASHBOT_ETC, and not contain '..' # $3 filename (must exist!), must be relative to BASHBOT_ETC, and not contain '..'

View File

@ -5,7 +5,8 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.1-0-gc0eb399 # shellcheck disable=SC1117
#### $$VERSION$$ v1.20-0-g2ab00a2
# will be automatically sourced from bashbot # will be automatically sourced from bashbot
@ -15,6 +16,7 @@ eval "$(basename "${BASH_SOURCE[0]}")(){ :; }"
# source from commands.sh to use the sendMessage functions # source from commands.sh to use the sendMessage functions
MSG_URL=$URL'/sendMessage' MSG_URL=$URL'/sendMessage'
EDIT_URL=$URL'/editMessageText'
PHO_URL=$URL'/sendPhoto' PHO_URL=$URL'/sendPhoto'
AUDIO_URL=$URL'/sendAudio' AUDIO_URL=$URL'/sendAudio'
DOCUMENT_URL=$URL'/sendDocument' DOCUMENT_URL=$URL'/sendDocument'
@ -27,6 +29,10 @@ ACTION_URL=$URL'/sendChatAction'
FORWARD_URL=$URL'/forwardMessage' FORWARD_URL=$URL'/forwardMessage'
ALBUM_URL=$URL'/sendMediaGroup' ALBUM_URL=$URL'/sendMediaGroup'
#
# send/edit message variants ------------------
#
# $1 CHAT $2 message # $1 CHAT $2 message
send_normal_message() { send_normal_message() {
local len text; text="$(JsonEscape "${2}")" local len text; text="$(JsonEscape "${2}")"
@ -47,54 +53,70 @@ send_normal_message() {
# $1 CHAT $2 message # $1 CHAT $2 message
send_markdown_message() { send_markdown_message() {
local text; text="$(JsonEscape "${2}")" _format_message_url "${1}" "${2}" ',"parse_mode":"markdown"' "${MSG_URL}"
text="${text//$'\n'/\\n}"
[ "${#text}" -ge 4096 ] && log_error "Warning: markdown message longer than 4096 characters, message is rejected if formatting crosses 4096 border."
until [ -z "${text}" ]; do
sendJson "${1}" '"text":"'"${text:0:4096}"'","parse_mode":"markdown"' "${MSG_URL}"
text="${text:4096}"
done
} }
# $1 CHAT $2 message # $1 CHAT $2 message
send_markdownv2_message() { send_markdownv2_message() {
local text; text="$(JsonEscape "${2}")" _markdownv2_message_url "${1}" "${2}" ',"parse_mode":"markdownv2"' "${MSG_URL}"
text="${text//$'\n'/\\n}"
[ "${#text}" -ge 4096 ] && log_error "Warning: markdown 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")"
until [ -z "${text}" ]; do
sendJson "${1}" '"text":"'"${text:0:4096}"'","parse_mode":"markdownv2"' "${MSG_URL}"
text="${text:4096}"
done
} }
# $1 CHAT $2 message # $1 CHAT $2 message
send_html_message() { send_html_message() {
_format_message_url "${1}" "${2}" ',"parse_mode":"html"' "${MSG_URL}"
}
# $1 CHAT $2 msg-id $3 message
edit_normal_message() {
_format_message_url "${1}" "${3}" ',"message_id":'"${2}"'' "${EDIT_URL}"
}
# $1 CHAT $2 msg-id $3 message
edit_markdown_message() {
_format_message_url "${1}" "${3}" ',"message_id":'"${2}"',"parse_mode":"markdown"' "${EDIT_URL}"
}
# $1 CHAT $2 msg-id $3 message
edit_markdownv2_message() {
_markdownv2_message_url "${1}" "${3}" ',"message_id":'"${2}"',"parse_mode":"markdownv2"' "${EDIT_URL}"
}
# $1 CHAT $2 msg-id $3 message
edit_html_message() {
_format_message_url "${1}" "${3}" ',"message_id":'"${2}"',"parse_mode":"html"' "${EDIT_URL}"
}
# internal function, send/edit formatted message with parse_mode and URL
# $1 CHAT $2 message $3 action $4 URL
_format_message_url(){
local text; text="$(JsonEscape "${2}")" local text; text="$(JsonEscape "${2}")"
text="${text//$'\n'/\\n}" text="${text//$'\n'/\\n}"
[ "${#text}" -ge 4096 ] && log_error "Warning: html message longer than 4096 characters, message is rejected if formatting crosses 4096 border." [ "${#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 until [ -z "${text}" ]; do
sendJson "${1}" '"text":"'"${text:0:4096}"'","parse_mode":"html"' "${MSG_URL}" sendJson "${1}" '"text":"'"${text:0:4096}"'"'"${3}"'' "${4}"
text="${text:4096}" text="${text:4096}"
done done
} }
# obsolote, will be removed after 1.0!! # internal function, send/edit markdownv2 message with URL
# $1 CHAT $2 message $3 keyboard # $1 CHAT $2 message $3 action $4 URL
old_send_keyboard() { _markdownv2_message_url() {
local text; text='"text":"'$(JsonEscape "${2}")'"' local text; text="$(JsonEscape "${2}")"
shift 2 text="${text//$'\n'/\\n}"
local keyboard="init" [ "${#text}" -ge 4096 ] && log_error "Warning: markdownv2 message longer than 4096 characters, message is rejected if formatting crosses 4096 border."
OLDIFS="$IFS" # markdown v2 needs additional double escaping!
IFS="\"" text="$(sed -E -e 's|([_|~`>+=#{}()!.-])|\\\1|g' <<< "$text")"
for f in "$@" ;do [ "$f" != " " ] && keyboard="$keyboard, [\"$f\"]";done until [ -z "${text}" ]; do
IFS="$OLDIFS" sendJson "${1}" '"text":"'"${text:0:4096}"'"'"${3}"'' "${4}"
keyboard="${keyboard/init, /}" text="${text:4096}"
sendJson "${1}" "${text}"', "reply_markup": {"keyboard": [ '"${keyboard}"' ],"one_time_keyboard": true}' "$MSG_URL" done
send_normal_message "$(getConfigKey "botadmin")" "Warning: old 'send_keyboard' format is deprecated since version 0.6 and will be removed after 1.0 release!"
} }
#
# send keyboard, buttons, files ---------------
#
# $1 CHAT $2 message $3 keyboard # $1 CHAT $2 message $3 keyboard
send_keyboard() { send_keyboard() {
if [[ "$3" != *'['* ]]; then old_send_keyboard "${@}"; return; fi if [[ "$3" != *'['* ]]; then old_send_keyboard "${@}"; return; fi
@ -168,7 +190,7 @@ else
fi fi
upload_file(){ upload_file(){
local CUR_URL WHAT STATUS file="$2" local CUR_URL WHAT STATUS text=$3 file="$2"
# file access checks ... # file access checks ...
[[ "$file" = *'..'* ]] && return # no directory traversal [[ "$file" = *'..'* ]] && return # no directory traversal
[[ "$file" = '.'* ]] && return # no hidden or relative files [[ "$file" = '.'* ]] && return # no hidden or relative files
@ -214,7 +236,7 @@ upload_file(){
;; ;;
esac esac
send_action "${1}" "$STATUS" send_action "${1}" "$STATUS"
sendUpload "$1" "${WHAT}" "${file}" "${CUR_URL}" "$3" sendUpload "$1" "${WHAT}" "${file}" "${CUR_URL}" "${text//\\n/$'\n'}"
} }
# typing for text messages, upload_photo for photos, record_video or upload_video for videos, record_audio or upload_audio for audio files, upload_document for general files, find_location for location # typing for text messages, upload_photo for photos, record_video or upload_video for videos, record_audio or upload_audio for audio files, upload_document for general files, find_location for location
@ -238,6 +260,10 @@ send_venue() {
} }
#
# other send message variants ---------------------------------
#
# $1 CHAT $2 from chat $3 from msg id # $1 CHAT $2 from chat $3 from msg id
forward_message() { forward_message() {
[ -z "$3" ] && return [ -z "$3" ] && return
@ -253,7 +279,7 @@ send_message() {
local text keyboard btext burl no_keyboard file lat long title address sent local text keyboard btext burl no_keyboard file lat long title address sent
text="$(sed <<< "${2}" 's/ mykeyboardend.*//;s/ *my[kfltab][a-z]\{2,13\}startshere.*//')$(sed <<< "${2}" -n '/mytextstartshere/ s/.*mytextstartshere//p')" text="$(sed <<< "${2}" 's/ mykeyboardend.*//;s/ *my[kfltab][a-z]\{2,13\}startshere.*//')$(sed <<< "${2}" -n '/mytextstartshere/ s/.*mytextstartshere//p')"
#shellcheck disable=SC2001 #shellcheck disable=SC2001
text="$(sed <<< "${text}" 's/ *mynewlinestartshere */\\n/g')" text="$(sed <<< "${text}" 's/ *mynewlinestartshere */\n/g')"
text="${text//$'\n'/\\n}" text="${text//$'\n'/\\n}"
[ "$3" != "safe" ] && { [ "$3" != "safe" ] && {
no_keyboard="$(sed <<< "${2}" '/mykeyboardendshere/!d;s/.*mykeyboardendshere.*/mykeyboardendshere/')" no_keyboard="$(sed <<< "${2}" '/mykeyboardendshere/!d;s/.*mykeyboardendshere.*/mykeyboardendshere/')"
@ -282,7 +308,7 @@ send_message() {
sent=y sent=y
fi fi
if [ -n "$file" ]; then if [ -n "$file" ]; then
send_file "$1" "$file" "$text" upload_file "$1" "$file" "$text"
sent=y sent=y
fi fi
if [ -n "$lat" ] && [ -n "$long" ]; then if [ -n "$lat" ] && [ -n "$long" ]; then

View File

@ -8,7 +8,8 @@
# #### if you start to develop your own bot, use the clean version of this file: # #### if you start to develop your own bot, use the clean version of this file:
# #### mycommands.clean # #### mycommands.clean
# #
#### $$VERSION$$ v1.1-0-gc0eb399 # shellcheck disable=SC1117
#### $$VERSION$$ v1.20-0-g2ab00a2
# #
# uncomment the following lines to overwrite info and help messages # uncomment the following lines to overwrite info and help messages
@ -24,6 +25,11 @@ export res=""
# Set INLINE to 1 in order to receive inline queries. # Set INLINE to 1 in order to receive inline queries.
# To enable this option in your bot, send the /setinline command to @BotFather. # To enable this option in your bot, send the /setinline command to @BotFather.
export INLINE="0" export INLINE="0"
# if your bot is group admin it get commands sent to other bots
# Set MEONLY to 1 to ignore commands sent to other bots
export MEONLY="0"
# Set to .* to allow sending files from all locations # Set to .* to allow sending files from all locations
# NOTE: this is a regex, not shell globbing! you must use a valid egex, # NOTE: this is a regex, not shell globbing! you must use a valid egex,
# '.' matches any character and '.*' matches all remaining charatcers! # '.' matches any character and '.*' matches all remaining charatcers!
@ -111,13 +117,13 @@ else
# example for actions based on chat or sender # example for actions based on chat or sender
case "${USER[ID]}+${CHAT[ID]}" in case "${USER[ID]}+${CHAT[ID]}" in
'USERID+'*) # do something for all messages from USER 'USERID1+'*) # do something for all messages from USER
printf "%s: U=%s C=%s M=%s\n" "$(date)" "${USER[ID]}" "${CHAT[ID]}" "${MESSAGE}" >>"${DATADIR}/${USER[ID]}.log" printf "%s: U=%s C=%s M=%s\n" "$(date)" "${USER[ID]}" "${CHAT[ID]}" "${MESSAGE}" >>"${DATADIR}/${USER[ID]}.log"
;;& ;;&
*'+CHATID') # do something for all messages from CHAT *'+CHATID1') # do something for all messages from CHAT
printf "%s: U=%s C=%s M=%s\n" "$(date)" "${USER[ID]}" "${CHAT[ID]}" "${MESSAGE}" >>"${DATADIR}/${CHAT[ID]}.log" printf "%s: U=%s C=%s M=%s\n" "$(date)" "${USER[ID]}" "${CHAT[ID]}" "${MESSAGE}" >>"${DATADIR}/${CHAT[ID]}.log"
;;& ;;&
'USERID+CHATID') # do something only for messages form USER in CHAT 'USERID2+CHATID2') # do something only for messages form USER in CHAT
printf "%s: U=%s C=%s M=%s\n" "$(date)" "${USER[ID]}" "${CHAT[ID]}" "${MESSAGE}" >>"${DATADIR}/${CHAT[ID]}+${USER[ID]}.log" printf "%s: U=%s C=%s M=%s\n" "$(date)" "${USER[ID]}" "${CHAT[ID]}" "${MESSAGE}" >>"${DATADIR}/${CHAT[ID]}+${USER[ID]}.log"
;;& ;;&
esac esac
@ -138,7 +144,7 @@ else
'/echo'*) '/echo'*)
send_action "${CHAT[ID]}" "typing" send_action "${CHAT[ID]}" "typing"
if ! user_is_botadmin "${USER[ID]}" ; then if ! user_is_botadmin "${USER[ID]}" ; then
send_markdown_message "${CHAT[ID]}" "*${NOTBOTADMIN}*"; return 1 send_markdownv2_message "${CHAT[ID]}" "*${NOTBOTADMIN}*"; return 1
fi fi
;; ;;
# will we process edited messages also? # will we process edited messages also?
@ -148,7 +154,7 @@ else
MESSAGE="${MESSAGE#/* }" MESSAGE="${MESSAGE#/* }"
;; ;;
'/_new_chat_member'*) '/_new_chat_member'*)
if [[ -n "${WELCOME_NEWMEMBER}" && "${NEWMEMBER[ISBOT]}" != "true" ]]; then if [[ -n "${WELCOME_NEWMEMBER}" && "${NEWMEMBER[ISBOT]}" != "true" ]] && bot_is_admin "${CHAT[ID]}"; then
send_normal_message "${CHAT[ID]}"\ send_normal_message "${CHAT[ID]}"\
"${WELCOME_MSG} ${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]} (@${NEWMEMBER[USERNAME]})" "${WELCOME_MSG} ${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]} (@${NEWMEMBER[USERNAME]})"
MYSENTID="${BOTSENT[ID]}" MYSENTID="${BOTSENT[ID]}"
@ -161,6 +167,11 @@ else
[ -n "${REPORT_LEFTMEMBER}" ] && send_normal_message "$(getConfigKey "botadmin")"\ [ -n "${REPORT_LEFTMEMBER}" ] && send_normal_message "$(getConfigKey "botadmin")"\
"Left member: ${CHAT[TITLE]} (${CHAT[ID]}): ${LEFTMEMBER[FIRST_NAME]} ${LEFTMEMBER[LAST_NAME]} (@${LEFTMEMBER[USERNAME]})" "Left member: ${CHAT[TITLE]} (${CHAT[ID]}): ${LEFTMEMBER[FIRST_NAME]} ${LEFTMEMBER[LAST_NAME]} (@${LEFTMEMBER[USERNAME]})"
;; ;;
'/_migrate_group'*)
# call group migration function if provided
_exec_if_function my_migrate_group "${MIGRATE[FROM]}" "${MIGRATE[TO]}"
;;
esac esac
case "${MESSAGE}" in case "${MESSAGE}" in
@ -172,7 +183,7 @@ else
'/question'*) # start interactive questions '/question'*) # start interactive questions
checkproc checkproc
if [ "$res" -gt 0 ] ; then if [ "$res" -gt 0 ] ; then
startproc "examples/question.sh" || _message "Can't start question." startproc "examples/question.sh" || send_normal_message "${CHAT[ID]}" "Can't start question."
else else
send_normal_message "${CHAT[ID]}" "$MESSAGE already running ..." send_normal_message "${CHAT[ID]}" "$MESSAGE already running ..."
fi fi
@ -180,12 +191,16 @@ else
'/cancel'*) # cancel interactive command '/cancel'*) # cancel interactive command
checkproc checkproc
if [ "$res" -gt 0 ] ;then killproc && _message "Command canceled.";else _message "No command is currently running.";fi if [ "$res" -gt 0 ] ;then
killproc && send_normal_message "${CHAT[ID]}" "Command canceled."
else
send_normal_message "${CHAT[ID]}" "No command is currently running."
fi
;; ;;
'/run_notify'*) # start notify background job '/run_notify'*) # start notify background job
myback="notify"; checkback "$myback" myback="notify"; checkback "$myback"
if [ "$res" -gt 0 ] ; then if [ "$res" -gt 0 ] ; then
background "examples/notify.sh 60" "$myback" || _message "Can't start notify." background "examples/notify.sh 60" "$myback" || send_normal_message "${CHAT[ID]}" "Can't start notify."
else else
send_normal_message "${CHAT[ID]}" "Background command $myback already running ..." send_normal_message "${CHAT[ID]}" "Background command $myback already running ..."
fi fi
@ -207,7 +222,7 @@ else
return 0 return 0
;; ;;
'/kickme'*) # this will replace the /kickme command '/kickme'*) # this will replace the /kickme command
send_markdown_mesage "${CHAT[ID]}" "*This bot will not kick you!*" send_markdownv2_mesage "${CHAT[ID]}" "This bot will *not* kick you!"
return 1 return 1
;; ;;
esac esac
@ -275,7 +290,9 @@ else
# return 0 to retry, return non 0 to give up # return 0 to retry, return non 0 to give up
bashbotBlockRecover() { bashbotBlockRecover() {
# place your commands to unblock here, e.g. change IP or simply wait # place your commands to unblock here, e.g. change IP or simply wait
sleep 60 && return 0 # may be temporary sleep 60 # may be temporary
# check connection working
[ -n "$(getJson "${ME_URL}")" ] && return 0
return 1 return 1
} }

View File

@ -4,7 +4,7 @@
# files: mycommands.sh.clean # files: mycommands.sh.clean
# copy to mycommands.sh and add all your commands and functions here ... # copy to mycommands.sh and add all your commands and functions here ...
# #
#### $$VERSION$$ v1.1-0-gc0eb399 #### $$VERSION$$ v1.20-0-g2ab00a2
# #
########## ##########
@ -21,6 +21,10 @@ export res=""
# To enable this option in your bot must also send the /setinline command to @BotFather. # To enable this option in your bot must also send the /setinline command to @BotFather.
export INLINE="0" export INLINE="0"
# if your bot is group admin it get commands sent to other bots
# Set MEONLY to 1 to ignore commands sent to other bots
export MEONLY="0"
# NOTE: this is a regex, not shell globbing! you must use a valid egex, # NOTE: this is a regex, not shell globbing! you must use a valid egex,
# '.' matches any character and '.*' matches all remaining charatcers! # '.' matches any character and '.*' matches all remaining charatcers!
# additionally you must escape special characters with '\', e.g. '\. \? \[ \*" to match them literally # additionally you must escape special characters with '\', e.g. '\. \? \[ \*" to match them literally
@ -102,7 +106,7 @@ else
return 0 return 0
;; ;;
'/kickme'*) # this will replace the /kickme command '/kickme'*) # this will replace the /kickme command
send_markdown_mesage "${CHAT[ID]}" "*This bot will not kick you!*" send_markdownv2_mesage "${CHAT[ID]}" "This bot will *not* kick you!"
return 1 return 1
;; ;;
esac esac

View File

@ -6,7 +6,7 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
###### ######
# parameters # parameters

View File

@ -2,7 +2,7 @@
# #
# ADD a new test skeleton to test dir, but does not activate test # ADD a new test skeleton to test dir, but does not activate test
# #
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# magic to ensure that we're always inside the root of our application, # magic to ensure that we're always inside the root of our application,
# no matter from which directory we'll run script # no matter from which directory we'll run script

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# common variables # common variables
export TESTME DIRME TESTDIR LOGFILE REFDIR TESTNAME export TESTME DIRME TESTDIR LOGFILE REFDIR TESTNAME

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
../dev/hooks/pre-commit.sh ../dev/hooks/pre-commit.sh

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# file: b-example-test.sh # file: b-example-test.sh
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# include common functions and definitions # include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh # shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# include common functions and definitions # include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh # shellcheck source=test/ALL-tests.inc.sh
@ -14,6 +14,7 @@ set -e
$TESTTOKEN $TESTTOKEN
nobody nobody
botadmin botadmin
EOF EOF
echo "${SUCCESS}" echo "${SUCCESS}"
@ -44,7 +45,3 @@ trap '' EXIT
cd "${DIRME}" || exit 1 cd "${DIRME}" || exit 1
echo "${SUCCESS}" echo "${SUCCESS}"
echo "Test bashbot.sh stat"
cp "${REFDIR}/count.test" "${TESTDIR}/count.jssh"
"${TESTDIR}/bashbot.sh" stats >"${TESTDIR}/stats.out"
diff -q "${TESTDIR}/stats.out" "${REFDIR}/stats.out" >>"${LOGFILE}" || { echo "${NOSUCCESS} Fail diff stats output!"; FAIL="1"; }

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#### $$VERSION$$ v1.2-dev-13-g2a5d47d #### $$VERSION$$ v1.20-0-g2ab00a2
# include common functions and definitions # include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh # shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# include common functions and definitions # include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh # shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# include common functions and definitions # include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh # shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# include common functions and definitions # include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh # shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# include common functions and definitions # include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh # shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash #!/usr/bin/env bash
#### $$VERSION$$ v1.0-0-g99217c4 #### $$VERSION$$ v1.20-0-g2ab00a2
# include common functions and definitions # include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh # shellcheck source=test/ALL-tests.inc.sh