mirror of
https://github.com/octoleo/telegram-bot-bash.git
synced 2024-12-29 05:02:46 +00:00
Merge pull request #161 from topkecleon/develop Version 1.20
Version 1.2
This commit is contained in:
commit
74ab0c24fc
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,7 +6,7 @@
|
||||
/botconf*
|
||||
/botacl*
|
||||
/botown*
|
||||
ˆ.jssh
|
||||
*.jssh
|
||||
*.save
|
||||
*.log
|
||||
*.swp
|
||||
|
215
README.html
215
README.html
@ -6,6 +6,136 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<title>Bashbot README</title>
|
||||
<style>
|
||||
html {
|
||||
line-height: 1.5;
|
||||
font-family: Georgia, serif;
|
||||
font-size: 20px;
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
word-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 1em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, 'Lucida Console', Consolas, monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
span.underline{text-decoration: underline;}
|
||||
@ -74,6 +204,7 @@
|
||||
code span.va { color: #19177c; } /* Variable */
|
||||
code span.vs { color: #4070a0; } /* VerbatimString */
|
||||
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
||||
@ -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>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>
|
||||
<pre><code>which bash && echo "bash seems available..."
|
||||
</code></pre>
|
||||
<pre><code>which bash && echo "bash seems available..."</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>
|
||||
<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">'/.*/.*/.*tar.gz'</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">'/.*/.*/.*tar.gz'</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 <Return> key.</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
|
||||
@ -177,8 +307,7 @@ You are Botadmin
|
||||
/info
|
||||
|
||||
This is bashbot, the Telegram bot written entirely in bash.
|
||||
It features background tasks and interactive chats, and can serve as an interface for CLI programs.
|
||||
</code></pre>
|
||||
It features background tasks and interactive chats, and can serve as an interface for CLI programs.</code></pre>
|
||||
<p>For more Information on how to install, customize and use your new bot, read the <a href="#Documentation">Documentation</a></p>
|
||||
<h3>Log files</h3>
|
||||
<p>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
|
||||
│ │
|
||||
│ ├── DEBUG.log # stdout/stderr of you bot (debug mode enabled)
|
||||
│ └── MESSAGE.log # full text of all message send/received (debug mode enabled)
|
||||
</code></pre>
|
||||
│ └── MESSAGE.log # full text of all message send/received (debug mode enabled)</code></pre>
|
||||
<hr />
|
||||
<h2>Security Considerations</h2>
|
||||
<p>Running a Telegram Bot means it is connected to the public and you never know what's send to your Bot.</p>
|
||||
@ -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>
|
||||
<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>
|
||||
<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>
|
||||
<span id="cb5-2"><a href="#cb5-2"></a> <span class="bu">echo</span> <span class="st">"text with variables. PWD=</span><span class="va">$PWD</span><span class="st">"</span></span>
|
||||
<span id="cb5-3"><a href="#cb5-3"></a> <span class="bu">printf</span> <span class="st">'%s\n'</span> <span class="st">"text with variables. PWD=</span><span class="va">$PWD</span><span class="st">"</span></span>
|
||||
<span id="cb5-4"><a href="#cb5-4"></a> <span class="ex">-</span><span class="op">></span> text with variables. PWD=/home/xxx</span>
|
||||
<span id="cb5-5"><a href="#cb5-5"></a></span>
|
||||
<span id="cb5-6"><a href="#cb5-6"></a> <span class="co"># more advanced</span></span>
|
||||
<span id="cb5-7"><a href="#cb5-7"></a> <span class="va">FLOAT=</span><span class="st">"1.2346777892864"</span> <span class="va">INTEGER=</span><span class="st">"12345.123"</span></span>
|
||||
<span id="cb5-8"><a href="#cb5-8"></a> <span class="bu">echo</span> <span class="st">"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">"</span></span>
|
||||
<span id="cb5-9"><a href="#cb5-9"></a> <span class="ex">-</span><span class="op">></span>text with variables. float=1.2346777892864, integer=12345.123, PWD=/home/xxx</span>
|
||||
<span id="cb5-10"><a href="#cb5-10"></a></span>
|
||||
<span id="cb5-11"><a href="#cb5-11"></a> <span class="bu">printf</span> <span class="st">"text with variables. float=%.2f, integer=%d, PWD=%s\n"</span> <span class="st">""</span> <span class="st">"</span><span class="va">$INTEGER</span><span class="st">"</span> <span class="st">"</span><span class="va">$PWD</span><span class="st">"</span></span>
|
||||
<span id="cb5-12"><a href="#cb5-12"></a> <span class="ex">-</span><span class="op">></span>text with variables. float=1.23, integer=12345, PWD=/home/xxx</span></code></pre></div>
|
||||
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a> <span class="co"># very simple</span></span>
|
||||
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a> <span class="bu">echo</span> <span class="st">"text with variables. PWD=</span><span class="va">$PWD</span><span class="st">"</span></span>
|
||||
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a> <span class="bu">printf</span> <span class="st">'%s\n'</span> <span class="st">"text with variables. PWD=</span><span class="va">$PWD</span><span class="st">"</span></span>
|
||||
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a> <span class="bu">printf</span> <span class="st">'text with variables. PWD=%s\n'</span> <span class="st">"</span><span class="va">$PWD</span><span class="st">"</span></span>
|
||||
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a> <span class="ex">-</span><span class="op">></span> text with variables. PWD=/home/xxx</span>
|
||||
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a> <span class="co"># more advanced</span></span>
|
||||
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a> <span class="va">FLOAT=</span><span class="st">"1.2346777892864"</span> <span class="va">INTEGER=</span><span class="st">"12345.123"</span></span>
|
||||
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a> <span class="bu">echo</span> <span class="st">"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">"</span></span>
|
||||
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a> <span class="ex">-</span><span class="op">></span> float=1.2346777892864, integer=12345.123, PWD=/home/xxx</span>
|
||||
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a> <span class="bu">printf</span> <span class="st">"text with variables. float=%.2f, integer=%d, PWD=%s\n"</span> <span class="st">"</span><span class="va">$FLOAT</span><span class="st">"</span> <span class="st">"</span><span class="va">$INTEGER</span><span class="st">"</span> <span class="st">"</span><span class="va">$PWD</span><span class="st">"</span></span>
|
||||
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a> <span class="ex">-</span><span class="op">></span> float=1.23, integer=12345, PWD=/home/xxx</span></code></pre></div>
|
||||
<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>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>
|
||||
<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>
|
||||
<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>
|
||||
<span id="cb6-2"><a href="#cb6-2"></a><span class="bu">export</span> <span class="va">BASHBOT_HOME=</span><span class="st">"</span><span class="va">$(</span><span class="bu">pwd</span><span class="va">)</span><span class="st">"</span></span>
|
||||
<span id="cb6-3"><a href="#cb6-3"></a><span class="bu">source</span> ./bashbot.sh source</span>
|
||||
<span id="cb6-4"><a href="#cb6-4"></a></span>
|
||||
<span id="cb6-5"><a href="#cb6-5"></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">"</span><span class="va">$(</span><span class="ex">getConfigKey</span> <span class="st">"botadmin"</span><span class="va">)</span><span class="st">"</span> <span class="st">"test"</span></span>
|
||||
<span id="cb6-7"><a href="#cb6-7"></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-9"><a href="#cb6-9"></a><span class="ex">send_message</span> <span class="st">"</span><span class="va">$(</span><span class="ex">getConfigKey</span> <span class="st">"botadmin"</span><span class="va">)</span><span class="st">"</span> <span class="st">"</span><span class="va">$(</span><span class="fu">df</span> -h<span class="va">)</span><span class="st">"</span></span></code></pre></div>
|
||||
<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" aria-hidden="true" tabindex="-1"></a><span class="bu">export</span> <span class="va">BASHBOT_HOME=</span><span class="st">"</span><span class="va">$(</span><span class="bu">pwd</span><span class="va">)</span><span class="st">"</span></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" aria-hidden="true" tabindex="-1"></a></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" aria-hidden="true" tabindex="-1"></a><span class="ex">send_message</span> <span class="st">"</span><span class="va">$(</span><span class="ex">getConfigKey</span> <span class="st">"botadmin"</span><span class="va">)</span><span class="st">"</span> <span class="st">"test"</span></span>
|
||||
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a></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" aria-hidden="true" tabindex="-1"></a><span class="ex">send_message</span> <span class="st">"</span><span class="va">$(</span><span class="ex">getConfigKey</span> <span class="st">"botadmin"</span><span class="va">)</span><span class="st">"</span> <span class="st">"</span><span class="va">$(</span><span class="fu">df</span> <span class="at">-h</span><span class="va">)</span><span class="st">"</span></span></code></pre></div>
|
||||
<p>For more information see <a href="doc/8_custom.md">Expert Use</a></p>
|
||||
<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>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>
|
||||
<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-3"><a href="#cb7-3"></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-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>
|
||||
<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" 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" aria-hidden="true" tabindex="-1"></a></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" 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">"your IP seems blocked by telegram"</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>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>
|
||||
<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>
|
||||
<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-3"><a href="#cb8-3"></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-5"><a href="#cb8-5"></a> <span class="fu">sleep</span> 60 <span class="kw">&&</span> <span class="bu">return</span> 0 <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-7"><a href="#cb8-7"></a> <span class="kw">}</span></span>
|
||||
<span id="cb8-8"><a href="#cb8-8"></a></span></code></pre></div>
|
||||
<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" 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" aria-hidden="true" tabindex="-1"></a><span class="fu">bashbotBlockRecover()</span> <span class="kw">{</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" aria-hidden="true" tabindex="-1"></a> <span class="fu">sleep</span> 60 <span class="kw">&&</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" 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" aria-hidden="true" tabindex="-1"></a> <span class="er">}</span></span></code></pre></div>
|
||||
<p>@Gnadelwartz</p>
|
||||
<h2>That's it all guys!</h2>
|
||||
<p>If you feel that there's something missing or if you found a bug, feel free to submit a pull request!</p>
|
||||
<h4>$$VERSION$$ v1.1-0-ge835bbc</h4>
|
||||
<h4>$$VERSION$$ v1.20-0-g2ab00a2</h4>
|
||||
</body>
|
||||
</html>
|
||||
|
14
README.md
14
README.md
@ -152,15 +152,16 @@ you shouldn't use echo to display it. [Use printf whenever possible](https://uni
|
||||
# very simple
|
||||
echo "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
|
||||
|
||||
# more advanced
|
||||
FLOAT="1.2346777892864" INTEGER="12345.123"
|
||||
echo "text with variabeles. float=$FLOAT, integer=$INTEGER, PWD=$PWD"
|
||||
->text with variables. float=1.2346777892864, integer=12345.123, PWD=/home/xxx
|
||||
echo "float=$FLOAT, integer=$INTEGER, PWD=$PWD"
|
||||
-> float=1.2346777892864, integer=12345.123, PWD=/home/xxx
|
||||
|
||||
printf "text with variables. float=%.2f, integer=%d, PWD=%s\n" "" "$INTEGER" "$PWD"
|
||||
->text with variables. float=1.23, integer=12345, PWD=/home/xxx
|
||||
printf "text with variables. float=%.2f, integer=%d, PWD=%s\n" "$FLOAT" "$INTEGER" "$PWD"
|
||||
-> float=1.23, integer=12345, PWD=/home/xxx
|
||||
```
|
||||
|
||||
### 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
|
||||
#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
|
||||
@ -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!
|
||||
|
||||
#### $$VERSION$$ v1.1-0-ge835bbc
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
16
README.txt
16
README.txt
@ -204,16 +204,17 @@ possible](https://unix.stackexchange.com/a/6581)
|
||||
# very simple
|
||||
echo "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
|
||||
|
||||
# more advanced
|
||||
FLOAT="1.2346777892864" INTEGER="12345.123"
|
||||
echo "text with variabeles. float=$FLOAT, integer=$INTEGER, PWD=$PWD"
|
||||
->text with variables. float=1.2346777892864, integer=12345.123, PWD=/home/xxx
|
||||
echo "float=$FLOAT, integer=$INTEGER, PWD=$PWD"
|
||||
-> float=1.2346777892864, integer=12345.123, PWD=/home/xxx
|
||||
|
||||
printf "text with variables. float=%.2f, integer=%d, PWD=%s\n" "" "$INTEGER"
|
||||
"$PWD"
|
||||
->text with variables. float=1.23, integer=12345, PWD=/home/xxx
|
||||
printf "text with variables. float=%.2f, integer=%d, PWD=%s\n" "$FLOAT"
|
||||
"$INTEGER" "$PWD"
|
||||
-> float=1.23, integer=12345, PWD=/home/xxx
|
||||
```
|
||||
|
||||
### 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
|
||||
#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
|
||||
@ -355,4 +359,4 @@ wait
|
||||
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
|
||||
|
@ -4,7 +4,7 @@
|
||||
# this addon counts how many files, e.g. stickers, are sent to
|
||||
# a chat and takes actions if threshold is reached
|
||||
#
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# used events:
|
||||
#
|
||||
|
@ -4,7 +4,7 @@
|
||||
# Addons can register to bashbot events at startup
|
||||
# by providing their name and a callback per event
|
||||
#
|
||||
#### $$VERSION$$ v1.2-dev-13-g2a5d47d
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
#
|
||||
# If an event occurs each registered event function is called.
|
||||
#
|
||||
|
@ -1,7 +1,11 @@
|
||||
#!/bin/sh
|
||||
# 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=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:
|
||||
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="runuser $runas -s /bin/bash -c " # runasuser with *runuser*
|
||||
|
||||
|
293
bashbot.sh
293
bashbot.sh
@ -11,7 +11,7 @@
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.2-dev-25-g0b64af7
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
#
|
||||
# Exit Codes:
|
||||
# - 0 success (hopefully)
|
||||
@ -22,13 +22,14 @@
|
||||
# - 5 cannot connect to telegram bot
|
||||
# - 6 mandatory module not found
|
||||
# - 7 can't get bottoken
|
||||
# - 8 curl/wget missing
|
||||
# - 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
|
||||
# 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
|
||||
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
|
||||
fi
|
||||
|
||||
@ -42,30 +43,36 @@ if [ -t 1 ] && [ -n "$TERM" ]; then
|
||||
NC='\e[0m'
|
||||
fi
|
||||
|
||||
# we need some bash 4+ features, check for old bash by feature
|
||||
if [ "$(echo -e "\u1111")" == "\u1111" ]; then
|
||||
echo -e "${ORANGE}Warning: Unicode '\uxxxx' seems not supported, install a more current bash.${NC}"
|
||||
# telegram uses utf-8 characters, check if we have an utf-8 charset
|
||||
if [ "${LANG}" = "${LANG%[Uu][Tt][Ff]*}" ]; then
|
||||
echo -e "${ORANGE}Warning: Telegram uses utf-8, but looks like you are using non utf-8 locale:${NC} ${LANG}"
|
||||
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
|
||||
# returns true if command exist
|
||||
_exists() {
|
||||
[ "$(LC_ALL=C type -t "${1}")" = "file" ]
|
||||
[ "$(type -t "${1}")" = "file" ]
|
||||
}
|
||||
# execute function if exists
|
||||
_exec_if_function() {
|
||||
[ "$(LC_ALL=C type -t "${1}")" != "function" ] && return 1
|
||||
[ "$(type -t "${1}")" != "function" ] && return 1
|
||||
"$@"
|
||||
}
|
||||
# returns true if function exist
|
||||
_is_function() {
|
||||
[ "$(LC_ALL=C type -t "${1}")" = "function" ]
|
||||
[ "$(type -t "${1}")" = "function" ]
|
||||
}
|
||||
# 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
|
||||
_round_float() {
|
||||
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() {
|
||||
[[ "$1" =~ ^[-a-zA-Z0-9,._]+$ ]] || return 3
|
||||
@ -83,16 +90,17 @@ check_token(){
|
||||
return 1
|
||||
}
|
||||
# log $1 to ERRORLOG with date
|
||||
log_error(){
|
||||
printf "%s: %s\n" "$(date)" "$*" >>"${ERRORLOG}"
|
||||
}
|
||||
log_error(){ printf "%s: %b\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
|
||||
export BASHBOTDEBUG
|
||||
# debug should always last argument
|
||||
[[ "${BASH_ARGV[0]}" == *"debug"* ]] && BASHBOTDEBUG="yes"
|
||||
# $1 where $2 command $3 may debug
|
||||
# shellcheck disable=SC2094
|
||||
debug_checks(){
|
||||
debug_checks(){ {
|
||||
[ -z "${BASHBOTDEBUG}" ] && return
|
||||
local DATE WHERE MYTOKEN; DATE="$(date)"; WHERE="${1}"; shift
|
||||
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! =========="
|
||||
# call user defined debug_checks if exists
|
||||
_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
|
||||
SCRIPT="$0"
|
||||
@ -119,7 +133,7 @@ if [ "${SCRIPT}" != "${REALME}" ] || [ "$1" = "source" ]; then
|
||||
SOURCE="yes"
|
||||
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
|
||||
if [ "$1" = "help" ]; then
|
||||
HELP="${BASHBOT_HOME:-.}/README"
|
||||
@ -168,16 +182,13 @@ COUNTFILE="${BASHBOT_VAR:-.}/count"
|
||||
LOGDIR="${RUNDIR:-.}/logs"
|
||||
|
||||
# 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
|
||||
[ ! -f "${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
|
||||
if [ -r "${TOKENFILE}" ]; then
|
||||
token="$(< "${TOKENFILE}")"
|
||||
# no old token available ask user
|
||||
# no old token, ask user
|
||||
elif [ -z "${CLEAR}" ] && [ "$1" != "init" ]; then
|
||||
echo "Running headless, set BOTTOKEN or run ${SCRIPT} init first!"
|
||||
exit 2
|
||||
@ -188,7 +199,6 @@ if [ -z "${BOTTOKEN}" ]; then
|
||||
read -r token
|
||||
fi
|
||||
[ -n "${token}" ] && printf '["bottoken"]\t"%s"\n' "${token}" >> "${BOTCONFIG}.jssh"
|
||||
fi
|
||||
|
||||
# no botadmin, setup botadmin
|
||||
if [ -z "$(getConfigKey "botadmin")" ]; then
|
||||
@ -238,45 +248,48 @@ if [ -z "${BOTTOKEN}" ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -d "${LOGDIR}" ] || [ ! -w "${LOGDIR}" ]; then
|
||||
if [[ ! -d "${LOGDIR}" || ! -w "${LOGDIR}" ]]; then
|
||||
LOGDIR="${RUNDIR:-.}"
|
||||
fi
|
||||
DEBUGLOG="${LOGDIR}/DEBUG.log"
|
||||
ERRORLOG="${LOGDIR}/ERROR.log"
|
||||
UPDATELOG="${LOGDIR}/BASHBOT.log"
|
||||
MESSAGELOG="${LOGDIR}/MESSAGE.log"
|
||||
|
||||
debug_checks "start SOURCE=${SOURCE:-no}" "$@"
|
||||
# read BOTTOKEN from bot database if not set
|
||||
if [ -z "${BOTTOKEN}" ]; then
|
||||
BOTTOKEN="$(getConfigKey "bottoken")"
|
||||
if [ -z "${BOTTOKEN}" ]; then
|
||||
BOTERROR="Warning: can't get bot token, try to recover working config"
|
||||
echo -e "${ORANGE}${BOTERROR}${NC}"
|
||||
BOTERROR="Warning: can't get bot token, try to recover working config..."
|
||||
echo -e "${ORANGE}${BOTERROR}${NC} \c"
|
||||
if [ -r "${BOTCONFIG}.jssh.ok" ]; then
|
||||
log_error "${BOTERROR}"
|
||||
cp "${BOTCONFIG}.jssh.ok" "${BOTCONFIG}.jssh"
|
||||
cp "${BOTCONFIG}.jssh.ok" "${BOTCONFIG}.jssh"; echo "OK"
|
||||
BOTTOKEN="$(getConfigKey "bottoken")"
|
||||
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
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# BOTTOKEN format checks
|
||||
if ! check_token "${BOTTOKEN}"; then
|
||||
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}8-10 digits${RED}:${GREY}35 alphanumeric characters + '_-'${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}"
|
||||
[ -n "$(getConfigKey "botid")" ] && echo -e "${GREY}Did you mean: \"${NC}$(getConfigKey "botid")${GREY}\" ?${NC}"
|
||||
fi
|
||||
[[ ! "${BOTTOKEN}" =~ :[a-zA-Z0-9_-]{35}$ ]] &&\
|
||||
echo -e "${ORANGE}Possible problem in the characters part, len is $(($(wc -c <<<"${BOTTOKEN#*:}")-1))${NC}"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
##################
|
||||
# here we start with the real stuff
|
||||
BASHBOT_RETRY="" # retry by default
|
||||
@ -295,8 +308,8 @@ declare -rx BOTTOKEN URL ME_URL UPD_URL GETFILE_URL
|
||||
|
||||
declare -ax CMD
|
||||
declare -Ax UPD BOTSENT USER MESSAGE URLS CONTACT LOCATION CHAT FORWARD REPLYTO VENUE iQUERY
|
||||
declare -Ax SERVICE NEWMEMBER LEFTMEMBER PINNED
|
||||
export res CAPTION
|
||||
declare -Ax SERVICE NEWMEMBER LEFTMEMBER PINNED MIGRATE
|
||||
export res CAPTION ME
|
||||
|
||||
|
||||
##################
|
||||
@ -375,7 +388,7 @@ killallproc() {
|
||||
# $ chat $2 msg_id $3 nolog
|
||||
declare -xr DELETE_URL=$URL'/deleteMessage'
|
||||
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}"
|
||||
}
|
||||
|
||||
@ -385,14 +398,19 @@ get_file() {
|
||||
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 FALSE if no curl is found or wget is forced by BASHBOT_WGET
|
||||
# sets BASHBOT_CURL to point to curl
|
||||
DETECTED_CURL="curl"
|
||||
function detect_curl() {
|
||||
# custom curl command
|
||||
[ -n "${BASHBOT_CURL}" ] && return 0
|
||||
# use wget
|
||||
[ -n "${BASHBOT_WGET}" ] && return 1
|
||||
if [ -n "${BASHBOT_WGET}" ]; then
|
||||
DETECTED_CURL="wget"
|
||||
return 1
|
||||
fi
|
||||
# default use curl in PATH
|
||||
BASHBOT_CURL="curl"
|
||||
_exists curl && return 0
|
||||
@ -405,48 +423,72 @@ function detect_curl() {
|
||||
fi
|
||||
done
|
||||
# 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."
|
||||
printf "%s: %s\n" "$(date)" "${warn}" >>"${UPDATELOG}"
|
||||
[ -n "${BASHBOTDEBUG}" ] && printf "%s: %s\n" "$(date)" "${warn}" >>"${DEBUGLOG}"
|
||||
log_update "${warn}"; [ -n "${BASHBOTDEBUG}" ] && log_debug "${warn}"
|
||||
return 1
|
||||
}
|
||||
|
||||
# iconv used to filter out broken utf characters, if not installed fake it
|
||||
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; }
|
||||
fi
|
||||
|
||||
TIMEOUT="${BASHBOT_TIMEOUT}"
|
||||
[[ "$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
|
||||
# here we have curl ----
|
||||
[ -z "${BASHBOT_CURL}" ] && BASHBOT_CURL="curl"
|
||||
# simple curl or wget call, output to stdout
|
||||
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
|
||||
"${BASHBOT_CURL}" -sL -k ${BASHBOT_CURL_ARGS} -m "${TIMEOUT}" "$1"
|
||||
}
|
||||
# usage: sendJson "chat" "JSON" "URL"
|
||||
sendJson(){
|
||||
local chat="";
|
||||
[ -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}"
|
||||
# curl variant for sendJson
|
||||
# usage: "JSON" "URL"
|
||||
sendJson_do(){
|
||||
# shellcheck disable=SC2086
|
||||
res="$("${BASHBOT_CURL}" -s -k ${BASHBOT_CURL_ARGS} -m "${TIMEOUT}"\
|
||||
-d '{'"${chat} $(iconv -f utf-8 -t utf-8 -c <<<$2)"'}' -X POST "${3}" \
|
||||
-H "Content-Type: application/json" | "${JSONSHFILE}" -b -n 2>/dev/null )"
|
||||
sendJsonResult "${res}" "sendJson (curl)" "$@"
|
||||
[ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "send" "${@}" &
|
||||
"${BASHBOT_CURL}" -s -k ${BASHBOT_CURL_ARGS} -m "${TIMEOUT}"\
|
||||
-d "${1}" -X POST "${2}" -H "Content-Type: application/json" | "${JSONSHFILE}" -b -n 2>/dev/null
|
||||
}
|
||||
#$1 Chat, $2 what, $3 file, $4 URL, $5 caption
|
||||
sendUpload() {
|
||||
[ "$#" -lt 4 ] && return
|
||||
if [ -n "$5" ]; then
|
||||
[ -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
|
||||
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 )"
|
||||
@ -459,29 +501,34 @@ if detect_curl ; then
|
||||
[ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "upload" "$@" &
|
||||
}
|
||||
else
|
||||
# simple curl or wget call outputs result to stdout
|
||||
# NO curl, try wget
|
||||
if _exists wget; then
|
||||
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
|
||||
wget --no-check-certificate -t 2 -T "${TIMEOUT}" ${BASHBOT_WGET_ARGS} -qO - "$1"
|
||||
}
|
||||
# usage: sendJson "chat" "JSON" "URL"
|
||||
sendJson(){
|
||||
local chat="";
|
||||
[ -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}"
|
||||
# curl variant for sendJson
|
||||
# usage: "JSON" "URL"
|
||||
sendJson_do(){
|
||||
# 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)"'}' \
|
||||
--header='Content-Type:application/json' "${3}" | "${JSONSHFILE}" -b -n 2>/dev/null )"
|
||||
sendJsonResult "${res}" "sendJson (wget)" "$@"
|
||||
[ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "send" "${@}" &
|
||||
wget --no-check-certificate -t 2 -T "${TIMEOUT}" ${BASHBOT_WGET_ARGS} -qO - --post-data="${1}" \
|
||||
--header='Content-Type:application/json' "${2}" | "${JSONSHFILE}" -b -n 2>/dev/null
|
||||
}
|
||||
sendUpload() {
|
||||
log_error "Sorry, wget does not support file upload"
|
||||
BOTSENT[OK]="false"
|
||||
[ -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
|
||||
|
||||
# retry sendJson
|
||||
@ -514,7 +561,7 @@ sendJsonRetry(){
|
||||
sendJsonResult(){
|
||||
local offset=0
|
||||
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}")"
|
||||
if [ "${BOTSENT[OK]}" = "true" ]; then
|
||||
BOTSENT[ID]="$(JsonGetValue '"result","message_id"' <<< "${1}")"
|
||||
@ -522,9 +569,10 @@ sendJsonResult(){
|
||||
# hot path everything OK!
|
||||
else
|
||||
# oops something went wrong!
|
||||
if [ "${res}" != "" ]; then
|
||||
if [ "${1}" != "" ]; then
|
||||
BOTSENT[ERROR]="$(JsonGetValue '"error_code"' <<< "${1}")"
|
||||
BOTSENT[DESCRIPTION]="$(JsonGetString '"description"' <<< "${1}")"
|
||||
grep -qs -F '"parameters","retry_after"' <<< "${1}" &&\
|
||||
BOTSENT[RETRY]="$(JsonGetValue '"parameters","retry_after"' <<< "${1}")"
|
||||
else
|
||||
BOTSENT[OK]="false"
|
||||
@ -593,9 +641,15 @@ title2Json(){
|
||||
printf '%s\n' "${title}${caption}${desc}${markup}${keyboard}"
|
||||
}
|
||||
|
||||
# get bot name
|
||||
# get bot name and id from telegram
|
||||
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)
|
||||
@ -626,7 +680,7 @@ JsonGetValue() {
|
||||
# processing of updates starts here
|
||||
process_updates() {
|
||||
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}"
|
||||
for ((num=0; num<=max; num++)); do
|
||||
process_client "$num" "${debug}"
|
||||
@ -637,7 +691,7 @@ process_client() {
|
||||
local num="$1" debug="$2"
|
||||
pre_process_message "${num}"
|
||||
# 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
|
||||
jssh_updateArray_async "BASHBOTBLOCKED" "${BLOCKEDFILE}"
|
||||
@ -802,7 +856,7 @@ pre_process_message(){
|
||||
local num="${1}"
|
||||
# unset everything to not have old values
|
||||
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"]}"
|
||||
CHAT[ID]="${UPD["result",${num},"message","chat","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]}"
|
||||
|
||||
# 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[0]="$(JsonDecode "${UPD["result",${num},"message","reply_to_message","text"]}")"
|
||||
REPLYTO[ID]="${UPD["result",${num},"message","reply_to_message","message_id"]}"
|
||||
@ -856,7 +910,7 @@ process_message() {
|
||||
fi
|
||||
|
||||
# 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[ID]="${MESSAGE[ID]}" # same as message ID
|
||||
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"]}")"
|
||||
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
|
||||
URLS[AUDIO]="$(get_file "${UPD["result",${num},"message","audio","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[VOICE]="$(get_file "${UPD["result",${num},"message","voice","file_id"]}")"
|
||||
fi
|
||||
# Contact
|
||||
if grep -qs -e '\["result",'"${num}"',"message","contact"' <<<"${UPDATE}"; then
|
||||
CONTACT[FIRST_NAME]="$(JsonDecode "${UPD["result",${num},"message","contact","first_name"]}")"
|
||||
# Contact, must have phone_number
|
||||
if [ -n "${UPD["result",${num},"message","contact","phone_number"]}" ]; then
|
||||
CONTACT[USER_ID]="$(JsonDecode "${UPD["result",${num},"message","contact","user_id"]}")"
|
||||
CONTACT[FIRST_NAME]="$(JsonDecode "${UPD["result",${num},"message","contact","first_name"]}")"
|
||||
CONTACT[LAST_NAME]="$(JsonDecode "${UPD["result",${num},"message","contact","last_name"]}")"
|
||||
CONTACT[NUMBER]="${UPD["result",${num},"message","contact","phone_number"]}"
|
||||
CONTACT[VCARD]="$(JsonGetString '"result",'"${num}"',"message","contact","vcard"' <<<"${UPDATE}")"
|
||||
fi
|
||||
|
||||
# vunue
|
||||
if grep -qs -e '\["result",'"${num}"',"message","venue"' <<<"${UPDATE}"; then
|
||||
# venue, must have a position
|
||||
if [ -n "${UPD["result",${num},"message","venue","location","longitude"]}" ]; then
|
||||
VENUE[TITLE]="$(JsonDecode "${UPD["result",${num},"message","venue","title"]}")"
|
||||
VENUE[ADDRESS]="$(JsonDecode "${UPD["result",${num},"message","venue","address"]}")"
|
||||
VENUE[LONGITUDE]="${UPD["result",${num},"message","venue","location","longitude"]}"
|
||||
@ -898,8 +952,10 @@ process_message() {
|
||||
LOCATION[LONGITUDE]="${UPD["result",${num},"message","location","longitude"]}"
|
||||
LOCATION[LATITUDE]="${UPD["result",${num},"message","location","latitude"]}"
|
||||
|
||||
# service messages
|
||||
if grep -qs -e '\["result",'"${num}"',"message","new_chat_member' <<<"${UPDATE}"; then
|
||||
# service messages, group or channel only!
|
||||
if [[ "${CHAT[ID]}" == "-"* ]] ; then
|
||||
# new chat member
|
||||
if [ -n "${UPD["result",${num},"message","new_chat_member","id"]}" ]; then
|
||||
SERVICE[NEWMEMBER]="${UPD["result",${num},"message","new_chat_member","id"]}"
|
||||
NEWMEMBER[ID]="${SERVICE[NEWMEMBER]}"
|
||||
NEWMEMBER[FIRST_NAME]="$(JsonDecode "${UPD["result",${num},"message","new_chat_member","first_name"]}")"
|
||||
@ -909,7 +965,8 @@ process_message() {
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
MESSAGE[0]="/_new_chat_member ${NEWMEMBER[ID]} ${NEWMEMBER[USERNAME]:=${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]}}"
|
||||
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"]}"
|
||||
LEFTMEMBER[ID]="${SERVICE[LEFTMEBER]}"
|
||||
LEFTMEMBER[FIRST_NAME]="$(JsonDecode "${UPD["result",${num},"message","left_chat_member","first_name"]}")"
|
||||
@ -919,6 +976,7 @@ process_message() {
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
MESSAGE[0]="/_left_chat_member ${LEFTMEMBER[ID]} ${LEFTMEMBER[USERNAME]:=${LEFTMEMBER[FIRST_NAME]} ${LEFTMEMBER[LAST_NAME]}}"
|
||||
fi
|
||||
# chat title / photo, check for any of them!
|
||||
if grep -qs -e '\["result",'"${num}"',"message","new_chat_[tp]' <<<"${UPDATE}"; then
|
||||
SERVICE[NEWTITLE]="$(JsonDecode "${UPD["result",${num},"message","new_chat_title"]}")"
|
||||
[ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[NEWTITLE]}" ] &&\
|
||||
@ -927,15 +985,25 @@ process_message() {
|
||||
[ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[NEWPHOTO]}" ] &&\
|
||||
MESSAGE[0]="/_new_chat_photo ${USER[ID]} ${SERVICE[NEWPHOTO]}"
|
||||
fi
|
||||
if grep -qs -e '\["result",'"${num}"',"message","pinned_message' <<<"${UPDATE}"; then
|
||||
SERVICE[PINNED]="$(JsonDecode "${UPD["result",${num},"message","pinned_message","message_id"]}")"
|
||||
# pinned message
|
||||
if [ -n "${UPD["result",${num},"message","pinned_message","message_id"]}" ]; then
|
||||
SERVICE[PINNED]="${UPD["result",${num},"message","pinned_message","message_id"]}"
|
||||
PINNED[ID]="${SERVICE[PINNED]}"
|
||||
PINNED[MESSAGE]="$(JsonDecode "${UPD["result",${num},"message","pinned_message","text"]}")"
|
||||
[ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[PINNED]}" ] &&\
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
MESSAGE[0]="/_new_pinned_message ${USER[ID]} ${PINNED[ID]} ${PINNED[MESSAGE]}"
|
||||
fi
|
||||
# migrate to super group
|
||||
if [ -n "${UPD["result",${num},"message","migrate_to_chat_id"]}" ]; then
|
||||
MIGRATE[TO]="${UPD["result",${num},"message","migrate_to_chat_id"]}"
|
||||
MIGRATE[FROM]="${UPD["result",${num},"message","migrate_from_chat_id"]}"
|
||||
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
|
||||
[[ "${SERVICE[*]}" =~ ^[[:blank:]]*$ ]] || SERVICE[0]="yes"
|
||||
fi
|
||||
|
||||
# split message in command and args
|
||||
[[ "${MESSAGE[0]}" == "/"* ]] && read -r CMD <<<"${MESSAGE[0]}" && CMD[0]="${CMD[0]%%@*}"
|
||||
@ -946,6 +1014,7 @@ process_message() {
|
||||
#########################
|
||||
# main get updates loop, should never terminate
|
||||
declare -A BASHBOTBLOCKED
|
||||
export BASHBOT_UPDATELOG="${BASHBOT_UPDATELOG-nolog}" # allow to be ""
|
||||
start_bot() {
|
||||
local DEBUGMSG ADMIN OFFSET=0
|
||||
# adaptive sleep defaults
|
||||
@ -953,12 +1022,12 @@ start_bot() {
|
||||
local stepsleep="${BASHBOT_SLEEP_STEP:-100}"
|
||||
local maxsleep="${BASHBOT_SLEEP:-5000}"
|
||||
# startup message
|
||||
DEBUGMSG="$(date): Start BASHBOT updates in Mode \"${1:-normal}\" =========="
|
||||
printf "%s\n" "${DEBUGMSG}" >>"${UPDATELOG}"
|
||||
DEBUGMSG="Start BASHBOT updates in Mode \"${1:-normal}\" =========="
|
||||
log_update "${DEBUGMSG}"
|
||||
# redirect to Debug.log
|
||||
[[ "${1}" == *"debug" ]] && exec &>>"${DEBUGLOG}"
|
||||
printf "%s\n" "${DEBUGMSG}"; DEBUGMSG="${1}"
|
||||
[[ "${DEBUGMSG}" == "xdebug"* ]] && set -x
|
||||
log_debug "${DEBUGMSG}"; DEBUGMSG="${1}"
|
||||
[[ "${DEBUGMSG}" == "xdebug"* ]] && set -x && unset BASHBOT_UPDATELOG
|
||||
# cleaup old pipes and empty logfiles
|
||||
find "${DATADIR}" -type p -delete
|
||||
find "${DATADIR}" -size 0 -name "*.log" -delete
|
||||
@ -994,7 +1063,7 @@ start_bot() {
|
||||
# adaptive sleep in ms rounded to next 0.1 s
|
||||
sleep "$(_round_float "${nextsleep}e-3" "1")"
|
||||
# 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?
|
||||
if [ -n "${UPDATE}" ]; then
|
||||
# we got something, do processing
|
||||
@ -1014,8 +1083,15 @@ start_bot() {
|
||||
else
|
||||
# oops, something bad happened, wait maxsleep*10
|
||||
(( 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"
|
||||
# try to recover
|
||||
if _is_function bashbotBlockRecover && [ -z "$(getJson "${ME_URL}")" ]; then
|
||||
log_error "Try to recover, calling bashbotBlockRecover ..."
|
||||
bashbotBlockRecover >>"${ERRORLOG}"
|
||||
fi
|
||||
fi
|
||||
OFFSET="-999"
|
||||
fi
|
||||
done
|
||||
@ -1072,6 +1148,15 @@ bot_init() {
|
||||
find . -name '*.jssh*' -exec chmod u+w \{\} +
|
||||
echo "Done."
|
||||
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
|
||||
echo -e "${GREEN}This is your bot config:${NC}"
|
||||
sed 's/^/\t/' "${BOTCONFIG}.jssh" | grep -vF '["bot_config_key"]'
|
||||
@ -1094,6 +1179,7 @@ if ! _is_function send_message ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# get location of JSON.sh, download if not exist
|
||||
JSONSHFILE="${BASHBOT_JSONSH:-${SCRIPTDIR}/JSON.sh/JSON.sh}"
|
||||
[[ "${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}"
|
||||
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
|
||||
# do not execute if read from other scripts
|
||||
|
||||
if [ -z "${SOURCE}" ]; then
|
||||
##############
|
||||
# internal options only for use from bashbot and developers
|
||||
# shellcheck disable=SC2221,SC2222
|
||||
case "${1}" in
|
||||
# update botname when starting only
|
||||
"botname"|"start"*)
|
||||
@ -1159,8 +1252,8 @@ if [ -z "${SOURCE}" ]; then
|
||||
exit
|
||||
;;
|
||||
# print usage stats
|
||||
"count") echo -e "${RED}Command ${GREY}count${RED} is deprecated, use ${GREY}stats{$RED}instead.${NC}";&
|
||||
"stats")
|
||||
echo -e "${ORANGE}stats deprecated, see bin/bashbot_stats --help${NC}"
|
||||
ME="$(getConfigKey "botname")"
|
||||
declare -A STATS
|
||||
jssh_readDB_async "STATS" "${COUNTFILE}"
|
||||
@ -1196,23 +1289,8 @@ if [ -z "${SOURCE}" ]; then
|
||||
;;
|
||||
# send message to all users
|
||||
'broadcast')
|
||||
ME="$(getConfigKey "botname")"
|
||||
declare -A SENDALL
|
||||
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" "$@"
|
||||
echo -e "${ORANGE}Broadcast is a separate command now, see ${BASHBOT_HOME:-.}/bin/send_broadcast.sh --help${NC}"
|
||||
"${BASHBOT_HOME:-.}"/bin/send_broadcast.sh --help
|
||||
exit
|
||||
;;
|
||||
# does what it says
|
||||
@ -1249,7 +1327,6 @@ if [ -z "${SOURCE}" ]; then
|
||||
debug_checks "end start" "$@"
|
||||
;;
|
||||
# does what it says
|
||||
"kill") echo -e "${RED}Command ${GREY}kill${RED} is deprecated, use ${GREY}stop{$RED}instead.${NC}";&
|
||||
"stop")
|
||||
ME="$(getConfigKey "botname")"
|
||||
SESSION="${ME:-_bot}-startbot"
|
||||
|
64
bin/bashbot_env.inc.sh
Normal file
64
bin/bashbot_env.inc.sh
Normal 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
74
bin/bashbot_stats.sh
Executable 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
113
bin/send_broadcast.sh
Executable 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
76
bin/send_edit_message.sh
Executable 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
65
bin/send_file.sh
Executable 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
74
bin/send_message.sh
Executable 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
|
||||
|
32
commands.sh
32
commands.sh
@ -15,7 +15,7 @@
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.1-0-gc0eb399
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
#
|
||||
|
||||
# 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!
|
||||
# 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*:
|
||||
*• /start*: _Start bot and get this message_.
|
||||
*• /help*: _Get this message_.
|
||||
*• /info*: _Get shorter info message about this bot_.
|
||||
*• /question*: _Start interactive chat_.
|
||||
*• /cancel*: _Cancel any currently running interactive chats_.
|
||||
*• /kickme*: _You will be autokicked from the chat_.
|
||||
*• /question*: _Start interactive chat (mycommands.dist)_.
|
||||
*• /cancel*: _Cancel any currently running interactive chat_.
|
||||
*• /kickme*: _You will be autokicked from the group_.
|
||||
*• /leavechat*: _The bot will leave the group with this command _.
|
||||
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)
|
||||
'
|
||||
|
||||
@ -66,8 +65,9 @@ fi
|
||||
#----------------------------
|
||||
# this file *MUST* not edited!
|
||||
# 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 MEONLY="0"
|
||||
export FILE_REGEX="${BASHBOT_ETC}/.*"
|
||||
|
||||
|
||||
@ -87,9 +87,18 @@ if [ -z "${1}" ] || [[ "${1}" == *"debug"* ]];then
|
||||
# your commands are in mycommands()
|
||||
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
|
||||
_exec_if_function mycommands
|
||||
! _is_function mycommands || mycommands
|
||||
|
||||
# run commands if true (0) is returned or if mycommands dose not exist
|
||||
# shellcheck disable=SC2181
|
||||
@ -105,7 +114,10 @@ if [ -z "${1}" ] || [[ "${1}" == *"debug"* ]];then
|
||||
;;
|
||||
'/start'*)
|
||||
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
|
||||
send_markdown_message "${CHAT[ID]}" "${bashbot_help}"
|
||||
else
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# this has to run once atfer git clone
|
||||
# and every time we create new hooks
|
||||
#### $$VERSION$$ v1.1-0-gc0eb399
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# magic to ensure that we're always inside the root of our application,
|
||||
# no matter from which directory we'll run script
|
||||
@ -18,6 +18,9 @@ mkdir "${TESTENV}"
|
||||
cp -r ./* "${TESTENV}"
|
||||
cd "test" || exit 1
|
||||
|
||||
# delete possible config
|
||||
rm -f "${TESTENV}/botconfig.jssh" "${TESTENV}/botacl" 2>/dev/null
|
||||
|
||||
#set -e
|
||||
fail=0
|
||||
tests=0
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
# 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,
|
||||
# no matter from which directory we'll run script
|
||||
@ -14,21 +14,24 @@ else
|
||||
echo "Sorry, no git repository $(pwd)" && exit 1
|
||||
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)"
|
||||
[ "${FILES}" = "" ] && echo "Noting changed since last push ... Abort" && exit
|
||||
set +f
|
||||
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
|
||||
dev/hooks/pre-commit.sh
|
||||
|
||||
echo -n "Add files to repo: "
|
||||
echo -e "Add files to repo: \c"
|
||||
# shellcheck disable=SC2086
|
||||
for file in ${FILES}
|
||||
do
|
||||
[ -d "${file}" ] && continue
|
||||
echo -n "${file} "
|
||||
echo -e "${file} \c"
|
||||
git add "$file"
|
||||
done
|
||||
git add .
|
||||
echo "done."
|
||||
echo " - Done."
|
||||
|
||||
|
24
dev/hooks/post-commit.sh
Executable file
24
dev/hooks/post-commit.sh
Executable 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}"
|
@ -1,5 +1,5 @@
|
||||
#!/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!
|
||||
@ -30,7 +30,7 @@ fi
|
||||
|
||||
# run shellcheck before commit
|
||||
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
|
||||
FILES="${FILES} $(sed '/^#/d' <"dev/shellcheck.files")"
|
||||
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
|
||||
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
|
||||
set +f
|
||||
[ -f "${LASTPUSH}" ] && LASTFILES="$(find ./* -newer "${LASTPUSH}")"
|
||||
@ -68,7 +68,7 @@ fi
|
||||
if command -v codespell &>/dev/null; then
|
||||
echo "Running codespell"
|
||||
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 "codespell -i 3 -w --skip=\"*.log,*.html,*.txt,.git*,examples\" -L \"ba\""
|
||||
else
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/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!
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# this has to run once atfer git clone
|
||||
# and every time we create new hooks
|
||||
#### $$VERSION$$ v1.1-0-gc0eb399
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# magic to ensure that we're always inside the root of our application,
|
||||
# no matter from which directory we'll run script
|
||||
@ -15,7 +15,7 @@ fi
|
||||
HOOKDIR="dev/hooks"
|
||||
|
||||
echo -n "Installing hooks..."
|
||||
for hook in pre-commit pre-push
|
||||
for hook in pre-commit post-commit pre-push
|
||||
do
|
||||
rm -f "${GIT_DIR}/hooks/${hook}"
|
||||
if [ -f "${HOOKDIR}/${hook}.sh" ]; then
|
||||
|
@ -2,12 +2,13 @@
|
||||
# file: make-distribution.sh
|
||||
# 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,
|
||||
# no matter from which directory we'll run script
|
||||
GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
|
||||
if [ "$GIT_DIR" != "" ] ; then
|
||||
[[ "$GIT_DIR" != "/"* ]] && GIT_DIR="${PWD}/${GIT_DIR}"
|
||||
cd "$GIT_DIR/.." || exit 1
|
||||
else
|
||||
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"
|
||||
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!
|
||||
|
||||
@ -49,22 +50,31 @@ done
|
||||
# dwonload JSON.sh
|
||||
echo "Inject JSON.sh"
|
||||
JSONSHFILE="JSON.sh/JSON.sh"
|
||||
if [ ! -f "${JSONSHFILE}" ]; then
|
||||
if [ ! -r "${JSONSHFILE}" ]; then
|
||||
mkdir "JSON.sh" 2>/dev/null
|
||||
curl -sL -o "${JSONSHFILE}" "https://cdn.jsdelivr.net/gh/dominictarr/JSON.sh/JSON.sh"
|
||||
chmod +x "${JSONSHFILE}"
|
||||
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
|
||||
echo "Create html doc"
|
||||
#shellcheck disable=SC1090
|
||||
source "$GIT_DIR/../dev/make-html.sh"
|
||||
# shellcheck disable=SC1090,SC1091
|
||||
source "../../dev/make-html.sh"
|
||||
|
||||
# create archive
|
||||
cd .. || exit 1
|
||||
echo "Create dist archives"
|
||||
zip -rq "${DISTNAME}-${VERSION}.zip" "${DISTNAME}"
|
||||
tar -czf "${DISTNAME}-${VERSION}.tar.gz" "${DISTNAME}"
|
||||
# shellcheck disable=SC2046
|
||||
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!"
|
||||
|
||||
|
7
dev/make-distribution.sh.exclude
Normal file
7
dev/make-distribution.sh.exclude
Normal file
@ -0,0 +1,7 @@
|
||||
data-bot-bash/*
|
||||
*.jssh
|
||||
botacl
|
||||
*.flock
|
||||
*.log
|
||||
*.last
|
||||
*.ok
|
@ -5,12 +5,13 @@
|
||||
# If you your bot is finished you can use make-standalone.sh to create the
|
||||
# the old all-in-one bashbot: bashbot.sh and commands.sh only!
|
||||
#
|
||||
#### $$VERSION$$ v1.1-0-gc0eb399
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# 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 2>/dev/null)
|
||||
if [ "$GIT_DIR" != "" ] ; then
|
||||
[[ "$GIT_DIR" != "/"* ]] && GIT_DIR="${PWD}/${GIT_DIR}"
|
||||
cd "$GIT_DIR/.." || exit 1
|
||||
else
|
||||
[ ! -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
|
||||
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
|
||||
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"
|
||||
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 -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
|
||||
chmod +x bashbot.sh.min
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# shellcheck disable=SC2028,2016
|
||||
# shellcheck disable=SC2028,SC2016,SC1117
|
||||
# joke hack to obfuscate bashbot.min.sh
|
||||
|
||||
infile="bashbot.sh"
|
||||
|
@ -1,4 +1,4 @@
|
||||
# list of additional files to check from shellcheck
|
||||
#### $$VERSION$$ v1.1-0-gc0eb399
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
bashbot.rc
|
||||
mycommands.sh.clean
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
#### $$VERSION$$ v1.1-0-gc0eb399
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
# shellcheck disable=SC2016
|
||||
#
|
||||
# Easy Versioning in git:
|
||||
|
@ -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)
|
||||
```
|
||||
|
||||
### 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
|
||||
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)
|
||||
|
||||
#### $$VERSION$$ v1.1-0-ge835bbc
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
|
@ -65,5 +65,5 @@ group. This step is up to you actually.
|
||||
#### [Prev Installation](0_install.md)
|
||||
#### [Next Getting started](2_usage.md)
|
||||
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
|
@ -29,6 +29,15 @@ Have FUN!
|
||||
├── commands.sh # command dispatcher - DO NOT EDIT!
|
||||
├── 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
|
||||
│ └── 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
|
||||
```
|
||||
|
||||
### User stats
|
||||
### Scripts in bin/
|
||||
|
||||
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:
|
||||
|
||||
```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
|
||||
@ -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
|
||||
* ```${SERVICE[NEWPHOTO]}```: New Chat Picture
|
||||
* ```${MESSAGE}```: /_new_chat_picture SENDER URL
|
||||
* ```${SERVICE[PINNED]}```: Pinned Message structure
|
||||
* ```${SERVICE[PINNED]}```: Pinned MESSAGE ID
|
||||
* ```${MESSAGE}```: /_new_pinned_message SENDER ID
|
||||
* ```${PINNED[ID]}```: Id 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[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
|
||||
|
||||
#### sending messages
|
||||
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:
|
||||
```bash
|
||||
send_text_message "${CHAT[ID]}" "lol"
|
||||
send_normal_message "${CHAT[ID]}" "lol"
|
||||
```
|
||||
To send text with markdown:
|
||||
```bash
|
||||
@ -283,5 +340,5 @@ send_action "${CHAT[ID]}" "action"
|
||||
#### [Prev Create Bot](1_firstbot.md)
|
||||
#### [Next Advanced Usage](3_advanced.md)
|
||||
|
||||
#### $$VERSION$$ v1.1-0-gc0eb399
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
|
@ -106,7 +106,7 @@ echo -e "Your Message: ${test}\nbye!"
|
||||
#### 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.
|
||||
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:
|
||||
```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.
|
||||
|
||||
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
|
||||
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.,
|
||||
@ -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.
|
||||
|
||||
|
||||
### 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
|
||||
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[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[DESC]}```: Description text for error
|
||||
* ```${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)
|
||||
#### [Next Expert Use](4_expert.md)
|
||||
|
||||
#### $$VERSION$$ v1.2-dev-14-g6ec00d4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
|
@ -378,5 +378,5 @@ for every poll until the maximum of BASHBOT_SLEEP ms.
|
||||
#### [Prev Advanced Use](3_advanced.md)
|
||||
#### [Next Best Practice](5_practice.md)
|
||||
|
||||
#### $$VERSION$$ v1.2-dev-13-g2a5d47d
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
|
@ -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)
|
||||
#### [Next Functions Reference](6_reference.md)
|
||||
|
||||
#### $$VERSION$$ v1.2-dev-13-g2a5d47d
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
### Send, forward, delete messages
|
||||
|
||||
To insert line brakes in a message or caption you can place `\n` in the text.
|
||||
|
||||
##### send_action
|
||||
```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_normal_message
|
||||
```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``` 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"
|
||||
|
||||
@ -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_html_message
|
||||
```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
|
||||
@ -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)*
|
||||
|
||||
----
|
||||
|
||||
### 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
|
||||
@ -244,6 +327,19 @@ fi
|
||||
|
||||
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
|
||||
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:*
|
||||
```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
|
||||
@ -272,7 +368,7 @@ Return true (0) if user is admin or creator of given chat.
|
||||
|
||||
*example:*
|
||||
```bash
|
||||
if _is_admin ; then
|
||||
if user_is_admin "${CHAT[ID]}" ; then
|
||||
send_markdown_message "${CHAT[ID]}" "*LEAVING CHAT...*"
|
||||
leave_chat "${CHAT[ID]}"
|
||||
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)
|
||||
#### [Next Notes for Developers](7_develop.md)
|
||||
|
||||
#### $$VERSION$$ v1.2-dev-13-g2a5d47d
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
|
@ -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** 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
|
||||
|
||||
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)
|
||||
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'
|
||||
@ -347,5 +349,5 @@ fi
|
||||
|
||||
#### [Prev Function Reference](6_reference.md)
|
||||
|
||||
#### $$VERSION$$ v1.2-dev-13-g2a5d47d
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
|
@ -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
|
||||
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
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#### $$VERSION$$ v1.2-dev-13-g2a5d47d
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
######
|
||||
# parameters
|
||||
|
@ -2,7 +2,7 @@
|
||||
# file: run_filename
|
||||
# background job to display content of all new files in WATCHDIR
|
||||
#
|
||||
#### $$VERSION$$ v1.2-dev-13-g2a5d47d
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
######
|
||||
# parameters
|
||||
|
@ -2,7 +2,7 @@
|
||||
# file: run_filename
|
||||
# background job to display all new files in WATCHDIR
|
||||
#
|
||||
#### $$VERSION$$ v1.2-dev-13-g2a5d47d
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
######
|
||||
# parameters
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
######
|
||||
# parameters
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
# shellcheck disable=SC1117
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# adjust your language setting here
|
||||
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment
|
||||
|
@ -2,7 +2,7 @@
|
||||
# file. multibot.sh
|
||||
# description: run multiple telegram bots from one installation
|
||||
#
|
||||
#### $$VERSION$$ v1.2-dev-13-g2a5d47d
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
if [ "${2}" = "" ] || [ "${2}" = "-h" ]; then
|
||||
echo "Usage: $0 botname command"
|
||||
|
@ -7,7 +7,7 @@
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
|
||||
SHELL=/bin/sh
|
||||
|
@ -5,7 +5,7 @@
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
######
|
||||
# parameters
|
||||
|
@ -1,19 +1,25 @@
|
||||
#!/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=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!*'
|
||||
|
||||
# outside *xxxx* markup we need two \\ to escape a '_', e.g. -> my\\_stupid\\_bot
|
||||
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:*
|
||||
/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,
|
||||
z.B.:_ /newtrack Apple mavic.\*air
|
||||
/track /addkey _zusätzlicher Begriff zum Tracken_
|
||||
/addblack _Begriff darf nicht vorkommen_
|
||||
/delkey _lösche Begriff_
|
||||
/delblack _lösche Blacklist Begriff_
|
||||
|
||||
/listtrack _zeigt aktuell getrackte Begriffe_
|
||||
/delkey ALL _löscht alle Begriffe_
|
||||
/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.
|
||||
|
||||
*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
|
||||
.
|
||||
Du hast eine eigene Telegram Dealgruppe? Lade mich ein und alle in der Guppe können mich nutzen:
|
||||
'
|
||||
|
||||
# uncomment the following lines to overwrite info and help messages
|
||||
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?*
|
||||
Klicke hier -> @'"${ME//_/\\\\_}"' <- und schicke /start
|
||||
Klicke hier https://t.me/'"${ME//_/\\_}"' und schicke /start
|
||||
|
||||
*Meine Befehle*:
|
||||
/suche _- Suchen und Tracken von Dealz_
|
||||
/watch _- Beobachten von Amazon Artikeln_
|
||||
/gruppen _- Liste aller Dealz Gruppen_
|
||||
/hilfe _- Hilfe zu weiteren Befehlen_
|
||||
'"${bashbot_commands}"'
|
||||
|
||||
*Dein '"${ME//_/-}"'*
|
||||
https://dealz.rrr.de/amzdealz.html
|
||||
'
|
||||
|
||||
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*:
|
||||
/suche _- Suchen und Tracken von Dealz_
|
||||
/watch _- Beobachten von Amazon Artikeln_
|
||||
/gruppen _- Liste aller Dealz Gruppen_
|
||||
'"${bashbot_commands}"'
|
||||
|
||||
/info _- Info zum Bot_
|
||||
/help _- Zeigt diese Liste_
|
||||
|
||||
_https://dealz.rrr.de/assets/images/rdealomat.gif_
|
||||
*Dein '"${ME//_/-}"'*
|
||||
'
|
||||
|
||||
# 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"
|
||||
SORRYADMIN2="Dieser Befehl ist dem Botadmin vorbehalten, sorry."
|
||||
|
||||
# Set INLINE to 1 in order to receive inline queries.
|
||||
# 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
|
||||
FILE_REGEX='/home/deal-O-mat/.*'
|
||||
FILE_REGEX='/this_is_my_bot_path/.*'
|
||||
# run curl over TOR or SOCKS
|
||||
#export BASHBOT_CURL_ARGS="--socks5-hostname localhost"
|
||||
|
||||
@ -180,40 +103,32 @@ WELCOME_MSG="Willkommen"
|
||||
export REPORT_NEWMEMBER="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"
|
||||
SEARCHFILE="${DATADIR}/0-dealsearch"
|
||||
WATCHFILE="${DATADIR}/0-dealwatch"
|
||||
NOTIFYFILE="${DATADIR}/0-dealnotify"
|
||||
|
||||
if [ "$1" = "startbot" ];then
|
||||
# run once after startup when the first message is received
|
||||
my_startup(){
|
||||
# send reminder on startup, random delay
|
||||
send_normal_message "-10011894xxxxx" "${REMINDER}"
|
||||
}
|
||||
# mark startup, triggers action on first message
|
||||
setConfigKey "startupaction" "await"
|
||||
# create KEYOFILE DB if not exist
|
||||
# create Database files on startup
|
||||
jssh_newDB "${TRACKFILE}"
|
||||
jssh_newDB "${SEARCHFILE}"
|
||||
jssh_newDB "${WATCHFILE}"
|
||||
jssh_newDB "${NOTIFYFILE}"
|
||||
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...
|
||||
mycommands() {
|
||||
# action triggered on first message after startup
|
||||
if [[ "$(getConfigKey "startupaction")" != "done"* ]]; then
|
||||
setConfigKey "startupaction" "done $(date)"
|
||||
fi
|
||||
# a service Message was received
|
||||
local SILENCER="yes"
|
||||
if [[ "${SERVICE}" != "" ]]; then
|
||||
# example: dleted service messages
|
||||
if [ "${SILENCER}" = "yes" ]; then
|
||||
if [ "${SILENCER}" = "yes" ] && bot_is_admin "${CHAT[ID]}"; then
|
||||
delete_message "${CHAT[ID]}" "${MESSAGE[ID]}"
|
||||
fi
|
||||
fi
|
||||
@ -222,46 +137,35 @@ else
|
||||
[ -n "${REMOVEKEYBOARD}" ] && remove_keyboard "${CHAT[ID]}" "..." &
|
||||
[[ -n "${REMOVEKEYBOARD_PRIVATE}" && "${CHAT[ID]}" == "${USER[ID]}" ]] && remove_keyboard "${CHAT[ID]}" "..." &
|
||||
|
||||
######################
|
||||
# default commands
|
||||
# fix upper case first letter in commands
|
||||
[[ "${MESSAGE}" =~ ^/[[:upper:]] ]] && MESSAGE="${MESSAGE:0:1}$(tr '[:upper:]' '[:lower:]' <<<"${MESSAGE:1:1}")${MESSAGE:2}"
|
||||
|
||||
######################
|
||||
# default commands
|
||||
case "${MESSAGE}" in
|
||||
'/info'*)
|
||||
send_action "${CHAT[ID]}" "typing"
|
||||
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'*)
|
||||
send_action "${CHAT[ID]}" "typing"
|
||||
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
|
||||
;;
|
||||
'/start'*)
|
||||
send_markdown_message "${CHAT[ID]}" "${bashbot_info}"
|
||||
send_markdownv2_message "${CHAT[ID]}" "${bashbot_help}"
|
||||
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'*)
|
||||
#return 1 # no
|
||||
# but if we do, remove /edited_message
|
||||
MESSAGE="${MESSAGE#/* }"
|
||||
;;
|
||||
'/_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]}"\
|
||||
"${WELCOME_MSG} ${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]} (@${NEWMEMBER[USERNAME]})"
|
||||
MYSENTID="${BOTSENT[ID]}"
|
||||
@ -279,8 +183,8 @@ else
|
||||
##########
|
||||
# pre test for admin only commands
|
||||
case "${MESSAGE}" in
|
||||
# must be in private chat, group admin, or botadmin
|
||||
'/sea'*|'/su'*|'/add'*|'/new'*|'/del'*|'/tra'*|'/wat'*|'/noti'*|'/lista'*)
|
||||
# must be private, group admin, or botadmin
|
||||
'/sea'*|'/su'*|'/add'*|'/new'*|'/del'*|'/tra'*)
|
||||
send_action "${CHAT[ID]}" "typing"
|
||||
if ! user_is_admin "${CHAT[ID]}" "${USER[ID]}" ; then
|
||||
delete_message "${CHAT[ID]}" "${MESSAGE[ID]}"
|
||||
@ -289,21 +193,13 @@ else
|
||||
{ sleep 5; delete_message "${CHAT[ID]}" "${MYSENTID}"; } &
|
||||
return 1
|
||||
fi
|
||||
;;&
|
||||
# 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
|
||||
# ok, now lets process the real command
|
||||
;;
|
||||
esac
|
||||
|
||||
#################
|
||||
# search commands
|
||||
#local vairable, e.g. read/write Database
|
||||
local FINDKEYS OLDKEYS KEY MYSENTID
|
||||
declare -a KEYARR
|
||||
declare -A SEARCHVALUES
|
||||
@ -311,69 +207,30 @@ else
|
||||
#################
|
||||
# pre processing of search commands
|
||||
case "${MESSAGE}" in
|
||||
'/add'*|'/tra'*|'/noti'*) # add no arg
|
||||
'/add'*|'/tra'*) # add no arg
|
||||
FINDKEYS="${MESSAGE#/* }"
|
||||
if [ "${FINDKEYS}" = "${MESSAGE}" ]; then
|
||||
send_normal_message "${CHAT[ID]}" "Kein Begriff angegeben!"
|
||||
exit
|
||||
fi
|
||||
;;&
|
||||
'/addw'*|'/wat'*) OLDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${WATCHFILE}")"
|
||||
;;&
|
||||
'/add'[kbt]*|'/tra'*) OLDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${TRACKFILE}")"
|
||||
;;&
|
||||
'/noti'*) OLDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${NOTIFYFILE}")"
|
||||
;;&
|
||||
|
||||
'/addk'*|'/addt'*|'/tra'*) # add track
|
||||
MESSAGE="/newtrack ${FINDKEYS} ${OLDKEYS}"
|
||||
;;
|
||||
'/addb'*) # add black
|
||||
[[ "${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
|
||||
'/delk'*) #delete key
|
||||
OLDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${TRACKFILE}")"
|
||||
if [ "${OLDKEYS}" = "" ]; then
|
||||
send_markdown_message "${CHAT[ID]}" "*Kein Tracking aktiv!*"
|
||||
send_markdownv2_message "${CHAT[ID]}" "*Kein Tracking aktiv!*"
|
||||
return
|
||||
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%%|!*}"
|
||||
FINDKEYS="${MESSAGE#/* }"
|
||||
read -r -a KEYARR <<<"ALL ${KEY//|/ }"
|
||||
if [ "${FINDKEYS}" = "ALL" ]; then
|
||||
jssh_deleteKeyDB "${CHAT[ID]}" "${TRACKFILE}"
|
||||
send_markdown_message "${CHAT[ID]}" "*Tracking gelöscht!*"
|
||||
send_markdownv2_message "${CHAT[ID]}" "*Tracking gelöscht!*"
|
||||
return
|
||||
elif [[ "${FINDKEYS}" =~ ^[0-9]+$ ]]; then
|
||||
if [ "${#KEYARR[@]}" -lt "${FINDKEYS}" ]; then
|
||||
@ -386,7 +243,7 @@ else
|
||||
FINDKEYS="${KEYARR[*]}"
|
||||
if [ -z "${FINDKEYS}" ]; then
|
||||
jssh_deleteKeyDB "${CHAT[ID]}" "${TRACKFILE}"
|
||||
send_markdown_message "${CHAT[ID]}" "*Tracking gelöscht!*"
|
||||
send_markdownv2_message "${CHAT[ID]}" "*Tracking gelöscht!*"
|
||||
return
|
||||
else
|
||||
KEY="${OLDKEYS#*!}"
|
||||
@ -395,80 +252,15 @@ else
|
||||
fi
|
||||
fi
|
||||
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
|
||||
send_normal_message "${CHAT[ID]}" "${OUT}"
|
||||
else
|
||||
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"]'
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
'/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
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
@ -480,9 +272,9 @@ else
|
||||
FINDKEYS="${MESSAGE#/* }"
|
||||
if [ "${FINDKEYS}" = "${MESSAGE}" ]; then
|
||||
delete_message "${CHAT[ID]}" "${MESSAGE[ID]}"
|
||||
send_markdown_message "${CHAT[ID]}" "${bashbot_shelp}"
|
||||
send_markdownv2_message "${CHAT[ID]}" "${bashbot_shelp}"
|
||||
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}"
|
||||
else
|
||||
send_normal_message "${CHAT[ID]}" "${SORRYADMIN}"
|
||||
@ -491,15 +283,15 @@ else
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return
|
||||
return 1
|
||||
;;
|
||||
|
||||
'/newt'*) # newtrack
|
||||
FINDKEYS="${MESSAGE#/* }"
|
||||
FINDKEYS="${FINDKEYS%[\" ]}"
|
||||
FINDKEYS="${FINDKEYS#[\" ]}"
|
||||
if [ "${FINDKEYS}" = "${MESSAGE}" ]; then
|
||||
send_markdown_message "${CHAT[ID]}" "${bashbot_shelp}"
|
||||
if [ "${FINDKEYS}" = "" ]; then
|
||||
send_markdownv2_message "${CHAT[ID]}" "${bashbot_shelp}"
|
||||
else
|
||||
set_keys "${FINDKEYS}" "${TRACKFILE}"
|
||||
fi
|
||||
@ -508,181 +300,66 @@ else
|
||||
send_action "${CHAT[ID]}" "typing"
|
||||
FINDKEYS="$(jssh_getKeyDB "${CHAT[ID]}" "${TRACKFILE}")"
|
||||
if [ "${FINDKEYS}" = "" ]; then
|
||||
send_markdown_message "${CHAT[ID]}" "*Kein Tracking aktiv!*"
|
||||
send_markdownv2_message "${CHAT[ID]}" "*Kein Tracking aktiv!*"
|
||||
return
|
||||
fi
|
||||
OUT="Tracking nach \"${FINDKEYS}\" ist aktiv."
|
||||
# send keyboard in private chats only
|
||||
if [[ "${CHAT[ID]}" != "${USER[ID]}" ]]; then
|
||||
send_normal_message "${CHAT[ID]}" "${OUT}"
|
||||
else
|
||||
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
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
set_keys(){
|
||||
local MYFIND MYKEY MYKEYF MINLEN MYCHECK MYSEARCH
|
||||
local MYFIND MYKEY MYKEYF MINLEN MYSEARCH
|
||||
declare -A KEYARR
|
||||
MYFIND="$1"
|
||||
MYKEYF="$2"
|
||||
MINLEN="3"
|
||||
MINLEN="4"
|
||||
# check len of keys
|
||||
for MYKEY in ${MYFIND}; do [ "${#MYKEY}" -lt ${MINLEN} ] && break; done
|
||||
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
|
||||
MYFIND="$(create_pattern "${MYFIND}")"
|
||||
MYCHECK="$(check_pattern "${MYFIND}")"
|
||||
[[ "${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//[^|]}"
|
||||
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
|
||||
KEYARR["${CHAT[ID]}"]="${MYFIND}"
|
||||
jssh_updateDB "KEYARR" "${MYKEYF}"
|
||||
#jssh_insertDB "${CHAT[ID]}" "${MYFIND}" "${MYKEYF}"
|
||||
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
|
||||
}
|
||||
# place your processing functions here
|
||||
|
||||
|
||||
# $1 ARRAYNAME $2 command
|
||||
printKeys() {
|
||||
# $1 ARRAYNAME to print
|
||||
printKeys() {
|
||||
local key
|
||||
declare -n ARRAY="$1"
|
||||
for key in "${!ARRAY[@]}"
|
||||
do
|
||||
printf '%s - %s\n' "${key}" "${ARRAY[${key}]}"
|
||||
done
|
||||
}
|
||||
}
|
||||
|
||||
# create a regex from space sepeareted keywords
|
||||
# $1 space separated words
|
||||
create_pattern() {
|
||||
|
||||
# create a regex from space sepeareted keywords
|
||||
# $1 space separated words
|
||||
create_pattern() {
|
||||
local PATTERN KEY
|
||||
set -f
|
||||
for KEY in $1
|
||||
@ -690,28 +367,7 @@ fi
|
||||
[ "${PATTERN}" != "" ] && PATTERN="${PATTERN}|"
|
||||
PATTERN="${PATTERN}${KEY}"
|
||||
done
|
||||
# revome blank and "
|
||||
PATTERN="${PATTERN//[\" ]}"
|
||||
# remove * at start
|
||||
PATTERN="${PATTERN//|\*/|}"; PATTERN="${PATTERN#\*}"
|
||||
# remove unneeded |
|
||||
PATTERN="${PATTERN//||/|}"; PATTERN="${PATTERN#|}"; PATTERN="${PATTERN%|}"
|
||||
set +f
|
||||
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}"
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
######
|
||||
# parameters
|
||||
|
@ -5,7 +5,7 @@
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
######
|
||||
# parameters
|
||||
@ -24,7 +24,7 @@ export 'LANGUAGE=C.UTF-8'
|
||||
unset IFS
|
||||
# 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)?"
|
||||
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."
|
||||
@ -34,7 +34,7 @@ until [ "$SUCCESS" = "y" ] ;do
|
||||
case $answer in
|
||||
'Yass!') echo "Goody! mykeyboardendshere";SUCCESS=y;;
|
||||
'No') echo "Well that's weird. mykeyboardendshere";SUCCESS=y;;
|
||||
'') echo "empty answer!" && exit ;;
|
||||
'') echo "empty answer! Try again";;
|
||||
*) SUCCESS=n;;
|
||||
esac
|
||||
done
|
||||
|
@ -1,7 +1,7 @@
|
||||
# file: botacl
|
||||
# a user not listed here, will return false from 'user_is_allowed'
|
||||
#
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
# Format:
|
||||
# user:resource:chat
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
# to show how you can customize bashbot by only editing mycommands.sh
|
||||
# NOTE: this is not tested, simply copied from original source and reworked!
|
||||
#
|
||||
#### $$VERSION$$ v1.2-dev-13-g2a5d47d
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
#
|
||||
# shellcheck disable=SC2154
|
||||
# shellcheck disable=SC2034
|
||||
|
@ -5,7 +5,7 @@
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
#
|
||||
# will be automatically sourced from bashbot
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# will be automatically sourced from bashbot
|
||||
|
||||
|
@ -5,7 +5,8 @@
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# 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
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.2-dev-14-g6ec00d4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# will be automatically sourced from bashbot
|
||||
|
||||
@ -18,6 +18,7 @@ UNBAN_URL=$URL'/unbanChatMember'
|
||||
GETMEMBER_URL=$URL'/getChatMember'
|
||||
|
||||
# usage: status="$(get_chat_member_status "chat" "user")"
|
||||
# $1 chat # $2 user
|
||||
get_chat_member_status() {
|
||||
sendJson "$1" '"user_id":'"$2"'' "$GETMEMBER_URL"
|
||||
# shellcheck disable=SC2154
|
||||
@ -42,7 +43,14 @@ user_is_creator() {
|
||||
return 1
|
||||
}
|
||||
|
||||
# $1 chat
|
||||
bot_is_admin() {
|
||||
user_is_admin "$1" "$(getConfigKey "botid")"
|
||||
}
|
||||
|
||||
# $1 chat # $2 user
|
||||
user_is_admin() {
|
||||
[[ -z "$1" || -z "$2" ]] && return 1
|
||||
[ "${1:--}" == "${2:-+}" ] && return 0
|
||||
user_is_botadmin "$2" && return 0
|
||||
local me; me="$(get_chat_member_status "$1" "$2")"
|
||||
@ -50,7 +58,9 @@ user_is_admin() {
|
||||
return 1
|
||||
}
|
||||
|
||||
# $1 user
|
||||
user_is_botadmin() {
|
||||
[ -z "$1" ] && return 1
|
||||
local admin; admin="$(getConfigKey "botadmin")"; [ -z "${admin}" ] && return 1
|
||||
[[ "${admin}" == "${1}" || "${admin}" == "${2}" ]] && return 0
|
||||
#[[ "${admin}" = "@*" ]] && [[ "${admin}" = "${2}" ]] && return 0
|
||||
@ -58,6 +68,7 @@ user_is_botadmin() {
|
||||
return 1
|
||||
}
|
||||
|
||||
# $1 user # $2 key # $3 chat
|
||||
user_is_allowed() {
|
||||
[ -z "$1" ] && return 1
|
||||
# user can do everything
|
||||
|
@ -5,7 +5,7 @@
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
#
|
||||
# source from commands.sh to use jsonDB functions
|
||||
#
|
||||
@ -204,7 +204,7 @@ jssh_checkDB_async() { jssh_checkDB "$@"; }
|
||||
jssh_checkDB(){
|
||||
local DB
|
||||
[ -z "$1" ] && return 1
|
||||
[[ "$1" = *'..'* ]] && return 2
|
||||
[[ "$1" = *'../.'* ]] && return 2
|
||||
if [[ "$1" == "${BASHBOT_VAR:-.}"* ]] || [[ "$1" == "${BASHBOT_DATA:-.}"* ]]; then
|
||||
DB="${1}.jssh"
|
||||
else
|
||||
@ -296,7 +296,7 @@ jssh_countKeyDB_async() {
|
||||
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,._
|
||||
# $2 key value
|
||||
# $3 filename (must exist!), must be relative to BASHBOT_ETC, and not contain '..'
|
||||
|
@ -5,7 +5,8 @@
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# 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
|
||||
|
||||
@ -15,6 +16,7 @@ eval "$(basename "${BASH_SOURCE[0]}")(){ :; }"
|
||||
# source from commands.sh to use the sendMessage functions
|
||||
|
||||
MSG_URL=$URL'/sendMessage'
|
||||
EDIT_URL=$URL'/editMessageText'
|
||||
PHO_URL=$URL'/sendPhoto'
|
||||
AUDIO_URL=$URL'/sendAudio'
|
||||
DOCUMENT_URL=$URL'/sendDocument'
|
||||
@ -27,6 +29,10 @@ ACTION_URL=$URL'/sendChatAction'
|
||||
FORWARD_URL=$URL'/forwardMessage'
|
||||
ALBUM_URL=$URL'/sendMediaGroup'
|
||||
|
||||
#
|
||||
# send/edit message variants ------------------
|
||||
#
|
||||
|
||||
# $1 CHAT $2 message
|
||||
send_normal_message() {
|
||||
local len text; text="$(JsonEscape "${2}")"
|
||||
@ -47,54 +53,70 @@ send_normal_message() {
|
||||
|
||||
# $1 CHAT $2 message
|
||||
send_markdown_message() {
|
||||
local text; text="$(JsonEscape "${2}")"
|
||||
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
|
||||
_format_message_url "${1}" "${2}" ',"parse_mode":"markdown"' "${MSG_URL}"
|
||||
}
|
||||
|
||||
# $1 CHAT $2 message
|
||||
send_markdownv2_message() {
|
||||
local text; text="$(JsonEscape "${2}")"
|
||||
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
|
||||
_markdownv2_message_url "${1}" "${2}" ',"parse_mode":"markdownv2"' "${MSG_URL}"
|
||||
}
|
||||
|
||||
# $1 CHAT $2 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}")"
|
||||
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
|
||||
sendJson "${1}" '"text":"'"${text:0:4096}"'","parse_mode":"html"' "${MSG_URL}"
|
||||
sendJson "${1}" '"text":"'"${text:0:4096}"'"'"${3}"'' "${4}"
|
||||
text="${text:4096}"
|
||||
done
|
||||
}
|
||||
|
||||
# obsolote, will be removed after 1.0!!
|
||||
# $1 CHAT $2 message $3 keyboard
|
||||
old_send_keyboard() {
|
||||
local text; text='"text":"'$(JsonEscape "${2}")'"'
|
||||
shift 2
|
||||
local keyboard="init"
|
||||
OLDIFS="$IFS"
|
||||
IFS="\""
|
||||
for f in "$@" ;do [ "$f" != " " ] && keyboard="$keyboard, [\"$f\"]";done
|
||||
IFS="$OLDIFS"
|
||||
keyboard="${keyboard/init, /}"
|
||||
sendJson "${1}" "${text}"', "reply_markup": {"keyboard": [ '"${keyboard}"' ],"one_time_keyboard": true}' "$MSG_URL"
|
||||
send_normal_message "$(getConfigKey "botadmin")" "Warning: old 'send_keyboard' format is deprecated since version 0.6 and will be removed after 1.0 release!"
|
||||
# internal function, send/edit markdownv2 message with URL
|
||||
# $1 CHAT $2 message $3 action $4 URL
|
||||
_markdownv2_message_url() {
|
||||
local text; text="$(JsonEscape "${2}")"
|
||||
text="${text//$'\n'/\\n}"
|
||||
[ "${#text}" -ge 4096 ] && log_error "Warning: markdownv2 message longer than 4096 characters, message is rejected if formatting crosses 4096 border."
|
||||
# markdown v2 needs additional double escaping!
|
||||
text="$(sed -E -e 's|([_|~`>+=#{}()!.-])|\\\1|g' <<< "$text")"
|
||||
until [ -z "${text}" ]; do
|
||||
sendJson "${1}" '"text":"'"${text:0:4096}"'"'"${3}"'' "${4}"
|
||||
text="${text:4096}"
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# send keyboard, buttons, files ---------------
|
||||
#
|
||||
|
||||
# $1 CHAT $2 message $3 keyboard
|
||||
send_keyboard() {
|
||||
if [[ "$3" != *'['* ]]; then old_send_keyboard "${@}"; return; fi
|
||||
@ -168,7 +190,7 @@ else
|
||||
fi
|
||||
|
||||
upload_file(){
|
||||
local CUR_URL WHAT STATUS file="$2"
|
||||
local CUR_URL WHAT STATUS text=$3 file="$2"
|
||||
# file access checks ...
|
||||
[[ "$file" = *'..'* ]] && return # no directory traversal
|
||||
[[ "$file" = '.'* ]] && return # no hidden or relative files
|
||||
@ -214,7 +236,7 @@ upload_file(){
|
||||
;;
|
||||
esac
|
||||
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
|
||||
@ -238,6 +260,10 @@ send_venue() {
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# other send message variants ---------------------------------
|
||||
#
|
||||
|
||||
# $1 CHAT $2 from chat $3 from msg id
|
||||
forward_message() {
|
||||
[ -z "$3" ] && return
|
||||
@ -253,7 +279,7 @@ send_message() {
|
||||
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')"
|
||||
#shellcheck disable=SC2001
|
||||
text="$(sed <<< "${text}" 's/ *mynewlinestartshere */\\n/g')"
|
||||
text="$(sed <<< "${text}" 's/ *mynewlinestartshere */\n/g')"
|
||||
text="${text//$'\n'/\\n}"
|
||||
[ "$3" != "safe" ] && {
|
||||
no_keyboard="$(sed <<< "${2}" '/mykeyboardendshere/!d;s/.*mykeyboardendshere.*/mykeyboardendshere/')"
|
||||
@ -282,7 +308,7 @@ send_message() {
|
||||
sent=y
|
||||
fi
|
||||
if [ -n "$file" ]; then
|
||||
send_file "$1" "$file" "$text"
|
||||
upload_file "$1" "$file" "$text"
|
||||
sent=y
|
||||
fi
|
||||
if [ -n "$lat" ] && [ -n "$long" ]; then
|
||||
|
@ -8,7 +8,8 @@
|
||||
# #### if you start to develop your own bot, use the clean version of this file:
|
||||
# #### 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
|
||||
@ -24,6 +25,11 @@ export res=""
|
||||
# Set INLINE to 1 in order to receive inline queries.
|
||||
# To enable this option in your bot, send the /setinline command to @BotFather.
|
||||
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
|
||||
# NOTE: this is a regex, not shell globbing! you must use a valid egex,
|
||||
# '.' matches any character and '.*' matches all remaining charatcers!
|
||||
@ -111,13 +117,13 @@ else
|
||||
|
||||
# example for actions based on chat or sender
|
||||
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"
|
||||
;;&
|
||||
*'+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"
|
||||
;;&
|
||||
'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"
|
||||
;;&
|
||||
esac
|
||||
@ -138,7 +144,7 @@ else
|
||||
'/echo'*)
|
||||
send_action "${CHAT[ID]}" "typing"
|
||||
if ! user_is_botadmin "${USER[ID]}" ; then
|
||||
send_markdown_message "${CHAT[ID]}" "*${NOTBOTADMIN}*"; return 1
|
||||
send_markdownv2_message "${CHAT[ID]}" "*${NOTBOTADMIN}*"; return 1
|
||||
fi
|
||||
;;
|
||||
# will we process edited messages also?
|
||||
@ -148,7 +154,7 @@ else
|
||||
MESSAGE="${MESSAGE#/* }"
|
||||
;;
|
||||
'/_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]}"\
|
||||
"${WELCOME_MSG} ${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]} (@${NEWMEMBER[USERNAME]})"
|
||||
MYSENTID="${BOTSENT[ID]}"
|
||||
@ -161,6 +167,11 @@ else
|
||||
[ -n "${REPORT_LEFTMEMBER}" ] && send_normal_message "$(getConfigKey "botadmin")"\
|
||||
"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
|
||||
|
||||
case "${MESSAGE}" in
|
||||
@ -172,7 +183,7 @@ else
|
||||
'/question'*) # start interactive questions
|
||||
checkproc
|
||||
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
|
||||
send_normal_message "${CHAT[ID]}" "$MESSAGE already running ..."
|
||||
fi
|
||||
@ -180,12 +191,16 @@ else
|
||||
|
||||
'/cancel'*) # cancel interactive command
|
||||
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
|
||||
myback="notify"; checkback "$myback"
|
||||
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
|
||||
send_normal_message "${CHAT[ID]}" "Background command $myback already running ..."
|
||||
fi
|
||||
@ -207,7 +222,7 @@ else
|
||||
return 0
|
||||
;;
|
||||
'/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
|
||||
;;
|
||||
esac
|
||||
@ -275,7 +290,9 @@ else
|
||||
# return 0 to retry, return non 0 to give up
|
||||
bashbotBlockRecover() {
|
||||
# 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
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
# files: mycommands.sh.clean
|
||||
# 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.
|
||||
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,
|
||||
# '.' matches any character and '.*' matches all remaining charatcers!
|
||||
# additionally you must escape special characters with '\', e.g. '\. \? \[ \*" to match them literally
|
||||
@ -102,7 +106,7 @@ else
|
||||
return 0
|
||||
;;
|
||||
'/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
|
||||
;;
|
||||
esac
|
||||
|
@ -6,7 +6,7 @@
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
######
|
||||
# parameters
|
||||
|
@ -2,7 +2,7 @@
|
||||
#
|
||||
# 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,
|
||||
# no matter from which directory we'll run script
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# common variables
|
||||
export TESTME DIRME TESTDIR LOGFILE REFDIR TESTNAME
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
../dev/hooks/pre-commit.sh
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# file: b-example-test.sh
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# include common functions and definitions
|
||||
# shellcheck source=test/ALL-tests.inc.sh
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# include common functions and definitions
|
||||
# shellcheck source=test/ALL-tests.inc.sh
|
||||
@ -14,6 +14,7 @@ set -e
|
||||
$TESTTOKEN
|
||||
nobody
|
||||
botadmin
|
||||
|
||||
EOF
|
||||
echo "${SUCCESS}"
|
||||
|
||||
@ -44,7 +45,3 @@ trap '' EXIT
|
||||
cd "${DIRME}" || exit 1
|
||||
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"; }
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.2-dev-13-g2a5d47d
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# include common functions and definitions
|
||||
# shellcheck source=test/ALL-tests.inc.sh
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# include common functions and definitions
|
||||
# shellcheck source=test/ALL-tests.inc.sh
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# include common functions and definitions
|
||||
# shellcheck source=test/ALL-tests.inc.sh
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# include common functions and definitions
|
||||
# shellcheck source=test/ALL-tests.inc.sh
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# include common functions and definitions
|
||||
# shellcheck source=test/ALL-tests.inc.sh
|
||||
|
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
#### $$VERSION$$ v1.0-0-g99217c4
|
||||
#### $$VERSION$$ v1.20-0-g2ab00a2
|
||||
|
||||
# include common functions and definitions
|
||||
# shellcheck source=test/ALL-tests.inc.sh
|
||||
|
Loading…
Reference in New Issue
Block a user