├── .gitignore ├── README.md ├── database.sql ├── npm-debug.log ├── package.json ├── public ├── css │ └── style.css └── images │ ├── Seeking-weather-update.png │ ├── github-icon.png │ ├── post-details.png │ ├── screenshot-of-posts.png │ ├── twitter-bot-respone.png │ └── twitterbird.png ├── server.js └── src ├── utils ├── config.js └── response-manager.js ├── views └── index.html └── weather-bot.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | src/utils/config-locals.js 3 | .vscode/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Twitter-weather-update-bot 2 | A Twitter bot which waits for #hashTag and sends weather update of city via tweets to the user 3 | 4 | #How it Works 5 | 6 | ### Step 1: 7 | User tweets to get weather update using hashTag **#DhakaWeather** such as: 8 | 9 | ![Seeking Weather Update of Dhaka](https://raw.githubusercontent.com/rbrahul/Twitter-weather-update-bot/master/public/images/Seeking-weather-update.png "Seeking Weather Update of Dhaka") 10 | 11 | 12 | ### Step 2: 13 | The twiter weather BOT always filters hashTag **#DhakaWeather**. And when ueser tweets this hastag ths BOT automatically responds him back with Weather information. For Example: 14 | 15 | ![Twitter Weather BOT responded back with information to the user](https://raw.githubusercontent.com/rbrahul/Twitter-weather-update-bot/master/public/images/twitter-bot-respone.png "Twitter Weather BOT responded back with information to the user") 16 | 17 | #Tweets Monitoring 18 | You can see all the tweets and response to tweets with their details in Tweets Monitoring panel. (Page Refreshing needed, Ajax not Implemented) 19 | 20 | 21 | ![Twitter Weather BOT keeps trak of all the tweets to monitor](https://raw.githubusercontent.com/rbrahul/Twitter-weather-update-bot/master/public/images/screenshot-of-posts.png "Twitter Weather BOT keeps trak of all the tweets to monitor") 22 | 23 | #### Detail view of tweets 24 | 25 | ![Tweet details view to get more information](https://raw.githubusercontent.com/rbrahul/Twitter-weather-update-bot/master/public/images/post-details.png "weet details view to get more information") 26 | 27 | #Installation 28 | 29 | ### Create a Twitter Application 30 | Go to https://apps.twitter.com/ and create a new Application. Then you will get consumer key, secret and access_token 31 | 32 | 33 | ### Get Weather API Key: 34 | Go to http://openweathermap.org/appid. If you don't have account yet you need to sign up to get free API Key. Their's APIs are really awesome. Don't hasitate. 35 | 36 | ### Create MySQL Database: 37 | Create a mysql database named as **twitter_bot**. or anything else. Then import the database schema from **database.sql** file from your project root directory. 38 | 39 | ####Change Configuration: 40 | After completing above steps please change the configuration file with your own App specific Information 41 | In **src\utils\config.js**: 42 | 43 | ```js 44 | module.exports.tweeterConfig = { 45 | consumer_key: 'YOUR_consumer_key', 46 | consumer_secret: 'YOUR_consumer_secret', 47 | access_token_key: 'YOUR_access_token_key', 48 | access_token_secret: 'YOUR_access_token_secret' 49 | }; 50 | 51 | 52 | module.exports.database = { 53 | host: 'localhost', 54 | user: 'root', // replace the user name with your own 55 | password: 'YOUR_DB_PASSWORD', // replace the password with your own 56 | database: 'twitter_bot' 57 | }; 58 | 59 | module.exports.APILocationInfo = { 60 | weatherAPIKEY: '240fae0e48fd82c8f35f6657c96496e4', 61 | hashTag: '#DhakaWeather', // you may replace it with your own 62 | cityID: '1337179', //This id denotes Dhaka, Bangladesh. To replace with your one get it from openweather.org 63 | cityNamye: 'Dhaka' // This City Name will be used when response back to the tweets. You may change it 64 | }; 65 | ``` 66 | 67 | ###Final Stage: 68 | I think you have successfully configured these information. If everything goes well run following line in your Terminal or Command Line Tools from project directory: 69 | 70 | ```sh 71 | $ npm start 72 | ``` 73 | Then go to [http://localhost:3000](http://localhost:3000) and visit. At first you will get a blank table. But when someone tweets using your **#hashTag** the system will response him back and save to your database. 74 | You have to refresh your page to see the lates tweets. 75 | 76 | #Note 77 | Twitter application has some strict rules. As a result your app may be down for a short period while developing if you restart your server freequently or execute your twitter connection related codes. 78 | If you find any error related to status then read the twitter [API Error and Response Status](https://dev.twitter.com/overview/api/response-codes) document. 79 | 80 | 81 | **Developed with ♥ using Nodejs,Express, MySQL, Jquery, Nunjuck** 82 | 83 | -------------------------------------------------------------------------------- /database.sql: -------------------------------------------------------------------------------- 1 | -- phpMyAdmin SQL Dump 2 | -- version 4.4.15.1 3 | -- http://www.phpmyadmin.net 4 | -- 5 | -- Host: 127.0.0.1 6 | -- Generation Time: Feb 21, 2017 at 06:41 AM 7 | -- Server version: 5.6.28 8 | -- PHP Version: 5.6.17 9 | 10 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; 11 | SET time_zone = "+00:00"; 12 | 13 | 14 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 15 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 16 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 17 | /*!40101 SET NAMES utf8mb4 */; 18 | 19 | -- 20 | -- Database: `twitter_bot` 21 | -- 22 | 23 | -- -------------------------------------------------------- 24 | 25 | -- 26 | -- Table structure for table `posts` 27 | -- 28 | 29 | CREATE TABLE IF NOT EXISTS `posts` ( 30 | `id` int(11) NOT NULL, 31 | `sender` varchar(255) NOT NULL, 32 | `sender_message` varchar(255) NOT NULL, 33 | `reply_message` varchar(255) NOT NULL, 34 | `posted_at` varchar(20) DEFAULT NULL, 35 | `others` longtext NOT NULL 36 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 37 | 38 | -- 39 | -- Indexes for dumped tables 40 | -- 41 | 42 | -- 43 | -- Indexes for table `posts` 44 | -- 45 | ALTER TABLE `posts` 46 | ADD PRIMARY KEY (`id`); 47 | 48 | -- 49 | -- AUTO_INCREMENT for dumped tables 50 | -- 51 | 52 | -- 53 | -- AUTO_INCREMENT for table `posts` 54 | -- 55 | ALTER TABLE `posts` 56 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; 57 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 58 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 59 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 60 | -------------------------------------------------------------------------------- /npm-debug.log: -------------------------------------------------------------------------------- 1 | 0 info it worked if it ends with ok 2 | 1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'start' ] 3 | 2 info using npm@3.10.10 4 | 3 info using node@v7.2.1 5 | 4 verbose run-script [ 'prestart', 'start', 'poststart' ] 6 | 5 info lifecycle twitter-weather-update-bot@1.0.0~prestart: twitter-weather-update-bot@1.0.0 7 | 6 silly lifecycle twitter-weather-update-bot@1.0.0~prestart: no script for prestart, continuing 8 | 7 info lifecycle twitter-weather-update-bot@1.0.0~start: twitter-weather-update-bot@1.0.0 9 | 8 verbose lifecycle twitter-weather-update-bot@1.0.0~start: unsafe-perm in lifecycle true 10 | 9 verbose lifecycle twitter-weather-update-bot@1.0.0~start: PATH: /usr/local/lib/node_modules/npm/bin/node-gyp-bin:/home/rbrahul/Documents/nodeprojects/twitter-weather-update-bot/node_modules/.bin:/home/rbrahul/Downloads/genymotion:/usr/bin:/bin:/usr/sbin:/sbin:/home/rbrahul/Downloads/genymotion:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/jvm/java-8-oracle/bin:/usr/lib/jvm/java-8-oracle/db/bin:/usr/lib/jvm/java-8-oracle/jre/bin:/usr/local/go/bin 11 | 10 verbose lifecycle twitter-weather-update-bot@1.0.0~start: CWD: /home/rbrahul/Documents/nodeprojects/twitter-weather-update-bot 12 | 11 silly lifecycle twitter-weather-update-bot@1.0.0~start: Args: [ '-c', 'node server.js' ] 13 | 12 silly lifecycle twitter-weather-update-bot@1.0.0~start: Returned: code: 1 signal: null 14 | 13 info lifecycle twitter-weather-update-bot@1.0.0~start: Failed to exec start script 15 | 14 verbose stack Error: twitter-weather-update-bot@1.0.0 start: `node server.js` 16 | 14 verbose stack Exit status 1 17 | 14 verbose stack at EventEmitter. (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:255:16) 18 | 14 verbose stack at emitTwo (events.js:106:13) 19 | 14 verbose stack at EventEmitter.emit (events.js:191:7) 20 | 14 verbose stack at ChildProcess. (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:40:14) 21 | 14 verbose stack at emitTwo (events.js:106:13) 22 | 14 verbose stack at ChildProcess.emit (events.js:191:7) 23 | 14 verbose stack at maybeClose (internal/child_process.js:885:16) 24 | 14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5) 25 | 15 verbose pkgid twitter-weather-update-bot@1.0.0 26 | 16 verbose cwd /home/rbrahul/Documents/nodeprojects/twitter-weather-update-bot 27 | 17 error Linux 4.2.0-41-generic 28 | 18 error argv "/usr/local/bin/node" "/usr/local/bin/npm" "start" 29 | 19 error node v7.2.1 30 | 20 error npm v3.10.10 31 | 21 error code ELIFECYCLE 32 | 22 error twitter-weather-update-bot@1.0.0 start: `node server.js` 33 | 22 error Exit status 1 34 | 23 error Failed at the twitter-weather-update-bot@1.0.0 start script 'node server.js'. 35 | 23 error Make sure you have the latest version of node.js and npm installed. 36 | 23 error If you do, this is most likely a problem with the twitter-weather-update-bot package, 37 | 23 error not with npm itself. 38 | 23 error Tell the author that this fails on your system: 39 | 23 error node server.js 40 | 23 error You can get information on how to open an issue for this project with: 41 | 23 error npm bugs twitter-weather-update-bot 42 | 23 error Or if that isn't available, you can get their info via: 43 | 23 error npm owner ls twitter-weather-update-bot 44 | 23 error There is likely additional logging output above. 45 | 24 verbose exit [ 1, true ] 46 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twitter-weather-update-bot", 3 | "version": "1.0.0", 4 | "description": "This app watches the special hashtag for weather information and sends back the update information", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node server.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [ 11 | "twitter-bot", 12 | "weather-bot", 13 | "weather-update-bot" 14 | ], 15 | "author": "Rahul Baruri ", 16 | "license": "ISC", 17 | "dependencies": { 18 | "express": "^4.14.1", 19 | "mysql": "^2.13.0", 20 | "node-fetch": "^1.6.3", 21 | "nunjucks": "^3.0.0", 22 | "twitter": "^1.7.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /public/css/style.css: -------------------------------------------------------------------------------- 1 | .row{ 2 | margin-left: -15px; 3 | margin-right: -15px; 4 | } 5 | .content-area { 6 | margin-top:70px; 7 | } 8 | .container-fluid { 9 | padding-right: 15px; 10 | padding-left: 15px; 11 | margin-right: auto; 12 | margin-left: auto; 13 | } 14 | 15 | body{ 16 | overflow-x:hidden; 17 | } 18 | #example_filter { 19 | float:right; 20 | } -------------------------------------------------------------------------------- /public/images/Seeking-weather-update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbrahul/Twitter-bot/7c89cb2004382239f77da6a8fe4cc0c6096c8feb/public/images/Seeking-weather-update.png -------------------------------------------------------------------------------- /public/images/github-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbrahul/Twitter-bot/7c89cb2004382239f77da6a8fe4cc0c6096c8feb/public/images/github-icon.png -------------------------------------------------------------------------------- /public/images/post-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbrahul/Twitter-bot/7c89cb2004382239f77da6a8fe4cc0c6096c8feb/public/images/post-details.png -------------------------------------------------------------------------------- /public/images/screenshot-of-posts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbrahul/Twitter-bot/7c89cb2004382239f77da6a8fe4cc0c6096c8feb/public/images/screenshot-of-posts.png -------------------------------------------------------------------------------- /public/images/twitter-bot-respone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbrahul/Twitter-bot/7c89cb2004382239f77da6a8fe4cc0c6096c8feb/public/images/twitter-bot-respone.png -------------------------------------------------------------------------------- /public/images/twitterbird.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rbrahul/Twitter-bot/7c89cb2004382239f77da6a8fe4cc0c6096c8feb/public/images/twitterbird.png -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | require('./src/weather-bot'); 2 | var express = require('express'); 3 | var path = require('path'); 4 | var nunjucks = require('nunjucks'); 5 | var app = express(); 6 | var mysql = require('mysql'); 7 | const config = require('./src/utils/config'); 8 | var connection = mysql.createConnection(config.database); 9 | 10 | connection.connect(function (err) { 11 | if (err) { 12 | console.log("Error connecting database ..", err); 13 | } 14 | }); 15 | 16 | app.use(express.static(path.join(__dirname, 'public'))); 17 | 18 | // view engine setup 19 | app.set('views', path.join(__dirname, 'src/views')); 20 | app.set('view engine', 'html'); 21 | nunjucks.configure('src/views', { 22 | autoescape: true, 23 | express: app 24 | }); 25 | 26 | app.locals.cityName = config.APILocationInfo.cityName; 27 | app.get('/', function (req, res) { 28 | 29 | connection.query("SELECT * FROM posts ORDER BY id DESC", function (err, rows, fields) { 30 | if (!err) { 31 | 32 | res.render('index', { posts: rows }); 33 | } else { 34 | console.log('Error while performing Query.', err); 35 | } 36 | 37 | }); 38 | 39 | }); 40 | app.get('*', function (req, res) { 41 | res.send('

