30Aug
artwork depicting a bot saying "Hello?"
The bot has just said “Hello word!”

Throughout the computers’ history, we’ve always wanted our electronic devices to be something more than abstract machines — we’ve wanted them to be more human-like, approachable, and relatable. This desire can be seen especially well in the popular culture and cinema in particular: from The Terminator to Wall-E, computers and artificial intelligence have been

This led the developers to create bots which became a craze with the introduction of chatbots, messenger bots, and social media bots. With their popularity rising every year, many people tried to prophesize that bots would revolutionize the entire IT industry … but as we all know, that didn’t quite happen. So what gives?

In this article, we’ll examine the ins and outs of modern bots: what their functionality looks like, which websites, services, and software they can be applied on, and which technologies can be used to create them.

OK, so what are bots and which type of them is the focus of this article?

Although bots seem like an essential part of today’s web environment, enclosing what they actually do in a simple definition be tricky — their scope of functionality is just so large. For simplicity’s sake, we can divide their functionality into 4 groups:

  1. Infrastructure bots, as the name suggests, support the infrastructure of various software products: they perform maintenance checks, test security, create logs, and so on.
  2. Commercial bots aid various businesses via automating their operations — and offering the same functionality to potential customers.
  3. Social media bots are designed to make user and browsing experience on various social media platforms easier: they aggregate latest news, moderate groups, send reminders, and generally act as neat little helpers.
  4. Lastly, malicious bots serve as antagonists of three groups we’ve outlined above — they typically aim to gain profit by exploiting vulnerabilities, aiding hackers in DDoS and phishing attacks, or simply trying to game the system.

While the under-the-hood organization of infrastructure and malicious bots is surely interesting, they deserve dedicated articles to do them justice, so we’ll examine other bot types for now. The goal of this article, therefore, is to focus on rather simple commercial and social bots — ones you typically see on Facebook, Reddit, Twitter, and so on.

Now, we can try defining what a bot actually is: it’s a piece of software packaged in an interface that you can easily interact with. While bots come in all shapes and sizes, those used on social media platforms do tend to be , imitating communication between real users.

Reddit

artwork depicting a stylized reddit logo
Look, even the icon looks like a bot!

Out of all companies in this list, Reddit is probably the most liberal in terms of external services and apps. This platform is essentially a joint effort of every Reddit user, so utilizing the power of bots makes perfect sense: just like ordinary users submit and discuss content, developers contribute their neat little creations to make the browsing experience even better.

Reddit admins have probably been wondering about the ethics of bots for a long time, so they’ve produced a guide called bottiquette (i.e. etiquette of using bots). The best thing about these guidelines is the fact that they can be applied to pretty much every platform. Here are the highlights:

  • Consider making your bot comment only when specifically called: With millions of comments posted every month, it’s easy to trigger the bot’s functionality accidentally.
  • Have your username or a dedicated subReddit listed in your comments for easy communication: This way, the community can indicate whether the bot is actually useful by providing feedback — and even not-so-constructive criticism like Just turn your abomination off! can be useful.
  • Consider giving users a way to opt-out or making it opt-in completely, alternatively offer blacklist options per user and per sub: Bots are great and all, but they often can be quite annoying and lead to a worse user experience.

This raises an interesting question that every bot developer should ask themselves: What are the company’s views on bots (or botting)?

artwork depicting a stylized robot dog
He’s really trying!

Every platform has its own views on bots: while some companies encourage developers to enhance their products with additional functionality, others aren’t so welcoming and prefer to retain absolute control by themselves. So far you could get the impression that bots as a technology are absolutely harmless — but there have been countless examples of botting, i.e. utilizing automation and violating terms of service to gain profit. These examples are rampant on Facebook and Twitter, causing a headache for many users.

Another issue stems from the fact that social media companies usually provide APIs to help developers build bots on top of their platforms. The problems start to arise when APIs get overused/misused and the company is faced with a difficult decision: leave the API accessible both to law-abiding developers and hackers or close it altogether? While some companies (e.g. Reddit) take the change and leave it open, other (e.g. Instagram) decide to close it after all.

The technology you’ll need

The best tool to create Reddit bots is the Python Reddit API Wrapper (a.k.a. PRAW) which is neatly optimized for this task. By accessing Reddit’s API, PRAW creates various instances of the Reddit class which serve as the gateway to the further functionality:

import praw

reddit = praw.Reddit(client_id='my client id',
                     client_secret='my client secret',
                     user_agent='my user agent')

Here’s the full code of a bot that sends Let Me Google That For You links, courtesy of PRAW:

from urllib.parse import quote_plus

import praw

QUESTIONS = ["what is", "who is", "what are"]
REPLY_TEMPLATE = "[Let me google that for you](http://lmgtfy.com/?q={})"


