Writing a Hive bot with beem

in Programming & Dev3 years ago

Introduction

Something I have wanted to do for a while was to try creating a bot that can respond to Hive posts based on some criteria. The idea for a project came about when I noticed that some people had mis-spelled the #proofofbrain tag. And so @proofofbrian was born!

To implement this I made use of the beem library. I have used this before to compile my #BritList posts, but that was a read-only process. It does seem the project creator @holger80 has been absent for a while, but others are maintaining it. I had a lot of help from @foxon in the Discord channel. Part of the problem was that I was using an old version. I use the Anaconda build of Python on Ubuntu and that was not finding the very latest version using the conda package manager, but I could get it using pip. Before I updated I was getting various errors when trying to use the account posting key, so that is something to check.

What I wanted to achieve was:

  • Check the post stream for those using the #proofofbrian tag.
  • Leave a comment and a small vote.
  • Log the user so they would not get this comment again.

There are various ways to avoid putting a private key in your code, but I opted for a local text file. beem can encrypt it if you prefer. Even if I exposed it the posting key of a low value account is not too useful.

I have another file for logging people who have been notified of their mistake. I was going to put animated GIFs in the comments, but used some images from Wikimedia instead. One issue I have not resolved is that the random picker seems to keep getting the same one.

Otherwise it seems to be working fine. I did do some tests such as creating comments against my own posts that I could just delete.

You can see the script is pretty short. beem does all the heavy lifting of blockchain operations. I tested it in Jupyter Notebook as it is convenient for playing around with things like this.

I am not sure if Hive really needs this particular bot. There are only a few such posts each day and I would hope people would take the hint, especially if they actually want the POB tokens. I could probably run it on a Raspberry Pi to have it up all the time. I may try that anyway. For now I have just run it during the day.

I hope others can gain some value from this. There are some links below to posts that inspired and informed me.

Please let me know if there are better ways to do any of this.

The Code

#!/usr/bin/env python
# coding: utf-8

from datetime import datetime, timedelta, date
from beem import Hive
from beem.account import Account
from beem.amount import Amount
from beem.blockchain import Blockchain
from beem.comment import Comment
from beem.exceptions import ContentDoesNotExistsException
from beem.instance import set_shared_blockchain_instance
import random

notified = []
with open('notified.txt','r') as f:
    for l in f:
        notified.append(l.strip())
        
posting = ''
with open('posting.txt','r') as f:
    for l in f:
        posting = l.strip()
        
postacc = 'proofofbrian'

hive = Hive(node=['https://api.hive.blog'], keys={'posting':posting})
set_shared_blockchain_instance(hive)
chain = Blockchain()

gifs=[
    {'Pic':'https://upload.wikimedia.org/wikipedia/commons/0/0a/Brian_May_2015.jpg', 'Source':'https://commons.wikimedia.org/wiki/File:Brian_May_2015.jpg'}, 
    {'Pic':'https://upload.wikimedia.org/wikipedia/commons/thumb/f/f1/Professor_Brian_Cox_OBE_FRS.jpg/320px-Professor_Brian_Cox_OBE_FRS.jpg', 'Source':'https://commons.wikimedia.org/wiki/File:Professor_Brian_Cox_OBE_FRS.jpg'}, 
    {'Pic':'https://upload.wikimedia.org/wikipedia/commons/thumb/c/c4/Brian_Cant_2008.jpg/450px-Brian_Cant_2008.jpg','Source':'https://commons.wikimedia.org/wiki/File:Brian_Cant_2008.jpg'},
    {'Pic':'https://upload.wikimedia.org/wikipedia/commons/thumb/2/2d/Brian_Cox_%282016%29_-_01.jpg/361px-Brian_Cox_%282016%29_-_01.jpg', 'Source':'https://commons.wikimedia.org/wiki/File:Brian_Cox_(2016)_-_01.jpg'},
    {'Pic':'https://upload.wikimedia.org/wikipedia/commons/thumb/3/36/Brian_Johnson.jpg/481px-Brian_Johnson.jpg', 'Source':'https://commons.wikimedia.org/wiki/File:Brian_Johnson.jpg'}
]

def addComment(comm):
    image = random.choice(gifs)
    text = f'''Here is your Proof of Brian. I think you meant #ProofOfBrain
![Brian]({image["Pic"]})
[Source]({image["Source"]})'''
    comm.reply(body=text,author=postacc)
    #return text

tracktag = 'proofofbrian'
while True:
    try:
        for post in chain.stream(opNames="comment", threading=True, thread_num=5):
            author = post['author']
            c = Comment(post)
            if c.is_main_post() and tracktag in post['tags'] and author not in notified:
                print('Found one', author,post['title'], post['timestamp'])
                print(post['tags'])
                addComment(c)
                c.upvote(voter=postacc)
                notified.append(author)
                with open('notified.txt', 'a') as f:
                    f.write(f'{author}\n')
    except Exception as error:
        print(repr(error))
        continue

Reference

Sort:  

Good work!

Correct me if I got it wrong. Does the main loop work on live stream and doesn't keep track of where it began tracking? Meaning if you stop and later restart all the posts in between aren't checked.

!BEER

You can specify a block to start on, so you can go back. I was not so worried about that as I would not miss many cases anyway.

!BEER

Cool. I am asking just in case. Maybe I will reuse your script... :)

Thanks for your effort.

!BEER

Feel free. The documentation is pretty good and you can get help in the Discord.

I will have to look in to this. I think I had issues with pip last time I tried to get beem working. It was some time ago.. and the windows version.

That is really cool. I wish I was more into coding than I am. I am just lazy and don't have the attention for it though. My hats off to those of you that have the patience for it!

I do it for a living and am happy to do that in Python lately. This can be considered extra practice, but I find it fun too.

As long as it is fun, that is all that matters! :)


The rewards earned on this comment will go directly to the person sharing the post on Twitter as long as they are registered with @poshtoken. Sign up at https://hiveposh.com.

Wow

I see you are new to Hive. Writing 'wow' will not get you far. People expect to actually hear what you think of something before they consider giving a vote.

Make sure you spell tags correctly, but it's better to engage with people than with bots.

Thank you for the advice sir