├── .gitignore ├── 001Bulbasaur_Dream.png ├── 13663654_786684231980_2095554349_o.png ├── 13709493_786878941780_84756877_o.png ├── 5e50e7cf-4eb9-4a65-9e18-cfa5d4ee0e7c.png ├── README.md ├── SUMMARY.md ├── Screen Shot 2015-09-29 at 10.46.40 PM.png ├── Screen Shot 2015-09-29 at 11.28.35 PM.png ├── Screen Shot 2015-09-29 at 11.41.44 PM.png ├── Screen Shot 2015-09-30 at 12.01.48 AM.png ├── Screen Shot 2015-10-01 at 9.34.10 PM.png ├── Screen Shot 2015-10-06 at 11.43.56 PM.png ├── Screen Shot 2015-10-06 at 11.46.29 PM.png ├── Screen Shot 2015-10-06 at 11.49.58 PM.png ├── Screen Shot 2015-10-06 at 9.11.34 PM.png ├── Screen Shot 2015-10-06 at 9.20.10 PM.png ├── Screen Shot 2015-10-07 at 10.24.26 AM.png ├── Screen Shot 2015-10-07 at 10.30.53 AM.png ├── Screen Shot 2015-10-11 at 5.56.57 PM.png ├── Screen Shot 2015-10-11 at 6.10.56 PM.png ├── Screen Shot 2015-10-11 at 6.18.10 PM.png ├── Screen Shot 2015-10-11 at 6.28.31 PM.png ├── Screen Shot 2015-10-11 at 6.30.54 PM.png ├── Screen Shot 2016-07-12 at 10.58.03 PM.png ├── Screen Shot 2016-07-12 at 11.46.02 PM.png ├── Screen Shot 2016-07-13 at 12.12.43 AM.png ├── Screen Shot 2016-07-13 at 12.31.44 AM.png ├── Screen Shot 2016-07-13 at 9.09.59 PM.png ├── acknowledgements.md ├── assets ├── Screen Shot 2017-04-05 at 8.28.21 PM.png ├── Screen Shot 2017-04-16 at 9.50.18 PM.png └── Screen Shot 2017-04-16 at 9.56.16 PM.png ├── book.json ├── chapter1.md ├── cheatsheet.md ├── copy_to_pythonanywhere.md ├── find_a_book.md ├── forking.md ├── how_well_build_one.md ├── personalize_your_bot.md ├── robot1.jpg ├── robot2.jpg ├── robot3.jpg ├── robot4.jpg ├── set_up_github.md ├── set_up_pythonanywhere.md ├── set_up_scheduling.md ├── set_up_twitter.md ├── tell_people_about_your_bot.md ├── test_your_bot.md ├── using_an_api.md ├── what_is_a_twitter_bot.md └── write_unit_tests.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Node rules: 2 | ## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 3 | .grunt 4 | 5 | ## Dependency directory 6 | ## Commenting this out is preferred by some people, see 7 | ## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git 8 | node_modules 9 | 10 | # Book build output 11 | _book 12 | 13 | # eBook build output 14 | *.epub 15 | *.mobi 16 | *.pdf -------------------------------------------------------------------------------- /001Bulbasaur_Dream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/001Bulbasaur_Dream.png -------------------------------------------------------------------------------- /13663654_786684231980_2095554349_o.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/13663654_786684231980_2095554349_o.png -------------------------------------------------------------------------------- /13709493_786878941780_84756877_o.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/13709493_786878941780_84756877_o.png -------------------------------------------------------------------------------- /5e50e7cf-4eb9-4a65-9e18-cfa5d4ee0e7c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/5e50e7cf-4eb9-4a65-9e18-cfa5d4ee0e7c.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
Welcome to the Build-a-Bot workshop!
2 | ======= 3 |
4 | This is a workshop for Python developers who are interested in making small, creative programming projects and have never made a Twitter bot before. We'll walk you through setting up a simple Twitter bot that tweets lines of a book 140 characters at a time. Then, we'll move on to customizing it using free, publicly accessible data sources and our imaginations. 🌈 5 | 6 | Our tools will be 7 | * 8 | [Twitter](http://www.twitter.com), an online social network where our bot's output will go. 9 | * 10 | [Tweepy](http://www.tweepy.org/), a Python library to simplify the Twitter API and authentication process 11 | * Hosting and scheduling on 12 | [PythonAnywhere](https://www.pythonanywhere.com), a hosting service which has a browser UI for everything we'll be doing today so that you won't need to install anything onto your personal computer. 13 | * 14 | Version control on [GitHub](https://github.com/). 15 | * 16 | Public domain books from [Project Gutenberg](https://www.gutenberg.org/) for our practice bot. 17 | 18 | Everyone has different skill levels and experience, so don't worry if you aren't familiar with some of these tools. We'll go into more depth about them in the next sections and you can always ask questions. 19 | 20 | 21 | ## Credits 22 | This tutorial was written by [Terian Koscik](https://twitter.com/spine_cone) for [PyDX 2015](http://pydx.org/). You can view the source at https://github.com/tpinecone/build-a-bot-workshop. -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | * [Introduction](README.md) 4 | * [What is a Twitter bot?](what_is_a_twitter_bot.md) 5 | * [How we'll build one](how_well_build_one.md) 6 | * [Set up PythonAnywhere](set_up_pythonanywhere.md) 7 | * [Set up GitHub](set_up_github.md) 8 | * [Forking](forking.md) 9 | * [Copy to PythonAnywhere](copy_to_pythonanywhere.md) 10 | * [Find a Book](find_a_book.md) 11 | * [Set up Twitter](set_up_twitter.md) 12 | * [Test your bot](test_your_bot.md) 13 | * [Set up scheduling](set_up_scheduling.md) 14 | * [Personalize your bot](personalize_your_bot.md) 15 | * [Using an API](using_an_api.md) 16 | * [Write unit tests](write_unit_tests.md) 17 | * [Tell people about your bot](tell_people_about_your_bot.md) 18 | * [Cheatsheet](cheatsheet.md) 19 | * [Acknowledgements](acknowledgements.md) 20 | 21 | -------------------------------------------------------------------------------- /Screen Shot 2015-09-29 at 10.46.40 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-09-29 at 10.46.40 PM.png -------------------------------------------------------------------------------- /Screen Shot 2015-09-29 at 11.28.35 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-09-29 at 11.28.35 PM.png -------------------------------------------------------------------------------- /Screen Shot 2015-09-29 at 11.41.44 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-09-29 at 11.41.44 PM.png -------------------------------------------------------------------------------- /Screen Shot 2015-09-30 at 12.01.48 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-09-30 at 12.01.48 AM.png -------------------------------------------------------------------------------- /Screen Shot 2015-10-01 at 9.34.10 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-10-01 at 9.34.10 PM.png -------------------------------------------------------------------------------- /Screen Shot 2015-10-06 at 11.43.56 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-10-06 at 11.43.56 PM.png -------------------------------------------------------------------------------- /Screen Shot 2015-10-06 at 11.46.29 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-10-06 at 11.46.29 PM.png -------------------------------------------------------------------------------- /Screen Shot 2015-10-06 at 11.49.58 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-10-06 at 11.49.58 PM.png -------------------------------------------------------------------------------- /Screen Shot 2015-10-06 at 9.11.34 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-10-06 at 9.11.34 PM.png -------------------------------------------------------------------------------- /Screen Shot 2015-10-06 at 9.20.10 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-10-06 at 9.20.10 PM.png -------------------------------------------------------------------------------- /Screen Shot 2015-10-07 at 10.24.26 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-10-07 at 10.24.26 AM.png -------------------------------------------------------------------------------- /Screen Shot 2015-10-07 at 10.30.53 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-10-07 at 10.30.53 AM.png -------------------------------------------------------------------------------- /Screen Shot 2015-10-11 at 5.56.57 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-10-11 at 5.56.57 PM.png -------------------------------------------------------------------------------- /Screen Shot 2015-10-11 at 6.10.56 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-10-11 at 6.10.56 PM.png -------------------------------------------------------------------------------- /Screen Shot 2015-10-11 at 6.18.10 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-10-11 at 6.18.10 PM.png -------------------------------------------------------------------------------- /Screen Shot 2015-10-11 at 6.28.31 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-10-11 at 6.28.31 PM.png -------------------------------------------------------------------------------- /Screen Shot 2015-10-11 at 6.30.54 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2015-10-11 at 6.30.54 PM.png -------------------------------------------------------------------------------- /Screen Shot 2016-07-12 at 10.58.03 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2016-07-12 at 10.58.03 PM.png -------------------------------------------------------------------------------- /Screen Shot 2016-07-12 at 11.46.02 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2016-07-12 at 11.46.02 PM.png -------------------------------------------------------------------------------- /Screen Shot 2016-07-13 at 12.12.43 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2016-07-13 at 12.12.43 AM.png -------------------------------------------------------------------------------- /Screen Shot 2016-07-13 at 12.31.44 AM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2016-07-13 at 12.31.44 AM.png -------------------------------------------------------------------------------- /Screen Shot 2016-07-13 at 9.09.59 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/Screen Shot 2016-07-13 at 9.09.59 PM.png -------------------------------------------------------------------------------- /acknowledgements.md: -------------------------------------------------------------------------------- 1 |
🐍🌷🐍🌷🐍🌷🐍🌷🐍🌷🐍🌷
2 | 3 | I am indebted to: 4 | * 5 | [Stefan Bohacek](https://twitter.com/fourtonfish) for writing https://botwiki.org/, a hugely important resource for me and for this workshop. 6 | * 7 | [Thursday Bram](https://twitter.com/thursdayb) for encouraging me to speak at PyDX, even though I had very little Python experience and even less speaking experience. 8 | * 9 | [Lacey Williams](https://twitter.com/laceynwilliams) for giving me the opportunity to talk about how much I love Twitter bots at [Django Girls PDX](http://djangogirls.org/portland) this summer, and for being an amazing and inspiring co-organizer. 10 | * 11 | [@thricedotted](https://twitter.com/thricedotted) for writing the first bot I read that made me spit out my drink from laughter (the esteemed [@wikisext](https://twitter.com/wikisext)). 12 | * 13 | [Nate Smith](https://twitter.com/nate_smith) for teaching me about Twitter bots and supporting me in everything I do. 14 | 15 |
🐍🌷🐍🌷🐍🌷🐍🌷🐍🌷🐍🌷
-------------------------------------------------------------------------------- /assets/Screen Shot 2017-04-05 at 8.28.21 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/assets/Screen Shot 2017-04-05 at 8.28.21 PM.png -------------------------------------------------------------------------------- /assets/Screen Shot 2017-04-16 at 9.50.18 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/assets/Screen Shot 2017-04-16 at 9.50.18 PM.png -------------------------------------------------------------------------------- /assets/Screen Shot 2017-04-16 at 9.56.16 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/assets/Screen Shot 2017-04-16 at 9.56.16 PM.png -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /chapter1.md: -------------------------------------------------------------------------------- 1 | # First Chapter 2 | 3 | GitBook allows you to organize your book into chapters, each chapter is stored in a separate file like this one. 4 | -------------------------------------------------------------------------------- /cheatsheet.md: -------------------------------------------------------------------------------- 1 | # Cheatsheet 2 | 3 | 4 | ## bash console commands 5 | 6 | * show contents of current directory: 7 | ``ls`` 8 | * change directory: ``cd [directory name]`` 9 | * set permissions: ``chmod [permission flag] [filename]`` 10 | 11 | ## Git commands 12 | * show changes that have been made: ``git diff`` 13 | * show current branch and files that have been changed: ``git status`` 14 | * clone a repository: ``git clone [clone url]`` -------------------------------------------------------------------------------- /copy_to_pythonanywhere.md: -------------------------------------------------------------------------------- 1 | # Copy to PythonAnywhere 2 | 3 | ![](13709493_786878941780_84756877_o.png) 4 | 5 | * 6 | Copy the HTTPS clone url for the fork (it should resemble https://github.com/[your_username]/hello-world-bot.git) 7 | * 8 | Go back to the PythonAnywhere bash console and run ``git clone clone url`` where ``clone url`` is the web address you just copied. 9 | 10 | ##What did we just do? 11 | "Cloning" a GitHub repo means taking some code that exists on GitHub and putting it somewhere that you can use and edit it. Here, we took your forked copy of the hello-world-bot template and put it on your PythonAnywhere server. 12 | 13 | One thing you might be wondering is why we didn't just make a clone of the original hello-world-bot template. The reason is that only people who have been granted permission to a repository can push changes to it. By making a fork of hello-world-bot, you can push whatever changes you want to your fork without needing access to the original. -------------------------------------------------------------------------------- /find_a_book.md: -------------------------------------------------------------------------------- 1 | # Find a Book 2 | 3 | We'll now need to find a book for our bot to tweet from. [https://www.gutenberg.org/](https://www.gutenberg.org/) has a wide selection of public domain books. Once you've found one, open the Plain Text version. 4 | 5 | * Open the PythonAnywhere home page in a new tab and go to the "Files" section 6 | * Open the file called book.txt inside the hello-world-bot directory and paste the text file into it \(we could have created it in the bash console, but pasting large amounts of text into the browser bash console can cause problems\). 7 | 8 | ![](Screen Shot 2015-10-11 at 6.28.31 PM.png) 9 | 10 | * Then: 11 | 12 | ![](5e50e7cf-4eb9-4a65-9e18-cfa5d4ee0e7c.png) 13 | 14 | * Remove any extraneous text that you don't want to tweet, like the table of contents or appendix. 15 | 16 | ## What did we just do? 17 | 18 | Project Gutenberg is a database of free books \(the legal kind!\). In order to run the hello-world-bot template, we need a text file called book.txt. 19 | 20 | -------------------------------------------------------------------------------- /forking.md: -------------------------------------------------------------------------------- 1 | # Forking 2 | 3 | ![](Screen Shot 2015-10-11 at 6.10.56 PM.png) 4 | 5 | * 6 | Fork the hello world bot template at https://github.com/tpinecone/hello-world-bot/ 7 | 8 | * 9 | By forking the hello world bot template, you'll be able to keep your bot and the changes you make to it separate from the original template repo. 10 | 11 | ##What did we just do? 12 | 13 | When you "fork" a GitHub repository, you're taking a project someone else has written (in this case, the hello-world-bot template), and creating a copy of it that you can make changes to. The changes you make on your fork won't affect the original repository. You can read more about forking here. -------------------------------------------------------------------------------- /how_well_build_one.md: -------------------------------------------------------------------------------- 1 | # How we'll build one 2 |
3 | For this workshop, we'll start by making a simple template bot that tweets the text of a book 140 characters at a time. Then, we'll change its behavior to make a new bot. To do this we will: 4 | 5 | * Make an account on PythonAnywhere 6 | * 7 | Clone the bot template from GitHub and find a book for it to tweet 8 | * Set up a Twitter acount for the bot 9 | * Test that the bot can tweet to the account we set up for it 10 | * Schedule the bot to run once per day (we'll go over paid hosting options that will allow you to tweet multiple times per day) 11 | * Come up with interesting ideas and implement them! 12 | -------------------------------------------------------------------------------- /personalize_your_bot.md: -------------------------------------------------------------------------------- 1 | # Personalize your Bot 2 | 3 | There are tons of free, easily accessible data sources you can use to create interesting bots. Some of my favorites are: 4 | 5 | * 6 | **Wikimedia** provides free, public APIs for all of their services including Wikipedia and Wikihow. Uses simple GET requests with no authentication required. There is [documentation](https://www.mediawiki.org/wiki/API:Main_page) as well as a [Python wrapper](https://pypi.python.org/pypi/wikipedia/). Cool bots that use the Wikimedia API include [@wikisext](https://twitter.com/wikisext) and [@how2butt](https://twitter.com/how2butt). 7 | * **Tweepy**, the library we used to send tweets from our sample bot, can also be used to search and reply to tweets. Tweepy is very [well documented](http://tweepy.readthedocs.org/en/v3.2.0/). 8 | * **Google** has a lot of different free, public APIs that have basic authentication and usage limit requirements. The whole list of Google APIs is [here](https://developers.google.com/apis-explorer/#p/). [@earthroverbot](https://twitter.com/EarthRoverBot) and [@youareherebot](https://twitter.com/youareherebot/with_replies) use the [Google Maps](https://developers.google.com/maps/?hl=en) API. 9 | * **ITunes** has a [search API](https://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html) that provides information on music, movies, and other media for free and with no authentication. 10 | * **Pokeapi** has a [wealth of pokemon data](http://pokeapi.co/) free and with no authentication steps. 11 | 12 | 13 | Here's a [mostly complete list of Python API wrappers](https://github.com/realpython/list-of-python-api-wrappers). 14 | 15 | It's also possible to make a unique bot without many changes or additions to the template. [@everyportland](https://twitter.com/everyportland) is a bot that has very minor differences from the original template. It tweets from a list of English nouns instead of a book, plus a Portland-specific modifier (i.e. "Natural abacuses"). 16 | 17 | **** 18 | You can check out the source code for these Python Twitter bots for ideas or examples: 19 | 20 | 21 | * [@taco_helper](https://github.com/tpinecone/taco_helper) creates fantastical Taco Bell menu items and suggests them to people who are selected based on their recent tweets. 22 | * 23 | [@angryrichpeople](https://github.com/tpinecone/angry_rich_people) posts 1 star reviews of $$$$ Yelp reviews 24 | * 25 | [@crystalliser](https://github.com/Autophagy/crystalliser-bot) takes an image and "crystallizes" it. 26 | * [@emoji_haiku](https://github.com/williln/emojihaiku) creates haikus out of emoji. 27 | * [@gutendelight](https://github.com/hugovk/gutendelight) makes rhyming couplets out of hip hop lyrics and classic literature. 28 | * 29 | [@kaikkisanat](https://github.com/hugovk/everyfinnishword) is tweeting every word in Finnish. 30 | * [@permitbot](https://github.com/chagan/permitbot) reports on building permits filed in Chicago. 31 | 32 | BotWiki maintains a [list of Twitter bots](https://botwiki.org/bots/twitterbots) which are not all open source or written in Python. 33 | 34 | Pick out a couple APIs that look interesting to you, even if you're not sure how you'll turn it into a bot. We'll go over how to use an API in the next chapter. 35 | 36 | -------------------------------------------------------------------------------- /robot1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/robot1.jpg -------------------------------------------------------------------------------- /robot2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/robot2.jpg -------------------------------------------------------------------------------- /robot3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/robot3.jpg -------------------------------------------------------------------------------- /robot4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spinecone/build-a-bot-workshop/599bcc8b9975e463a5db25b52ceaa3ff7096370b/robot4.jpg -------------------------------------------------------------------------------- /set_up_github.md: -------------------------------------------------------------------------------- 1 | 2 | # Set up a GitHub account 3 |
4 | If you don't have a GitHub account, you'll need to create one first at https://github.com/join (the free version will be fine). Then go to https://github.com/spinecone/hello-world-bot. 5 | 6 | The template we're going to base a new bot on, Hello World Bot, is made up of 7 files (one of them is not visible in this screenshot. I'll explain why further down). 7 | * **README.md** is a file that most GitHub repos have. It describes what the project does and how to use it. 8 | * **book.txt** is where the text of a book will go. 9 | * **book_manager.py** handles the logic of getting lines out of our book file, and deleting them after they're tweeted. 10 | * **bot.py** handles authenticating with Twitter and posting tweets. 11 | * **tests.py** tests that the bot does what it's supposed to do. We'll cover the basics of unit testing in one of the last chapters. 12 | * Finally, **secrets.py** will hold our authentication secrets which we'll cover in the next section. **secrets.py** is not included in the template repo since we don't want to make our authentication info publicly accessible. 13 | 14 | ##What did we just do? 15 | GitHub is a service that allows us to share projects with others. It uses Git, a program for keeping track of changes to a project. There's nothing about Git or GitHub that's specific to programming. You could use it to keep track of changes to a novel or any other project you might want to share with other people, as long as it can be represented as a group of files. For this tutorial, we're going to be taking "hello-world-bot," an example Twitter bot that's hosted on GitHub, copying it, and turning it into a whole new bot. 16 | 17 | Git and GitHub are very complex and have a lot of different features that we won't be covering in this tutorial. If you're interested in getting started with Git and GitHub, I highly recommend the Don't Be Afraid to Commit tutorial. 18 | 19 | 20 | -------------------------------------------------------------------------------- /set_up_pythonanywhere.md: -------------------------------------------------------------------------------- 1 | # Set up a PythonAnywhere account 2 | * 3 | Sign up for PythonAnywhere at https://www.pythonanywhere.com/registration/register/beginner/ 4 | * 5 | Start a new bash console from the "Consoles" tab and leave it open, we'll come back to it later. 6 | 7 | ![](Screen Shot 2015-10-11 at 5.56.57 PM.png) 8 | ##What did we just do? 9 | PythonAnywhere is a service for writing and hosting Python applications. We can put the code for our bot on PythonAnywhere, make changes to it, and tell it when to run. Without PythonAnywhere, this tutorial would need to have a lengthy chapter on how to install and use Python on all the different types of operating systems people might be using to create their bot. 10 | 11 | There are a lot of different services out there for hosting web applications with their own pros and cons. We're using PythonAnywhere because it has a fairly simple UI, it allows us to write Python programs from the browser, and it's free. If you're more experienced at programming, you might be interested in checking out Heroku, Digital Ocean, and AWS for deployment. Those are services with more options, but are a little harder to use than PythonAnywhere. -------------------------------------------------------------------------------- /set_up_scheduling.md: -------------------------------------------------------------------------------- 1 | # Set up scheduling 2 |
3 | We're going to make a shell script which PythonAnywhere will execute on a schedule. A free account is only allowed to run one scheduled task per day, but if you want to tweet more than that you can get unlimited scheduled tasks for about $5 per month on PythonAnywhere or other hosting services like Digital Ocean. You can read more about choosing and configuring hosting at [BotWiki](https://botwiki.org/tutorials/). 4 | 5 | For our free once per day bot, 6 | * Add a file called send_tweet.sh to the hello-world-bot directory with the following contents: 7 | ```sh 8 | #!/bin/bash 9 | cd /home/$USER/hello-world-bot/ 10 | python3 bot.py 11 | ``` 12 | * 13 | On the bash console, make sure you're in the hello-world-bot directory and run 14 | ```sh 15 | chmod +x send_tweet.sh 16 | ``` 17 | This will give PythonAnywhere permission to run the script. 18 | * 19 | Visit the "Schedule" tab on PythonAnywhere 20 | * Add a new scheduled task which points to /home/[your username]/hello-world-bot/send_tweet.sh and runs within the next couple of minutes. **Note that the system time is in the UTC timezone**, which may not be the same as your own timezone! ![](Screen Shot 2015-10-01 at 9.34.10 PM.png) 21 | * You'll be able to tell if the scheduled task is working correctly if a tweet is posted at the time you configured it for. If something went wrong, you can remove the task and set it up again with a different time. 22 | -------------------------------------------------------------------------------- /set_up_twitter.md: -------------------------------------------------------------------------------- 1 | # Set up a Twitter account 2 | 3 | * 4 | Create an account for the bot at https://twitter.com/signup. (don't worry about picking a perfect username, it can be changed later). 5 | * Note: if you've created a Twitter account before, you won't be allowed to use the same phone number to sign up for a new account. You can sign up for a free phone number at https://www.google.com/voice that will forward to your existing number. 6 | * If you would like, this is a good time to go to your account settings and turn off mobile and email notifications. 7 | * 8 | Visit https://apps.twitter.com/app/new to create a new Twitter application for this account. This will give us credentials that will allow our bot to tweet on this account's behalf. 9 | 10 | Note: The information you enter here won't be used for our bot, but make sure the (arbitrary) website you enter begins with http:// 11 | * 12 | Once you have created an application for your account, visit the Keys and Access Tokens section. 13 | * Create a new access token. 14 | 15 | We will now take the credentials we just received and put them in a secrets.py file. 16 | 17 | * 18 | Go back to our PythonAnywhere bash console. 19 | * 20 | Add a secrets.py file to the hello-world-bot directory. You can add the file using the "Files" tab the same way we added book.txt, or you can use a text editor like vim on the bash console. It should resemble this: 21 | ```py 22 | consumer_key = "I'M A CONSUMER KEY" 23 | consumer_secret = "I'M A CONSUMER SECRET" 24 | access_token = "I'M AN ACCESS TOKEN" 25 | access_token_secret = "I'M AN ACCESS TOKEN SECRET" 26 | ``` 27 | **It's very important that you do not commit your secrets file to GitHub! If you do, anyone in the world can use this information to post tweets on your behalf.** 28 | 29 | ##What did we just do? 30 | 31 | Twitter needs to give your bot permission to post tweets via its API. Like many services, Twitter uses OAuth to grant that permission. Instead of just authenticating with your username and password, which could compromise your account if stolen, OAuth allows you to generate tokens that you can turn off or set to "read only." 32 | 33 | OAuth can be a little complicated to set up, but most of that process is taken care of us by Tweepy, the library we're using to communicate with Twitter. You can read more about OAuth here. -------------------------------------------------------------------------------- /tell_people_about_your_bot.md: -------------------------------------------------------------------------------- 1 | # Tell people about your bot 2 | 3 | There are a number of ways to share your bot with other botmakers. You can tweet about it using [#botALLY](https://twitter.com/search?q=%23botALLY&src=tyah) or [#botmakers](https://twitter.com/hashtag/botmakers?src=hash). 4 | 5 | Add a description for your bot to add it to the BotWiki [here](http://botwiki.org/submit-your-bot). You can direct any questions to [Stefan Bohacek](https://twitter.com/fourtonfish). -------------------------------------------------------------------------------- /test_your_bot.md: -------------------------------------------------------------------------------- 1 | # Test your bot 2 | The bot should be all ready to go. Go to the PythonAnywhere bash console, cd into hello-world-bot, and run ``python3 bot.py`` to test it. If everything has been set up correctly, the command will run without errors, a tweet will be posted to the bot's account, and the text of the tweet will be removed from book.txt. 3 |

4 | 🌷 🌸 🌹 🌺 **success!** 🌺 🌹 🌸🌷 5 |
6 | -------------------------------------------------------------------------------- /using_an_api.md: -------------------------------------------------------------------------------- 1 | # Using an API 2 | An API is a set of instructions that programs can use to talk to each other. In web development, these instructions are usually defined as a set of urls that can take different parameters. 3 | 4 | To make a Twitter bot, you might use an API to collect boring data and do something interesting to it. For example, @how2butt uses the url ```http://www.wikihow.com/api.php?action=query&list=random&rnnamespace=0&rnlimit=1&format=json``` from the MediaWiki API to find a random WikiHow article. Then, in order to make the world a better place, it replaces one of the words in the article's title with "butt." 5 | 6 | Let's use a simpler example to look at how an API works. Try visiting the url ```http://pokeapi.co/api/v2/pokemon/1/``` in your browser. 7 | 8 | This url is an endpoint of the Pokéapi. It has extensive documentation at https://pokeapi.co/ which describes all the different kinds of urls you can use to see Pokemon data. 9 | 10 | The pile of text you're seeing is JSON, a data format that most programming languages can understand. 11 | 12 |

"I'm machine-readable!" 13 |
14 | 15 | We can use Python's requests and json libraries to read from JSON urls like this one: 16 | 17 | 18 | Now all you have to do is pass the text you've created to Tweepy. You can read data from pretty much any API just using requests.get() and json()! 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /what_is_a_twitter_bot.md: -------------------------------------------------------------------------------- 1 | # What is a Twitter bot? 2 | A Twitter bot is any kind of program that posts generated content to Twitter, either on a regular schedule or in response to something. They can be funny or insightful or beautiful or anything else you can think of. 3 |
4 | 5 |
6 |

7 | bots by [@R4_Unit](https://twitter.com/R4_Unit), [@joemfox](https://twitter.com/joemfox), [@muffinista](https://twitter.com/muffinista), [@objelisks](https://twitter.com/objelisks), [@spine_cone](https://twitter.com/spine_cone), [@chrisrodley](https://twitter.com/chrisrodley), and [@yeldora_](https://twitter.com/yeldora_). 8 | # Why should I make one? 9 | Because of their simplicity, bots are a fun project for both programmers looking for a creative outlet and creative people wanting to expand their programming skills. 10 | 11 | Traditional programming education does not usually allow for much creative expression. As aspiring programmers, we are often told that it is in our best interests (professionally, academically, etc.) to work on projects that can serve as a portfolio and teach us about software development. But what kind of projects? A sharing economy startup? A new javascript framework? I have often wondered whether I deserve to be called a software developer because those projects were never of much interest to me. 12 | 13 | Twitter bots interest me because unlike many software projects that work hard to convince you of their importance and seriousness, Twitter bots are inherently irreverent. No one will ever get rich from a cool Twitter bot idea. And yet people keep making them in all the different and fascinating ways that you can make art. -------------------------------------------------------------------------------- /write_unit_tests.md: -------------------------------------------------------------------------------- 1 | # Write unit tests for your bot 2 | 3 | Sweet! Your bot is tweeting on a schedule, and you're on your way to Twitter bot superstardom! But what if you want to add some changes to your bot down the line? How can we verify that your changes won't break any of the current behavior? 4 | 5 | We can safely make changes and additions to our bot through the magic of ✨unit tests✨! 6 | 7 | Unit tests check that every small part of a program works the way a programmer expects it to. For example, if you were programming a vending machine, you might write a unit test that checks that the machine gives you chips if you put a dollar into the machine, and another test that it won't give you the chips if you only put in 50 cents. 8 | 9 | In general, every unit test consists of some setup and one or more assertions. Here's how that might look with the vending machine from earlier. 10 | 11 | 12 | 13 | The setup for both of these tests is that we initialize a VendingMachine object, and put some money into it. In the first test, we assert that "chips" is what we get back after inserting 1 money, essentially a dollar. The second test asserts is that "NOT ENOUGH!" is what the machine returns for .5 money. We would prefer to receive proper edible chips from a real machine, but for the purposes of unit testing, the string "chips" will be just fine. 14 | 15 | Once these tests are in place, we can update the vending machine to accept different amounts of money and return different kinds of items knowing that we won't break our dollar chips behavior without realizing it. 16 | 17 | There are 3 unit tests that are included in the hello-world-bot template. The tests check that: 18 | 1. The bot will tweet sentences that are less than 140 characters. 19 | * If a sentence is longer than 140 characters, the bot will tweet up to 140 characters of it. 20 | * After tweeting, the bot will remove the text it just tweeted from the book file. 21 | 22 | You can run the tests with ```python3 tests.py```. However, depending on the changes you made to personalize your bot, these tests probably aren't valid anymore. Let's go over how these basic tests work(ed), and you can change them to fit your bot. 23 | 24 | 25 | Since we don't want to affect the book we're actually tweeting from, we use a temporary file ("test_file") that we create and destroy in each test. For this test, the test_file just has two short sentences, in order to assert that get_next_chunk() will return the entire first sentence if it's short enough. 26 | 27 | This test uses mocking to run the bot with test_file instead of book.txt, which has some pretty complicated syntax. If you're interested in learning more about mocks, you can read more about it here: https://docs.python.org/3/library/unittest.mock.html 28 | --------------------------------------------------------------------------------