def main():
    reddit = praw.Reddit(
        user_agent="LMGTFY (by /u/USERNAME)",
        client_id="CLIENT_ID",
        client_secret="CLIENT_SECRET",
        username="USERNAME",
        password="PASSWORD",
    )

    subreddit = reddit.subreddit("AskReddit")
    for submission in subreddit.stream.submissions():
        process_submission(submission)


def process_submission(submission):
    # Ignore titles with more than 10 words as they probably are not simple
    # questions.
    if len(submission.title.split()) > 10:
        return

    normalized_title = submission.title.lower()
    for question_phrase in QUESTIONS:
        if question_phrase in normalized_title:
            url_title = quote_plus(submission.title)
            reply_text = REPLY_TEMPLATE.format(url_title)
            print("Replying to: {}".format(submission.title))
            submission.reply(reply_text)
            # A reply has been made so do not attempt to match other phrases.
            break


if __name__ == "__main__":
    main()

Here’s what Reddit’s use case can teach us: It’s crucial for the bot’s developer to gather feedback from the users. However, it’s not always self-evident for them how to report bugs and ask for new features: while more complex software always provides the information about its developers, bots’ compactness and limited functionality often doesn’t let it return a message like Meet my creator Sarah — she’s happy to hear your feedback!

The Good bot! / Bad bot! feature offers users a distinct way of saying This feature is neat — I love it! or Yeah… can we disable it, please?

Telegram

artwork depicting a stylized Telegram logo
At least they’ve beaten WhatsApp in terms of bot functionality

Telegram is a messenger that claims to be a real alternative to WhatsApp. Focusing on privacy and convenience, it’s slowly but surely gaining momentum and increasing its user base. While the majority of people are coming for synchronised chats and cute stickers, we can take a look at another feature of Telegram that is often overlooked — bots.

While pondering over the pros and cons of their service, Telegram developers realized that it was actually possible to create a powerful bot ecosystem instead of implementing individual bots just for the heck of it.

  • Integrate with other services: Connect with apps like Gmail, Wikipedia, and YouTube to utilize their functionality (akin to how many of Slack bots work)
  • Get customized notifications and news: Acting as a personalized newspaper, the bot can send content the moment it’s published.
  • Accept payments from Telegram users: Bots can serve as virtual storefronts and manage payments between users.
  • Build single- and multiplayer games: It’s even possible to create various games via HTML5: from simple puzzles to first person shooters and strategy games.
  • Create custom tools: Bots can offer weather forecasts, translations, cheat sheets, and so on.
  • Build social services: They can also help people connect and organize their communication based on preferences or geographic location.

The functionality described above may seem pretty basic, but bots’ power lies in the ecosystem — they’re deeply integrated into the messenger, allowing for easy access and usage.

The technology you’ll need

Here’s a simple Python-based (do make sure to check our Python interview questions out!) bot that replies to the user’s input with a predefined message — this bot can serve as a template for something more advanced.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This program is dedicated to the public domain under the CC0 license.
#
# THIS EXAMPLE HAS BEEN UPDATED TO WORK WITH THE BETA VERSION 12 OF PYTHON-TELEGRAM-BOT.
# If you're still using version 11.1.0, please see the examples at
# https://github.com/python-telegram-bot/python-telegram-bot/tree/v11.1.0/examples

"""
Simple Bot to reply to Telegram messages.
First, a few handler functions are defined. Then, those functions are passed to
the Dispatcher and registered at their respective places.
Then, the bot is started and runs until we press Ctrl-C on the command line.
Usage:
Basic Echobot example, repeats messages.
Press Ctrl-C on the command line or send a signal to the process to stop the
bot.
"""

import logging

from telegram.ext import Updater, CommandHandler, MessageHandler, Filters

# Enable logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    level=logging.INFO)

logger = logging.getLogger(__name__)


# Define a few command handlers. These usually take the two arguments bot and
# update. Error handlers also receive the raised TelegramError object in error.
def start(update, context):
    """Send a message when the command /start is issued."""
    update.message.reply_text('Hi!')


def help(update, context):
    """Send a message when the command /help is issued."""
    update.message.reply_text('Help!')


def echo(update, context):
    """Echo the user message."""
    update.message.reply_text(update.message.text)


def error(update, context):
    """Log Errors caused by Updates."""
    logger.warning('Update "%s" caused error "%s"', update, context.error)


def main():
    """Start the bot."""
    # Create the Updater and pass it your bot's token.
    # Make sure to set use_context=True to use the new context based callbacks
    # Post version 12 this will no longer be necessary
    updater = Updater("TOKEN", use_context=True)

    # Get the dispatcher to register handlers
    dp = updater.dispatcher

    # on different commands - answer in Telegram
    dp.add_handler(CommandHandler("start", start))
    dp.add_handler(CommandHandler("help", help))

    # on noncommand i.e message - echo the message on Telegram
    dp.add_handler(MessageHandler(Filters.text, echo))

    # log all errors
    dp.add_error_handler(error)

    # Start the Bot
    updater.start_polling()

    # Run the bot until you press Ctrl-C or the process receives SIGINT,
    # SIGTERM or SIGABRT. This should be used most of the time, since
    # start_polling() is non-blocking and will stop the bot gracefully.
    updater.idle()


