Skip to content

ecmendenhall/instant-bot

Repository files navigation

Instant Bot

Build Status npm version

Remix on Glitch

Instant Bot Logo

Instant bot is a command-line tool and lightweight framework for building Twitter/Mastodon bots that run on Glitch and AWS Lambda. It provides two tools: a CLI that wraps Serverless Framework to create and deploy your bot, and a lightweight library that handles setting up your bot and configuring a Twitter/Mastodon client. The goal is to provide just enough framework to get up, running, and out of the way so you can use Node, Glitch, and Serverless to build cool bots without worrying about the servers that run them.

⚠️ 🚨 Warning: This project is still in development, and APIs may break at any time! 🚨 ⚠️

Installation

Instant Bot is an npm package. Install node and npm, then install the instant-bot CLI with:

$ npm install -g instant-bot

You'll need an account for your bot on Twitter or Mastodon. If you want to deploy to Lambda, you'll also need an AWS account.

Getting Started

If you're using Glitch, start here. If you're using Lambda, start here.

Instant Bots on Glitch

Glitch is a very cool platform for instantly running and remixing Node applications.

Creating an Instant Bot

To create an Instant Bot on Glitch, you don't need the instant-bot CLI. Instead, just click one of the buttons below:

Twitter:

Remix on Glitch

Mastodon:

Remix on Glitch

Anatomy of your Instant Bot

A new Glitch instant bot looks something like this:

$ tree lipogram-bot
.
├── .env - Stores secrets like your Twitter API keys.
├── .gitignore - Sane defaults so you don't check in your secrets!
├── bot.js - Where your bot code should live.
├── package.json - Dependencies, including the instant-bot library.
├── README.md - A markdown file describing your bot.

Let's walk through each of these files in order.

.env

Your instant bot uses dotenv to load secrets as enviroment variables when it starts up. Edit your new bot's .env and fill in the details.

If you're building a Twitter bot, your .env should looks something like this:

TWITTER_CONSUMER_KEY=<your twitter consumer key>
TWITTER_CONSUMER_SECRET=<your twitter consumer secret>
TWITTER_ACCESS_TOKEN=<your twitter access token>
TWITTER_ACCESS_TOKEN_SECRET=<your twitter access token secret>

If you're building a Mastodon bot, your .env will include Mastodon-related variables instead:

MASTODON_ACCESS_TOKEN=<your Mastodon access token>
MASTODON_API_URL="https://oulipo.social/api/v1/"

Don't worry! Glitch automatically wipes out these values when someone forks your project!

You'll need to get all these secrets from somewhere. Here's a guide on how to get your AWS access keys. Here's how to get Twitter access tokens. Here's a tool for generating your Mastodon token.

.gitignore

This file makes sure you don't accidentally check in your secret keys if you save your instant bot in a Git repository or push it to Github. It excludes your .env file and the node_modules directory by default.

bot.js

The core of your application. It will look something like this:

const instantBot = require('instant-bot');

instantBot({service: 'twitter'}, (bot) => {
  bot.post('Hola from lipogram bot!');
  bot.messages.filter(m => !m.text.includes('e')).map((message) => {
    bot.client.post('statuses/retweet/:id', {id: message.id_str});
  });
});

Your instant bot is just a JS function. Call instantBot with some configuration options and pass in a function to create a new bot. Once your bot is initialized, you can post messages, read new messages and mentions, and access the underlying Twitter/Mastodon client to do whatever the heck else you want. Load your favorite modules and go crazy—Instant Bot is designed to load a client and get out of your way. For all the details on what you can do with a Bot, see "The Bot API" below.

package.json

NPM looks in here for your project's dependencies. Make sure instant-bot is in here under the "dependencies" section. To add new stuff, run:

$ npm install --save <package-name>

README.md

If you include a README.md file in your project root, Glitch will serve it at your project's base URL. Link here from your bot's Twitter description!

$ npm install --save <package-name>

That's it! If your bot is complex, you'll probably want to create and require your own modules. If it's simple, you can open bot.js and start hacking!

You can see this whole example here.

Instant Bots on AWS Lambda

If you're building a more complicated bot, you may want to run it on AWS Lambda.

Creating an Instant Bot

To create a new bot, run:

$ instant-bot create

The CLI will prompt you for a project name and ask whether you're building a bot for Twitter or Mastodon.

Anatomy of your Instant Bot

Your new instant bot is a serverless framework application. The instant-bot CLI provides a handful of helper commands, but it's basically a lightweight wrapper around Serverless.

A new instant bot looks something like this:

$ tree lipogram-bot
.
├── .env - Stores secrets like your Twitter API keys.
├── .gitignore - Sane defaults so you don't check in your secrets!
├── bot.js - Where your bot code should live.
├── handler.js - The handler function that AWS Lambda calls to start your bot every time it runs.
├── package.json - Dependencies, including the instant-bot library.
└── serverless.yml - Serverless Framework configuration.

Let's walk through each of these files in order.

.env.example

Your instant bot uses dotenv to load secrets as enviroment variables when it starts up. Edit your new bot's .env and fill in the details.

If you're building a Twitter bot, your .env should looks something like this:

AWS_ACCESS_KEY_ID=<your AWS access key ID>
AWS_SECRET_ACCESS_KEY=<your AWS secret access key>
TWITTER_CONSUMER_KEY=<your twitter consumer key>
TWITTER_CONSUMER_SECRET=<your twitter consumer secret>
TWITTER_ACCESS_TOKEN=<your twitter access token>
TWITTER_ACCESS_TOKEN_SECRET=<your twitter access token secret>

