Hacking Steemit - Unclaimed Reward Notifications

in #howto6 years ago

Intro:

Today I'm going to show you how to build a little Command Line Interface (CLI) tool to check whether or not you have unclaimed rewards.

First I'll show you the full code, then I'll walk through it line-by-line to explain what is going on. This tutorial assumes you have basic working knowledge of python, pip, and bash, and are using MacOS or Unix.

Create a file named steem_check, make it executable by running chmod +x steem_check and put the following code in it:

#!/usr/bin/env python3

import requests
import click
import sys

unclaimed_msg = """
You have unclaimed rewards on Steemit!
Visit https://steemit.com/@{user}/transfers to redeem:
{sbd:.3f} SBD
{steem:.3f} STEEM
"""

claimed_msg = """
No unclaimed rewards at this time. Check again soon!
"""

error_msg = """
Unable to find a wallet for the user {user}. Please check your spelling and try again.
"""

@click.command()
@click.option('--quiet', is_flag=True)
@click.argument('user')
def check_unclaimed_rewards(user, quiet):
    data = requests.get(f'https://steemit.com/@{user}.json').json()
    if data['status'] == '404':
        if not quiet:
            print(error_msg.format(user=user))
        sys.exit(1)

    pending_sbd = data['user']['reward_sbd_balance'].split(' ')[0]
    pending_steem = data['user']['reward_vesting_steem'].split(' ')[0]

    pending_sbd = float(pending_sbd)
    pending_steem = float(pending_steem)

    if pending_steem > 0 or pending_sbd > 0:
        print(unclaimed_msg.format(**{
            'user':user,
            'sbd': pending_sbd,
            'steem': pending_steem
            }))
    elif not quiet:
        print(claimed_msg)

    sys.exit(0)
    
if __name__ == '__main__':
    check_unclaimed_rewards()

Explanation:

#!/usr/bin/env python3

This is typically referred to as a shebang line. It tells the shell where to look for the interpreter for this file. This allows us to run the script directly, without specifying the python3 interpreter.

import requests
import click
import sys

Here we import all the packages we need for the rest of the script. Requests is the gold standard for making HTTP requests in Python, and click is a fantastic framework for creating quick little CLI tools. Sys is a Python builtin that makes it easier to interact with the underlying operating system.

unclaimed_msg = """
You have unclaimed rewards on Steemit!
Visit https://steemit.com/@{user}/transfers to redeem:
{sbd:.3f} SBD
{steem:.3f} STEEM
"""

claimed_msg = """
No unclaimed rewards at this time. Check again soon!
"""

error_msg = """
Unable to find a wallet for the user {user}. Please check your spelling and try again.
"""

We will use these string literals to communicate with the user. In Python, three double quotes (""") will start and end a multi-line string literal. The content inside the curly braces ({ }) lets us specify where we wish to insert variables into the string. Python has absolutely fantastic support for string formatting, and a great guide for what exactly is going on can be found here.

@click.command()
@click.option('--quiet', is_flag=True)
@click.argument('user')
def check_unclaimed_rewards(user, quiet):

We declare our function and let Click know that we want to expose it to the command line. We specify that we take in an optional boolean flag --quiet and a mandatory argument called user.

    data = requests.get(f'https://steemit.com/@{user}.json').json()
    if data['status'] == '404':
        if not quiet:
            print(error_msg.format(user=user))
        sys.exit(1)

First, we format the URL we want to pull data from using a new feature in Python 3.6 called an f-string. Then, we make a GET request to that URL and convert the resulting JSON to a dictionary object. If the user does not exist and we get a 404 error, then we print an error message out to the user and exit. If the user specifies the --quiet flag, we supress the error and fail silently.

    pending_sbd = data['user']['reward_sbd_balance'].split(' ')[0]
    pending_steem = data['user']['reward_vesting_steem'].split(' ')[0]

    pending_sbd = float(pending_sbd)
    pending_steem = float(pending_steem)

If we don't recieve a 404 error, then we continue to execute the rest of our program. The api returns the data we want as a string in the format {amount} {currency} so we have to do a little work to parse the numerical information out.

    if pending_steem > 0 or pending_sbd > 0:
        print(unclaimed_msg.format(**{
            'user':user,
            'sbd': pending_sbd,
            'steem': pending_steem
            }))
    elif not quiet:
        print(claimed_msg)

    sys.exit(0)

Finally, we check if there is any Steem or SBD to redeem. If there is, we tell the user to check their wallet. Otherwise, we print a failure message, unless the --quiet flag is specified. I wanted to show off a cool feature called kwarg (keyword argument) unpacking. The ** converts the dictionary into keyword arguments passed into the format function, and is equivalent to the following:

    print(unclaimed_msg.format(
        user=user,
        sbd=pending_sbd,
        steem=pending_steem
        ))

Lastly, we need to call our function.

if __name__ == '__main__':
    check_unclaimed_rewards()

This is just some Python boilerplate that says to run check_unclaimed_rewards only if this file is executed directly. This way we can write other scripts that import this function without having it execute every time.

Running It

Back inside the terminal, you should be able to execute the program now! Here is the output I see when I pass in my own username

Maxwells-MacBook-Pro:steemit maxwellgerber$ ./steem_check maxg
You have unclaimed rewards on Steemit!
Visit https://steemit.com/@maxg/transfers to redeem:
0.077 SBD
0.045 STEEM

After claiming my rewards:

Maxwells-MacBook-Pro:steemit maxwellgerber$ ./steem_check maxg
No unclaimed rewards at this time. Check again soon!

But we can do one better! Let's add the ./steem_check executable to our path so we can run it from anywhere! I did this by symlinking the file to one of my /bin folders with the following command:

ln ./steem_check /usr/local/bin

Finally, I added the following line to my .bashrc:

steem_check --quiet maxg

Now, every time I open a new terminal, that line will get run. If I have Steem to redeem, a notification will pop up in my terminal. If not, the message will be supressed by the --quiet flag and I won't see anything. Pretty useful!

Thanks for reading!

How did I do? Did you find this useful? Too long? Too short? Would you like to see more content like this in the future? Let me know below!

I ordered an Amazon Echo Dot last week that should be arriving soon. My next goal is to turn this into an Echo skill and document that process.

Sort:  

You got a 1.88% upvote from @postpromoter courtesy of @maxg!

Congratulations @maxg! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

Award for the number of comments

Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

By upvoting this notification, you can help all Steemit users. Learn how here!

Coin Marketplace

STEEM 0.29
TRX 0.12
JST 0.034
BTC 62772.18
ETH 3154.14
USDT 1.00
SBD 3.86