chessvision-ai-bot analyzes chess positions posted on Reddit

4 minute read

We’re just few days after launching chessvision.ai and people reached me out both privately and in the comments suggesting that it’d be nice to build a bot for r/chess that can work with the app and analyze chess images posted on Reddit.

All of us love the awesome u/ChessFenBot that was doing just that, but for some reason, it hasn’t been working recently. Perhaps this is why I received some many request to make chessvision.ai working for that use case.

so from now u/chessvision-ai-bot will be pleased to serve you!

Launch on Reddit:

[P] I’m a bot and will serve people analyzing chess positions from images posted on /r/chess

/u/chessvision-ai-bot will serve you to analyze chess positions posted on /r/chess

How to build a bot for Reddit

In this case, the only thing I needed was a part that can observe what’s being posted on r/chess subreddit, and for each new published post, extract an image from it, if any, and analyze it with existing chessvision.ai service that I built for the purpose of the Chrome extension.

Fortunately, there is an PRAW which is an awesome wrapper for Reddit API for Python.

Fetching posts

PRAW makes fetching new posts as easy as:

submissions = reddit.subreddit('chess').new(limit=5)

I simply fetch new submissions every 5 minutes or so. For each new submission, first, we check if the bot already analyzed it - it’s an important check because we don’t want the bot to analyze the same post more than once. If it has not been yet analyzed, we fetch it:

submission = reddit.submission(id=submission_id)

where submission_id is a unique identifier of a submission.

Extracting image from a post

Next, we need to check if the submission has any images. It’s the tricky part because I wanted to handle all reasonable methods of attaching an image to the post - and there can be many!

  1. Post can be a link type post
  2. Post can be a text post that has a link to an image in its text part

The first case is easier as PRAW provides an easy way to access the URL of a submission, if any:

url = submission.url

But we need to determine if this url is an url of an image - and don’t be tempted to just check if the URL ends with .jpg or .png!

The method I ended up with relies on checking the Content-Type header of server response. The code uses requests and HTTP HEAD method request to check the Content-Type without fetching the resource itself.

def is_image_url(url):
    # we don't use image/* in order to omit
    # .gif and other non-static image types
    image_types = (
      "image/png",
      "image/jpeg",
      "image/jpg",
    )

    try:
        r = requests.head(url)
    except requests.exceptions.MissingSchema:
        return False

    try:
        return r.headers["content-type"] in image_types
    except KeyError:
        return False

For the second case, i.e. when the post is a text post and it contains a link to an image, the bot uses a regular expression that finds all urls in submission’s text and check each using the approach for the first case.

Once the bot has an image, it gives it to the chessvision.ai service to analyze and if it finds a chess position in the image, the bot posts its response to Reddit. Again, PRAW makes it easy:

submission.reply(message)

where message is the bot’s reply.

Deploying the bot

There are many options here. I heard many people run their bots on their local machines which is fine if the bot doesn’t have to run 24/7, but it my case I wanted it to be properly deployed on a server so I went for Google Cloud deploy. Heroku is another choice which is very popular.

What’s next

I have plans to add more useful features for the bot. Stay tuned!