If you're building a Mastodon bot, your .env will include Mastodon-related variables instead:

MASTODON_ACCESS_TOKEN=<your Mastodon access token>
MASTODON_API_URL="https://oulipo.social/api/v1/"

You'll need to get all these secrets from somewhere. Here's a guide on how to get your AWS access keys. Here's how to get Twitter access tokens. Here's a tool for generating your Mastodon token.

Note: .env.example is just an example file! Make sure you create your own .env file including all the variables in .env.example or your bot won't work!

.gitignore

This file makes sure you don't accidentally check in your secret keys if you save your instant bot in a Git repository or push it to Github. It excludes your .env file and the node_modules directory by default.

bot.js

The core of your application. It will look something like this:

const instantBot = require('instant-bot');

module.exports.run = () => {

  instantBot({service: 'twitter'}, (bot) => {
    bot.post('Hola from lipogram bot!');
    bot.messages.filter(m => !m.text.includes('e')).map((message) => {
      bot.client.post('statuses/retweet/:id', {id: message.id_str})
    });
  });

};

Your instant bot is just a JS function. Call instantBot with some configuration options and pass a function to create a new bot. Once your bot is initialized, you can post messages, read new messages and mentions, and access the underlying Twitter/Mastodon client to do whatever the heck else you want. Load your favorite modules and go crazy—Instant Bot is designed to load a client and get out of your way. For all the details on what you can do with a Bot, see "The Bot API" below.

handler.js

This is the Serverless Framework handler that AWS Lambda will call every time your bot runs. It's pretty simple by default: it just imports and runs your bot code. (But it can do anything a Serverless handler can do, if you want!)

'use strict';

const bot = require('./bot');

module.exports.runBot = (event, context, callback) => {
  bot.run();
  callback(null, { message: 'Your bot ran successfully!', event });
};

Note: Lambda is stateless! If your bot needs persistent data, you'll have to store it somewhere else. Consider writing JSON data to S3, or saving data to a DynamoDB table.

package.json

NPM looks in here for your project's dependencies. Make sure instant-bot is in here under the "dependencies" section. To add new stuff, run:

$ npm install --save <package-name>

Note: When Serverless deploys your bot to AWS Lambda, it zips up and uploads your bot's project directory—including its node_modules! If you add a new dependency, make sure to install it with npm install before deploying your bot! Lamda won't run npm install when it deploys your bot—it's up to you to run it locally!

serverless.yml

A Serverless Framework configuration file. Your instant bot's file is pretty simple by default:

service: lipogram-bot

provider:
  name: aws
  runtime: nodejs6.10

package:
  include:
    - .env
    - node_modules

functions:
  runBot:
    handler: handler.runBot
    events:
      - schedule: rate(1 minute)

This configures the Lambda function that runs your bot to run on Node 6.10 and trigger handler.runBot every minute. You can do lots and lots of stuff with your serverless.yml, including spinning up other AWS resources, tweaking and triggering your Lambda function's configuration, and making your bot respond to other events, like HTTP requests or SNS messages. You have the full power of Serverless at your disposal.

That's it! If your bot is complex, you'll probably want to create and require your own modules. If it's simple, you can open bot.js and start hacking!

You can see this whole example here.

Deploying your Instant Bot

Once you've copied your secrets to .env, and installed your bot's dependencies with npm install, deploy your bot with:

$ instant-bot deploy

This basically just delegates to serverless deploy. Since your bot is just a serverless app, you can use the Serverless CLI to deploy it, too.

Debugging your Instant Bot

To see your bot's logs, run:

$ instant-bot logs

(This delegates to serverless logs -f runBot.)

Removing your Instant Bot

To shut down your bot and delete its Lambda, run:

$ instant-bot remove

(This delegates to serverless remove. Get the picture? 😸)

The Bot API

Configuration

To create a new bot, require('instant-bot') and call it with configuration options:

const instantBot = require('instant-bot');

instantBot({
  service: 'twitter',
  rate: '1 minute',
  host: 'aws'
});

Options:

  • service: The service your bot will use. Either 'twitter' or 'mastodon'.
  • rate: How frequently your bot should post new messages. This can be any human-readable time juration can parse, like '30 minutes' or '2 days'.
  • host: Where your bot runs. Either 'aws' or 'glitch'

The Bot object

When your bot spins up, it loads some useful data:

Attributes:

  • bot.messages: an array of new messages from users your bot follows.
  • bot.mentions: an array of new messages that mention your bot.
  • bot.recentPosts: an array containing the last few messages your bot posted.

Your bot keeps track of the last time it ran, so these only load new messages and mentions. Each of these arrays contains

The Bot object also provides a convenience method for posting a new message. This is super simple right now:

Methods:

  • bot.post(message): post a message to your bot's timeline.

Finally, your bot has access to its underlying Twitter/Mastodon client if you want do do anything more complex:

Attribute:

  • bot.client: your bot's underlying client library. This is twit for Twitter and node-mastodon for Mastodon.

The bot API is meant to be a little bit of sugar on top of the underlying client library. This abstraction is intentionally leaky: use the client library to do the really complex stuff!

More Resources

Contributions

Are welcome! Open an issue or send a pull request.

Contributors

Thanks to mekaseymour for pairing on Glitch README pages.

License

This project is released under an MIT license. See LICENSE.txt if you want to read one.

About

⚡️🤖 Instant bots on AWS Lambda ⚡️

Resources

License

Stars

Watchers

Forks

Packages

No packages published