if __name__ == '__main__':
    main()

In the list above, we mentioned the ability to manage payments. Here’s how it’s implemented:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This program is dedicated to the public domain under the CC0 license.
#
# THIS EXAMPLE HAS BEEN UPDATED TO WORK WITH THE BETA VERSION 12 OF PYTHON-TELEGRAM-BOT.
# If you're still using version 11.1.0, please see the examples at
# https://github.com/python-telegram-bot/python-telegram-bot/tree/v11.1.0/examples

"""
Basic example for a bot that can receive payment from user.
"""

import logging

from telegram import (LabeledPrice, ShippingOption)
from telegram.ext import (Updater, CommandHandler, MessageHandler,
                          Filters, PreCheckoutQueryHandler, ShippingQueryHandler)

# Enable logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    level=logging.INFO)

logger = logging.getLogger(__name__)


def error(update, context):
    """Log Errors caused by Updates."""
    logger.warning('Update "%s" caused error "%s"', update, context.error)


def start_callback(update, context):
    msg = "Use /shipping to get an invoice for shipping-payment, "
    msg += "or /noshipping for an invoice without shipping."
    update.message.reply_text(msg)


def start_with_shipping_callback(update, context):
    chat_id = update.message.chat_id
    title = "Payment Example"
    description = "Payment Example using python-telegram-bot"
    # select a payload just for you to recognize its the donation from your bot
    payload = "Custom-Payload"
    # In order to get a provider_token see https://core.telegram.org/bots/payments#getting-a-token
    provider_token = "PROVIDER_TOKEN"
    start_parameter = "test-payment"
    currency = "USD"
    # price in dollars
    price = 1
    # price * 100 so as to include 2 d.p.
    # check https://core.telegram.org/bots/payments#supported-currencies for more details
    prices = [LabeledPrice("Test", price * 100)]

    # optionally pass need_name=True, need_phone_number=True,
    # need_email=True, need_shipping_address=True, is_flexible=True
    context.bot.send_invoice(chat_id, title, description, payload,
                             provider_token, start_parameter, currency, prices,
                             need_name=True, need_phone_number=True,
                             need_email=True, need_shipping_address=True, is_flexible=True)


def start_without_shipping_callback(update, context):
    chat_id = update.message.chat_id
    title = "Payment Example"
    description = "Payment Example using python-telegram-bot"
    # select a payload just for you to recognize its the donation from your bot
    payload = "Custom-Payload"
    # In order to get a provider_token see https://core.telegram.org/bots/payments#getting-a-token
    provider_token = "PROVIDER_TOKEN"
    start_parameter = "test-payment"
    currency = "USD"
    # price in dollars
    price = 1
    # price * 100 so as to include 2 d.p.
    prices = [LabeledPrice("Test", price * 100)]

    # optionally pass need_name=True, need_phone_number=True,
    # need_email=True, need_shipping_address=True, is_flexible=True
    context.bot.send_invoice(chat_id, title, description, payload,
                             provider_token, start_parameter, currency, prices)


def shipping_callback(update, context):
    query = update.shipping_query
    # check the payload, is this from your bot?
    if query.invoice_payload != 'Custom-Payload':
        # answer False pre_checkout_query
        query.answer(ok=False, error_message="Something went wrong...")
        return
    else:
        options = list()
        # a single LabeledPrice
        options.append(ShippingOption('1', 'Shipping Option A', [LabeledPrice('A', 100)]))
        # an array of LabeledPrice objects
        price_list = [LabeledPrice('B1', 150), LabeledPrice('B2', 200)]
        options.append(ShippingOption('2', 'Shipping Option B', price_list))
        query.answer(ok=True, shipping_options=options)


# after (optional) shipping, it's the pre-checkout
def precheckout_callback(update, context):
    query = update.pre_checkout_query
    # check the payload, is this from your bot?
    if query.invoice_payload != 'Custom-Payload':
        # answer False pre_checkout_query
        query.answer(ok=False, error_message="Something went wrong...")
    else:
        query.answer(ok=True)


# finally, after contacting to the payment provider...
def successful_payment_callback(update, context):
    # do something after successful receive of payment?
    update.message.reply_text("Thank you for your payment!")


