Using Python to
Write a Twitter Bot

Brian Mitchell

 @BrianMitchL

Follow along at https://brianm.me/talks/python-twitter-bot

What is a Twitter bot?

A script that routinely interacts with Twitter

  • Auto-posting Tweets
  • Responding to mentions
  • Spam following, liking, replying, quoting, retweeting, etc. 🙄

Basic Structure


                    while True:
                        # implement logic here

                        # download data
                        # manipulate data
                        # post a tweet

                        time.sleep(60)
                

Location

Static or dynamic

Twitter has geolocation data...


                    def get_location_from_user_timeline(username, fallback):
                        """
                        Load the 20 most recent tweets of a given twitter handle and
                        return a models.WeatherLocation object of the most recent location.
                         This function will find a tweet with coordinates or a place,
                         preferring coordinates. If a location is not found in the most
                         recent 20 tweets, the given fallback location will be returned.
                        :type username: str
                        :param username: twitter username to follow
                        :type fallback: models.WeatherLocation
                        :param fallback: a fallback in case no location can be found
                        :return: models.WeatherLocation
                        """
                        api = get_tweepy_api()
                        # gets the 20 most recent tweets from the given profile
                        try:
                            timeline = api.user_timeline(screen_name=username,
                                                         include_rts=False,
                                                         count=20)
                            for tweet in timeline:
                                # if tweet has coordinates (from a smartphone)
                                if tweet.coordinates is not None:
                                    lat = tweet.coordinates['coordinates'][1]
                                    lng = tweet.coordinates['coordinates'][0]
                                    name = tweet.place.full_name
                                    logging.debug('Found %s: %f, %f', name, lat, lng)
                                    return models.WeatherLocation(lat=lat,
                                                                  lng=lng,
                                                                  name=name)
                                # if the location is a place, not coordinates
                                elif tweet.place is not None:
                                    point = utils.centerpoint(
                                        tweet.place.bounding_box.coordinates[0])
                                    lat = point[0]
                                    lng = point[1]
                                    name = tweet.place.full_name
                                    logging.debug('Found the center of bounding box at '
                                                  '%s: %f, %f', name, lat, lng)
                                    return models.WeatherLocation(lat=lat,
                                                                  lng=lng,
                                                                  name=name)
                            # fallback to hardcoded location if there is no valid data
                            logging.warning('Could not find tweet with location, '
                                            'falling back to hardcoded location')
                            return fallback
                        except tweepy.TweepError as err:
                            logging.error(err)
                            logging.warning('Could not find tweet with location, '
                                            'falling back to hardcoded location')
                            return fallback
                

What if it Crashes?


                import traceback
                ...
                try:
                    while True:
                        ...
                except Exception as err:
                    logging.error(err)
                    logging.error('We got an exception!', exc_info=True)
                    if CONFIG['basic']['dm_errors']:
                        api = get_tweepy_api()
                        api.send_direct_message(screen_name=api.me().screen_name,
                                                text=str(random.randint(0, 9999))
                                                     + traceback.format_exc())
            

Questions?

 @BrianMitchL

 @WeatherByBrian

Submit a pull request or feature suggestion!
https://github.com/BrianMitchL/weatherBot

I also would love some code review 🙃