├── .gitignore ├── .env.dist ├── package.json ├── now.json ├── README.md ├── LICENSE └── src └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | .env 4 | -------------------------------------------------------------------------------- /.env.dist: -------------------------------------------------------------------------------- 1 | DISCORD_TOKEN = "" 2 | DISCORD_CHANNEL_ID = "" 3 | 4 | # To get credentials, create an app on 5 | # https://developer.twitter.com/ 6 | 7 | TWITTER_CONSUMER_KEY="" 8 | TWITTER_CONSUMER_SECRET="" 9 | TWITTER_ACCESS_TOKEN_KEY="" 10 | TWITTER_ACCESS_TOKEN_SECRET="" 11 | 12 | # Add a comma separated list of keywords (add hash for hashtags) 13 | TWITTER_KEYWORDS="" 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "drawingbotsbot", 3 | "version": "1.0.0", 4 | "description": "Bot for Drawingbots Discord", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "dev": "backpack dev", 8 | "build": "backpack build", 9 | "start": "NODE_ENV=production node build/main.js" 10 | }, 11 | "author": "Jonathan Berger", 12 | "license": "MIT", 13 | "dependencies": { 14 | "backpack-core": "^0.8.3", 15 | "discord.js": "^11.4.2", 16 | "dotenv": "^6.1.0", 17 | "express": "^4.16.4", 18 | "twitter": "^1.7.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /now.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "name": "drawingbots-bot", 4 | "builds": [ 5 | { "src": "src/index.js", "use": "@now/node" } 6 | ], 7 | "env": { 8 | "NODE_ENV": "production", 9 | "DISCORD_TOKEN": "@discord_token", 10 | "DISCORD_CHANNEL_ID": "@discord_channel_id", 11 | "TWITTER_CONSUMER_KEY": "@twitter_consumer_key", 12 | "TWITTER_CONSUMER_SECRET": "@twitter_consumer_secret", 13 | "TWITTER_ACCESS_TOKEN_KEY": "@twitter_access_token_key", 14 | "TWITTER_ACCESS_TOKEN_SECRET": "@twitter_access_token_secret", 15 | "TWITTER_KEYWORDS": "@twitter_keywords" 16 | } 17 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Drawingbots Bot 2 | 3 | The bot for the Drawingbots Discord server. For now it just sends #plottertwitter tweets to a Discord channel. 4 | 5 | ## Set up 6 | 7 | 1. Create an application then a bot on Discord: https://discordapp.com/developers/applications/ 8 | 1. Calculate permissions for your bot here https://discordapi.com/permissions.html#23552 9 | 1. Create an app for Twitter (your developer account will need to be verified) https://developer.twitter.com 10 | 11 | ## Run 12 | 13 | 1. Copy `.env.dist` to `.env` and fill in your credentials for Discord and Twitter. Also, choose twitter keywords (add hash character for hashtags). 14 | 1. `npm install` 15 | 1. `node src/index.js` 16 | 17 | ### Find the Discord channel ID 18 | 19 | Uncomment this line to list all channels the bot belongs to : 20 | 21 | ```bot.channels.map((chan) => console.log(chan.id, chan.name));``` 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Jonathan Berger 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const Discord = require('discord.js'); 2 | const Twitter = require('twitter'); 3 | require('dotenv').config(); 4 | 5 | const express = require('express') 6 | const app = express() 7 | const port = 3000 8 | 9 | const twitter = new Twitter({ 10 | consumer_key: process.env.TWITTER_CONSUMER_KEY, 11 | consumer_secret: process.env.TWITTER_CONSUMER_SECRET, 12 | access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY, 13 | access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET 14 | }); 15 | 16 | const bot = new Discord.Client(); 17 | let stream; 18 | 19 | bot.on('ready', function () { 20 | //bot.channels.map((chan) => console.log(chan.id, chan.name)); 21 | const chan = bot.channels.get(process.env.DISCORD_CHANNEL_ID); 22 | 23 | if (!chan) { 24 | console.log('Chan doesn\'t exist, nothing will happen here.'); 25 | return; 26 | } 27 | 28 | console.log('Connected to Discord Server.'); 29 | 30 | if (stream) { 31 | // stream already started 32 | console.log('Stream already started.'); 33 | return; 34 | } 35 | 36 | try { 37 | stream = twitter.stream('statuses/filter', { track: process.env.TWITTER_KEYWORDS }); 38 | } catch (e) { 39 | console.log(e); 40 | } 41 | 42 | 43 | stream.on('data', function (tweet) { 44 | if (tweet && !tweet.retweeted_status) { 45 | const url = `https://twitter.com/${tweet.user.screen_name}/status/${tweet.id_str}`; 46 | console.log('New tweet !', url); 47 | chan.send(url); 48 | } 49 | }); 50 | 51 | stream.on('error', function (error) { 52 | console.log('Error from twitter.'); 53 | console.log(error.message); 54 | }); 55 | }); 56 | 57 | bot.on('error', (error) => { 58 | console.log("Error from discord."); 59 | console.log(error.message); 60 | }); 61 | 62 | 63 | bot.login(process.env.DISCORD_TOKEN); 64 | 65 | app.get('*', (req, res) => { 66 | return handle(req, res) 67 | }) 68 | 69 | app.listen(port, err => { 70 | if (err) throw err 71 | console.log(`> Web service ready on port ${port}`) 72 | }) 73 | --------------------------------------------------------------------------------