def main():
    # Create the Updater and pass it your bot's token.
    # Make sure to set use_context=True to use the new context based callbacks
    # Post version 12 this will no longer be necessary
    updater = Updater("TOKEN", use_context=True)

    # Get the dispatcher to register handlers
    dp = updater.dispatcher

    # simple start function
    dp.add_handler(CommandHandler("start", start_callback))

    # Add command handler to start the payment invoice
    dp.add_handler(CommandHandler("shipping", start_with_shipping_callback))
    dp.add_handler(CommandHandler("noshipping", start_without_shipping_callback))

    # Optional handler if your product requires shipping
    dp.add_handler(ShippingQueryHandler(shipping_callback))

    # Pre-checkout handler to final check
    dp.add_handler(PreCheckoutQueryHandler(precheckout_callback))

    # Success! Notify your user!
    dp.add_handler(MessageHandler(Filters.successful_payment, successful_payment_callback))

    # log all errors
    dp.add_error_handler(error)

    # Start the Bot
    updater.start_polling()

    # Run the bot until you press Ctrl-C or the process receives SIGINT,
    # SIGTERM or SIGABRT. This should be used most of the time, since
    # start_polling() is non-blocking and will stop the bot gracefully.
    updater.idle()


if __name__ == '__main__':
    main()

 

Here’s what Telegram’s use case can teach us: One of the biggest obstacles in front of bots’ popularization has to do with their interfaces:: while developers have no problem using terminal-like commands (e.g. /start or /help), less tech-savvy users find it cumbersome and unintuitive. This may very well be the reason why bots never became the next big thing: they lacked simplicity which ensures the technology’s adoption by the general population.

In all honesty, we can’t blame them: bots are supposed to imitate human conversations, so ensuring usability is crucial. Telegram developers noticed this problem and introduced a possible solution: inline keyboards. Here’s how they look like:

screenshot of an inline keyboard in Telegram

screenshot of an inline keyboard in Telegram

This design decision is smart because it guides the user through the possible conversation options, as if saying Hey! My name’s BotBot. Here’s what I specialize in and here’s what you can ask me about… Chances are, these new, human-friendly interfaces will help ordinary users reconsider the pros and cons of bots — we’re cautiously optimistic about that.

Instagram

artwork depicting a stylized Instagram logo
Too bad bots aren’t welcome there…

In Instagram’s case, bots pretty much fall in the You’re not welcome here category: as stated in the app’s Terms of Use, You can’t attempt to create accounts or access or collect information in unauthorized ways. This includes creating accounts or collecting information in an automated way without our express permission. it’s easy to see why: it’s crucial for the app’s entire business model (which can be summed up as Real life of real users, here and now) to involve real users exclusively; when various bots get added to the mix, user experience may get tainted — and Instagram is cracking down on bots hard.

The punishment for using bots ranges from shadow bans (making the user’s content appear to a lesser amount of followers for a period of time) to actual bans, which is a nightmare scenario for almost every user. Still, many people are continuing to use these services because they also offer grey hat (not explicitly prohibited by the terms of service) and black hat (explicitly prohibited by the terms of service) marketing techniques like mass liking, mass following, mass commenting, and so on.

As discussed above, developers utilize the application’s API to fuel bots’ functionality. There was another measure to combat botting that Instagram introduced: the company closed the official API in April ‘18 without prior warning, causing an uproar among the community — overnight, dozens of third-party services were rendered useless, causing thousands of Instagram-based businesses to be unable to track metrics.

artwork depicting a stylized robot dog next to a "No robots allowed!" sign
Sorry, little guy!

Instagram’s REST and search APIs are supposed to be the go-to place for developers using Instagram as a platform… but not if the latest update happened 5 years ago. ¯\_(ツ)_/¯

Here’s what Instagram’s use case can teach us: It’s also interesting to see that Facebook has been gradually implementing functionality of third-party bots into the official Instagram services. A striking example is the so-called scheduling: publishing a post at a later time. This feature is essential for many users who, upon seeing that Instagram doesn’t provide it, had to turn to third-party services.

In its fight against botting, Instagram is Goliath — its control over the platform is nearly absolute, but the price of every possible mistake doesn’t leave any room for rapid innovation. Bots, on the other hand, are Davids — thanks to their size, they can stay one step ahead of Instagram and circumvent most of the restrictions imposed on them.

This situation forced Instagram to adopt a new strategy: if you can’t detect every bot that violates your terms of service, steal their functionality and make them obsolete. This is exactly what happened with scheduling — Facebook has recently introduced this feature to its Creator Studio. The takeaway, therefore, is to pay attention to the company’s policy towards bots: it’s rather dangerous to focus on a single feature, so it makes sense to try and diversify.

Conclusion

Even though bots haven’t ushered in the revolution that some developers envisioned, they’re still an incredibly powerful tool when used correctly — after all, they make the future seem a bit closer. Designing a simple bot isn’t fundamentally different from designing complex software — you need to appreciate the problem users are experiencing and offer a solution. With just enough perseverance, your bot will make it to the top! 🙂

Leave a Reply