404, Page Not found

'); 42 | }); 43 | 44 | app.listen(3000, function () { 45 | console.log('Twitter weather update BOT listening on port 3000!\n visit: http://localhost:3000'); 46 | }) 47 | -------------------------------------------------------------------------------- /src/utils/config.js: -------------------------------------------------------------------------------- 1 | // Please replace these configuration with your owns 2 | 3 | module.exports.tweeterConfig = { 4 | consumer_key: 'YOUR_consumer_key', 5 | consumer_secret: 'YOUR_consumer_secret', 6 | access_token_key: 'YOUR_access_token_key', 7 | access_token_secret: 'YOUR_access_token_secret' 8 | }; 9 | 10 | 11 | module.exports.database = { 12 | host: 'localhost', 13 | user: 'root', // replace the user name with your own 14 | password: 'YOUR_DB_PASSWORD', // replace the password with your own 15 | database: 'twitter_bot' 16 | }; 17 | 18 | module.exports.APILocationInfo = { 19 | weatherAPIKEY: '240fae0e48fd82c8f35f6657c96496e4', 20 | hashTag: '#DhakaWeather', // you may replace it with your own 21 | cityID: '1337179', //This id denotes Dhaka, Bangladesh. To replace with your one get it from openweather.org 22 | cityName: 'Dhaka' 23 | }; 24 | 25 | -------------------------------------------------------------------------------- /src/utils/response-manager.js: -------------------------------------------------------------------------------- 1 | var fetch = require('node-fetch'); 2 | const APIInfo = require('./config').APILocationInfo; 3 | 4 | module.exports.getCurrentWeatherInfo = function () { 5 | return fetch(`http://api.openweathermap.org/data/2.5/weather?id=${APIInfo.cityID}&appid=${APIInfo.weatherAPIKEY}&units=Metric`); 6 | }; 7 | -------------------------------------------------------------------------------- /src/views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Twitter Weather Update BOT 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 22 |
23 | 46 |
47 |
48 |
49 |
50 | 51 |
52 |
53 |

