Die Abenteuer des HiQ Smart Bots/The Adventures of the HiQ Smart Bot (Deu/Eng)

View this thread on: d.buzz | hive.blog | peakd.com | ecency.com
·@quekery·
0.000 HBD
Die Abenteuer des HiQ Smart Bots/The Adventures of the HiQ Smart Bot (Deu/Eng)
![image.png](https://files.peakd.com/file/peakd-hive/quekery/Ep3cNfoeM5SW4gENEYq7vHrcwB22LwQBQPdSfxvg89kMV8msjksc35sSA1DMNaapFuk.png)

<div class="pull-left">

Wie ihr vielleicht in der [HiQ №17](https://peakd.com/hiq/@hiq/hiq-17-or-smart-stylish-and-sexy-or-hiqs-swiss-hive-nectar-queen-token-task-force-interview-mit-gamergeek56-black-and-white-com) gelesen habt, bastle ich einen Discord Bot. Dieser soll uns, dem Team HiQuarters 2.0, etwas Arbeit erleichtern und ist für mich auch eine gute Gelegenheit etwas in Python reinzufomoen. Als Anfänger hatte ich so einige Hürden, welche mich um den Schlaf gebracht haben. Und ich hatte auch etwas Support, um diese zu überwinden. 

<h2>Die Sache mit dem Server </h2>
Wenn man erst mal einen Bot hat, möchte man natürlich auch, dass dieser nicht ständig auf dem eigenen Rechner läuft. Also holt man sich einen günstigen Server bei Privex. Die Warnung, dass dieser nur IPV6 kann, habe ich natürlich im Jahr 2022 ignoriert.

Als ich mein Bot-Skript dann auf dem Server starten wollte, hagelte es Fehlermeldungen. Ein freundlicher User, welcher noch keinen Hive Account hat, fand aber den Fehler. Die Hive-Api-Nodes können fast alle nur IPV4. Glücklicherweise kann immerhin *deathwing* IPV6, weshalb ich jetzt nur noch diese Api-Node verwenden kann.

Da ich noch nie Linux bzw. Debian genutzt habe, war es für mich auch nicht gerade leicht den Bot auf dem Server zum Laufen zu bekommen. Tutorials fand ich auch keine. Aber auch hier konnte mir besagter User weiterhelfen. Mit 1-2 Tips von weiteren Hivians kann ich nun die wichtigsten Befehl, um den Bot auf dem Privex-Server zuverlässig laufen zu lassen.
</div>

<div class="pull-right">

As you may have read in the [HiQ №17](https://peakd.com/hiq/@hiq.magazine/hiq-17-or-smart-stylish-and-sexy-or-hiqs-swiss-hive-nectar-queen-token-inspectors-interview-with-gamergeek56-black-and-white-co), I'm building a Discord bot. This should make some work easier for us, Team HiQuarters 2.0, and is also a good opportunity for me to learn Python. As a beginner I had some hurdles which made me lose sleep. And I also had some support to overcome them.    

<h2>The thing with the server</h2>
Once you have a bot, of course you want it not to run on your own computer all the time. So you get a cheap server at Privex. Of course I ignored the warning that it can only do IPV6 in 2022.

When I then wanted to start my bot script on the server, it hailed error messages. But a friendly user, who doesn't have a Hive account yet, found the error. The Hive api nodes can almost all only IPV4. Fortunately at least *deathwing* can do IPV6, so now I can only use this api node.

Since I have never used Linux or Debian, it was not easy for me to get the bot running on the server. I didn't find any tutorials either. But also here said user could help me. With 1-2 tips from other Hivians I can now the most important commands to run the bot on the Privex server reliably.
</div>

<hr>

<div class="pull-left">

<h2>Bug bei der Pool-Abfrage</h2>
Im weiteren Verlauf der Bot Odyssey stellte sich ein Fehler beim Auslesen der Pool-Daten heraus. Falls ihr die [HiQ №17](https://peakd.com/hiq/@hiq/hiq-17-or-smart-stylish-and-sexy-or-hiqs-swiss-hive-nectar-queen-token-task-force-interview-mit-gamergeek56-black-and-white-com) nicht gelesen habt. Der Bot hat eine Funktion, mit der man auslesen kann wie viele Leute in einen Pool gefomot sind und gibt detaillierte Daten darüber via CSV-Datei aus. Bei wiederholten Abfragen dieser Daten aktualisierten sich diese aber nicht.

Dieser Fehler hat mich fast um den Verstand gebracht. ;)
Ich habe so viel versucht. Lokale Variablen statt Klassenvariablen, einen Destruktor nutzen etc.. Die Lösung war allerdings recht simpel. Die Klasse der Bibliothek *hiveengine*, womit ich mir die Daten hole, hatte ich global instanziiert. Sobald ich also den Bot startete, holte er sich die Daten und hat sie dann natürlich nicht mehr aktualisert. NOOB!

Also habe ich die Klasse erst in meiner Klasse instanziiert und wie von Zauberhand funktionierte der Befehl nun zuverlässig.


Ein kleiner Fun Fact am Rande: Im Jahre 2022 bekommen es diverse Programme wie Excel oder Google Docs nicht hin, die CSV Datei ordentlich zu formatieren. Das Problem ist, dass die Api für Nachkommastellen einen Punkt benutzt. In Deutschland benutzt man dafür aber ein Komma. Nun kann man in den meisten Programmen die Formatierung nicht einfach auf die englische Schreibweise umstellen. Bei Excel hilft es das Programm auf englisch zu stellen. Bei Google geht es gar nicht, soweit ich weiß. 
</div>

<div class="pull-right">

<h2>Bug in the pool query </h2>
In the further course of the Bot Odyssey, a bug turned out when reading the pool data. In case you haven't read the [HiQ №17](https://peakd.com/hiq/@hiq.magazine/hiq-17-or-smart-stylish-and-sexy-or-hiqs-swiss-hive-nectar-queen-token-inspectors-interview-with-gamergeek56-black-and-white-co). The bot has a function to read how many people are fomoed in a pool and outputs detailed data about it via CSV file. However, when repeatedly querying this data, it did not update.

This error almost drove me out of my mind. ;)
I tried so many things. Local variables instead of class variables, using a destructor etc.... But the solution was quite simple. The class of the library *hiveengine*, with which I get the data, I had instantiated globally. So as soon as I started the bot, it fetched the data and then of course didn't update it. NOOB!

So I instantiated the class in my class first and like magic the command now worked reliably.

<img scr="https://i.imgur.com/XXqtpc6.png">

A little fun fact on the side: In 2022, various programs like Excel or Google Docs don't get it to format the CSV file properly. The problem is that the Api uses a dot for decimal places. In Germany, however, a comma is used for this. Now in most programs you can't simply change the formatting to the English notation. With Excel it helps to set the program to English. With Google it does not work at all, as far as I know.   
</div>
<img src="https://i.imgur.com/XXqtpc6.png">

<div class="pull-left">

<h2> Nie wieder manueller Payout? </h2>
Was der Bot auch können sollte, ist Anteile an HiQ Teammitglieder via Discordbefehl auszuzahlen. Dieser Befehl hat sich als sehr buggy herausgestellt. Mal ging er. Mal wurde mir ein Fehler geschmissen. 

<img src="https://i.imgur.com/sXJD5sE.png">

In diesen Beispiel wurden 8 Transaktionen gemacht. (Anm. von @quekery: Im Beispiel ist der Fehler bereits behoben.) Wie ich später erfahren haben, kann man nur 5 Transaktionen pro Account pro Block machen. D.h. hätten sich jetzt die 8 Transaktionen auf z.B. 2 Blöcke verteilt, wären die Transfers ohne Probleme durchgegangen, in einem Block allerdings nicht. Da wir jetzt nicht enorm viele Transfers machen, reicht es z.B. immer ne Sekunde zu warten nach jedem Transfer.

Für die Zukunft ist das jedenfalls eine sehr nützliche Info. Auch für Anwendungsfälle wie Airdrops kann dieses Wissen nicht schaden. Man könnte für größere Airdrop sich auch eigene Transaktionen bauen, um diesen Fehler etwas professioneller zu umgehen, was mir im HE Discord geraten wurde.
</div>

<div class="pull-right">

<h2> No more manual payout? </h2>
What the bot should also be able to do is pay out shares to HiQ team members via Discord command. This command turned out to be very buggy. Sometimes it worked. Sometimes it threw me an error. 

<img src="https://i.imgur.com/sXJD5sE.png">

In this example, 8 transactions were made. (Note from @quekery: In the example, the error is already fixed.) As I learned later, you can only make 5 transactions per account per block. I.e. if the 8 transactions had been spread over e.g. 2 blocks, the transfers would have gone through without problems, but not in one block. Since we don't do a lot of transfers now, it's enough to wait a second after each transfer.

Anyway, for the future this is a very useful info. Also for use cases like airdrops this knowledge can't hurt. You could also build your own transactions for larger airdrops to avoid this error a bit more professionally, which was advised to me in the HE Discord.
</div>

<hr>

<div class="pull-left">

<h2> USP für den Bot </h2>
Was macht man jetzt mit so einem Bot, wenn man ihn erst mal hat? Naja, neben Aufgabenerleichterungen spielt man natürlich auch etwas mit den Möglichkeiten. Dabei entstehen viele "Nonsensfunktionen". Eines Abends hatte @mugglow die Idee, dass der Bot random Hive-Memes posten könnte. 10 min später konnte der Bot z.B. das:
</div>

<div class="pull-left">

<h2> USP for the bot </h2> 
What do you do with such a bot once you have it? Well, in addition to making tasks easier, you naturally also play with the possibilities. In the process, many "nonsense functions" are created. One evening @mugglow had the idea that the bot could post random Hive memes. 10 min later the bot could do this:
</div>

<img src="https://i.imgur.com/u4IoPBL.png
">

<div class="pull-left">

Scheinbar war diese Funktion Grund genug für @captaincryptic den Bot auch auf den LOLZ Discord einzuladen. Nur blöd, dass der Bot noch nicht für andere Discord-Server konzipiert war - insbesondere die "Nonsensfunktionen" nicht.

Dies war aber eine gute Gelegenheit auch den Umgang mit anderen Discord Servern zu erproben. Auch die deutschen Texte, die der Bot so ausspuckt, habe ich mit der Hilfe von @thatgermandude ins englische Übersetzt.
</div>

<div class="pull-right">

Apparently this function was reason enough for @captaincryptic to invite the bot also on the LOLZ Discord. Just stupid that the bot was not yet designed for other Discord servers - especially the "nonsense functions" were not.

But this was a good opportunity to test also the handling with other Discord servers. I also translated the German texts that the bot spits out into English with the help of @thatgermandude.  
</div>

![](https://i.imgur.com/T87pmNn.png)

<div class="pull-left">

Im Bild seht ihr übrigens eine Chatfunktion. Wieder so eine "Nonsensfunktione". 😅

<h2> Error Handling </h2>
Was mir auch etwas Kopfzerbrechen bereitet hat, ist der Umgang mit Fehlern. Aber mit etwas Übung geht das mittlerweile ganz gut. Die Bibliothek *discord*, welche ich benutze, ist auch ganz gut damit. Aber bei Hive oder Hive Engine Funktionen muss ich natürlich auch solche Fehler auffangen.

Bei meinen ersten Experimenten mit der Bibliothek *discord* habe ich das Event *on_message* benutzt. Mir wurde aber geraten Commands zu benutzen. Dabei habe ich festgestellt, dass es viel besser Funktioniert mit Fehlern umzugehen und auch einfacher ist, Commands für bestimmte Server, Rollen oder Channel zu limitieren.

```Python
def check_guild():
    def predicate(ctx):
        return ctx.guild.id==913981667469819904 or ctx.guild.id==853303046431572038
    return commands.check(predicate)

@bot.command(name='wallet', help='use **$wallet user TOKEN** to get infos about the liquid asset.')
@commands.check_any(commands.has_role('Registered'), check_guild())
async def wallet(ctx, arg1, arg2):    
    try:
        tokens=Tokens(arg1)        
        tokens.get_token_info(arg2)        
        if tokens.symbol==-1:
            raise AccountDoesNotExistsException        
        await ctx.send(tokens.balance +' '+ tokens.symbol)
    except AccountDoesNotExistsException:
        await ctx.send('Wrong Account or Token')
    
@wallet.error
async def wallet_error(ctx, error):
    if isinstance(error, commands.MissingRole):
        await ctx.send('[REDACTED]')
    else:
        await ctx.send(str(error))
```

Mit diesen Command zum Beispiel kann man auslesen, wie viele Tokens eines bestimmten Tokens in einer Wallet sind.

![](https://i.imgur.com/UVb3rrH.png)

Den Befehl habe ich derzeit auf 2 Server limitiert. Außerdem kann man den Befehl benutzen, wenn man eine bestimmte Rolle hat. Jetzt könnte man zum Beispiel den User oder den Token falsch schreiben.

![](https://i.imgur.com/9PN8tl1.png)

Und zack der Bot schmeißt uns eine Fehlermeldung aus.

<h2> To Do </h2>
In naher Zukunft braucht der Bot noch einige Funktionen, die wichtig und nützlich sind für das Team HiQuarters 2.0, wie HIQS Discountsale, Registrierung und das automatische Verteilen der HiQ Subscriberbadge. Auch muss ich noch alle *on_message* Befehle in Commands umschreiben.

Wer weiß auf welche Server sich der HiQ Smart Bot noch so verirren wird und welche Funktionalitäten daraus entstehen werden.

Solltet ihr den HiQ Smart Bot oder Funktionen auch haben wollen, dann meldet euch bei mir. Wir finden bestimmt eine Übereinkunft.
</div>

<div class="pull-right">

By the way, in the picture you can see a chat function. Again such a "nonsense function". 😅

<h2> Error Handling </h2>
What also gave me some headaches is the handling of errors. But with a little practice, it works pretty well by now. The library *discord*, which I use, is also quite good with it. But with Hive or Hive Engine functions I have to catch such errors of course.

In my first experiments with the library *discord* I used the event *on_message*. But I was advised to use commands. I found out that it is much better to handle errors and also easier to limit commands for certain servers, roles or channels.

```Python
def check_guild():
    def predicate(ctx):
        return ctx.guild.id==913981667469819904 or ctx.guild.id==853303046431572038
    return commands.check(predicate)

@bot.command(name='wallet', help='use **$wallet user TOKEN** to get infos about the liquid asset.')
@commands.check_any(commands.has_role('Registered'), check_guild())
async def wallet(ctx, arg1, arg2):    
    try:
        tokens=Tokens(arg1)        
        tokens.get_token_info(arg2)        
        if tokens.symbol==-1:
            raise AccountDoesNotExistsException        
        await ctx.send(tokens.balance +' '+ tokens.symbol)
    except AccountDoesNotExistsException:
        await ctx.send('Wrong Account or Token')
    
@wallet.error
async def wallet_error(ctx, error):
    if isinstance(error, commands.MissingRole):
        await ctx.send('[REDACTED]')
    else:
        await ctx.send(str(error))
```

With this command for example you can read out how many tokens of a certain token are in a wallet.

![](https://i.imgur.com/UVb3rrH.png)

I have currently limited the command to 2 servers. Also, you can use the command if you have a specific role. Now you could misspell the user or token for example.

![](https://i.imgur.com/9PN8tl1.png)

And wham the bot throws us an error message.

<h2> To Do </h2> 
In the near future, the bot still needs some functions that are important and useful for Team HiQuarters 2.0, like HIQS Discountsale, registration and automatic distribution of the HiQ Subscriberbadge. Also, I still need to rewrite all *on_message* commands into commands.

Who knows on which servers the HiQ Smart Bot will get lost and which functionalities will result from it.

If you want to have the HiQ Smart Bot or some of its functions, please contact me. We will surely find an agreement.
</div>
👍 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,