I recently released the bot called TrendChecker, which helps you to find out how high your post is in Hot/Trending/Promoted. If my bot receives a transaction with a valid url as the memo it checks where your post is in Hot or Trending and then sends your money back. The bot is completely build only with steem-python. This is a tutorial for people who are interested in the code behind the project and want to learn something about steem-python and how to develop bots for Steem. I will try to explain the backbone of this project and explain one aspect that might help you with your project.
What will I learn?
- How to find out how high your post is in Hot or Trending.
- How to check for incoming transactions.
Requirements
- Python 3.6
- steem-python
- requests (only if you want to run the full bot)
Difficulty
- Basic
Tutorial Contents
Setup
This is pretty simple because it is basically the same for every project: just import Steem and initialize the class. In addition, you will need the build in module json
. In addition, I created two .json
files: the first is for storing the account name and the private keys and the second is to avoid double spending. More on that later on in the tutorial.
Finding a specific post in Hot or Trending
Only a very small percentage of all posts reach the general top 100 of Hot or Trending and therefore we want to get the top 100 for every tag of our post.
To get the tags we need to use s.get_content(author,permlink)
. However, the user only sent us a full url of the post with this format: steemit.com/main-tag/@author/permlink
. If we split this url every time a “/” comes up the author will be fifth element and the permlink the sixth one. The only thing left to do is to remove the “@” from the string with the author’s name.
After getting the content, we can finally extract all the tags. However, these tags are located in the json_metadata
of the post and if we call post[“json_metadata”][“tags”]
we will get an error. We need to load this .json “file” as a json first and then we can get the tags.
Sometimes users send wrong urls and we don’t want our bot to stop. Therefore we will put these few lines of code into a try: | except:
construct. If something fails for whatever reason the bot will simply return "TRENDCHECKER error! wrong url or post doesn't exist..."
.
These are all the functions from the official documentation to get posts by some factor.
To try out which post they will return you can simply test most of them by going to the corresponding steemit.com url.
get_discussions_by_votes()
--> https://steemit.com/votes/
get_discussions_by_active()
--> https://steemit.com/active/
get_discussions_by_payout()
--> /payout/
Now we can get all hot, trending and promoted post for every tag in our list of tags. Then we will create 3 variables. Please note here that that could be done with only one variable! These variables will count what rank our post has in Hot/…. .
As the last step, we’ll create a for loop
for the Hot, Trending and Promoted posts. If the author of the post in one of this loops is equal to the author of our post we will stop the for loop
by writing break
. If this isn’t the case we will add 1 to our counter (variable).
Note: While I’m writing this tutorial I noticed that checking for the author isn’t enough because if you released multiple post in a short period of time they all could be in Hot/Trending. Now If your second post was more successful it likely surpassed the first post in its ranking. However, if your looking for your first post you will instead get the ranking of your second post. To fix this we will need to check if the permlink
is the same, too.
The beautiful ability of strings is that you can add them to each other similarly to numbers. For our memo (the message that will be send back to the user) we will start with a little “brand” message.
Now for every tag we’ll add (Tag):
to the memo. If the tag is nothing (general hot/trending page) we will add All:
.
If we find our matching post in Hot or Trending we will add str(rank) + “.” + “ in hot/trending/promoted”
.
After we gone through all post in Hot/Trending/Promoted we will add a simple comma as a separation.
The last step is to return this memo which will now be send back to the user.
Checking for incoming transactions
Obviously, we want our bot to run without any breaks and delays. Therefore the first thing we have to do is an infinitive loop
. The simplest one is while 1:
.
Secondly we need to import one more steem-python class to get the incoming transactions: the account class
.
It easily allows us to access account data. It needs to
be initialized with your account name and the Steem()
class.
With the help of this class we now can get our account history which we can filter_by transfer
. There is also another command for getting the account history which relies on the standard Steem class
.
The only catch with this function is that you can’t filter it.
The -1
sets the order: the newest transaction/index comes first. 500
is the limit of the history. Getting 500 items from our history is definitely overkill and we would need much less. However, if the bot was in real use and went down for some hours it would still process most transactions and send the money back after it went back online because your transaction is still likely to be within our limit of 500. If the limit were 3 and I got 3 Bid bot advertisements in that time frame the bot wouldn’t see your transaction and therefore not send your money back.
Next up are the conditions for when we want our bot to act:
- the transaction has never been processed before --> is not in our trx_list
- the transaction was sent to me not from me
- the transaction has a memo
- the memo contains a url
If all these conditions are true we can be pretty certain that the user wanted to use our bot. Now we can add this new trx_id
to our list of transaction so that it doesn’t get processed twice, generate a memo (discover where to post is in hot…) and send the money back to the user.
If you want me to cover these three functions write a comment down below.
Now we are basically finished, however, we want to ensure that our bot can run without any downtime. The bot sometimes failed at this part for whatever reason so we again put it in a try: | except:
construct. If the bot fails to execute these previous lines of code he waits 30 seconds and the initializes the Steem()
and Account()
Class again. For the ability to sleep we need to import the build in package time
.
With this code the bot ran successfully for 3-5 days straight. However, the bot stilled stopped once or twice with this error. If anyone could help me please write a comment or contact me on Discord (wil1liam#8715).
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "trendchecker.py", line 118, in <module>
s = Steem(node,keys=keys)
File "/home/konstantin/steem-python/steem/account.py", line 34, in __init__
self.refresh()
File "/home/konstantin/steem-python/steem/account.py", line 37, in refresh
account = self.steemd.get_account(self.name)
File "/home/konstantin/steem-python/steem/steemd.py", line 168, in get_account
return first(self.call('get_accounts', [account]))
File "/home/konstantin/steem-python/steembase/http_client.py", line 223, in call
*args)
File "/home/konstantin/steem-python/steembase/http_client.py", line 243, in call
return_with_args=return_with_args)
File "/home/konstantin/steem-python/steembase/http_client.py", line 263, in _return
raise RPCError(error_message)
steembase.exceptions.RPCError: Assert Exception:api_itr != _registered_apis.end(): Could not find API
I hope you liked this tutorial! Leave any feedback or questions in the comments below!
You check out my previous work if you liked it!
To view the full code visit my Github repository.
Curriculum
Bot Development
Steemit Python Bots
- Part 1: How to find someone's newest post
- Part 2: How to return a list of the people who upvoted your post
- Part 3: Relike someones post if they liked yours
Steemit Python Analysis
Posted on Utopian.io - Rewarding Open Source Contributors