Weather Update Posts

54 |
55 |
56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | {% for post in posts %} 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | {% else %} 85 |

No Posts Found ..

86 | {% endfor %} 87 | 88 | 89 |
NameUser's PostReply MessageTimeDetails
NameUser's PostReply MessageTimeDetails
{{post.sender}}{{post.sender_message}}{{post.reply_message}}{{post.posted_at}}Details
90 |
91 |
92 | 93 | 94 |
95 |
96 |
97 | 98 | 99 | 115 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 137 | 138 | -------------------------------------------------------------------------------- /src/weather-bot.js: -------------------------------------------------------------------------------- 1 | const TwitterPackage = require("twitter"); 2 | const fetch = require("node-fetch"); 3 | const responseManager = require("./utils/response-manager"); 4 | 5 | const config = require('./utils/config'); 6 | var Twitter = new TwitterPackage(config.tweeterConfig); 7 | var mysql = require('mysql'); 8 | var connection = mysql.createConnection(config.database); 9 | 10 | connection.connect(function (err) { 11 | if (err) { 12 | console.log("Error connecting database ..", err); 13 | } 14 | }); 15 | 16 | function escapeSingleQoute(text) { 17 | return text.replace(/\'/g, "\\'") 18 | } 19 | 20 | function sendPostBack(sender, sender_message, reply_message, others) { 21 | Twitter.post('statuses/update', { status: reply_message }, function (error, tweet, response) { 22 | if (error) { 23 | console.log(error); 24 | } else { 25 | const timeStr = new Date().toString(); 26 | connection.query("INSERT INTO posts(`sender`,`sender_message`,`reply_message`,`posted_at`,`others`) VALUES('" + sender + "','" + sender_message + "','" + reply_message + "','" + timeStr + "','" + others + "')", function (err, rows, fields) { 27 | if (!err) { 28 | console.log('Post have been stored: ', rows); 29 | } else { 30 | console.log('Error while performing Query.', err); 31 | } 32 | 33 | }); 34 | } 35 | 36 | }); 37 | } 38 | 39 | 40 | Twitter.stream('statuses/filter', { track: config.APILocationInfo.hashTag }, 41 | function (stream) { 42 | stream.on('data', function (tweet) { 43 | responseManager.getCurrentWeatherInfo() 44 | .then(function (response) { 45 | return response.json(); 46 | }) 47 | .then(function (response) { 48 | const mentionString = '@' + tweet.user.screen_name; 49 | const weatherInfo = `Weather of ${config.APILocationInfo.cityName}: ${response.weather[0].description}, Temperature:${response.main.temp} Celcious, Humidity: ${response.main.humidity}` 50 | const reply_message = `Hi ${mentionString}! ${weatherInfo}`; 51 | const sender_message = tweet.text; 52 | sendPostBack(escapeSingleQoute(mentionString), escapeSingleQoute(sender_message), escapeSingleQoute(reply_message), escapeSingleQoute(JSON.stringify(tweet, null, 4))); 53 | }); 54 | 55 | console.log(tweet.text); 56 | }); 57 | stream.on('error', function (error) { 58 | console.log('error found', error); 59 | }); 60 | }); 61 | --------------------------------------------------------------------------------