Skip to content

Instantly share code, notes, and snippets.

@knolleary
Last active May 3, 2020 20:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save knolleary/a62a809cbebf0ac9f2c387888ae90c59 to your computer and use it in GitHub Desktop.
Save knolleary/a62a809cbebf0ac9f2c387888ae90c59 to your computer and use it in GitHub Desktop.
Save tweets to a database and display on a webpage

This is a variation of the example flow demonstrated in the Node-RED Introduction video - https://www.youtube.com/watch?v=vYreeoCoQPI

Configuring the flow

After importing the flow, you will need to:

  1. authorise the Twitter node to access your account
  2. pick a hashtag it should search for (defaults to #starwars)
  3. point the mongo nodes at an instance of mongodb (assumes it is running locally)

How it works

The main flow looks for tweets that match a given hashtag. They are then passed through sentiment analysis and tagged with an additional property based on whether they are deemed to be positive or negative. The tweets are then stored in a mongodb collection.

The second flow creates a HTTP endpoint at /tweets. This returns a formatted page of the 5 most recent tweets stored in the database. They are colour coded based on their sentiment score.

There is a third flow provided that clears out the mongodb collection when injected.

[{"id":"87b919a8.7237c8","type":"inject","z":"49f7aed8.60937","name":"Clear Tweets","topic":"","payload":"{}","payloadType":"str","repeat":"","crontab":"","once":false,"x":190,"y":420,"wires":[["ab1c97b9.3443b8"]]},{"id":"53089f3b.e4a25","type":"mongodb out","z":"49f7aed8.60937","mongodb":"8ff7c7cd.26e048","name":"","collection":"tweets","payonly":false,"upsert":false,"multi":false,"operation":"delete","x":553,"y":415,"wires":[]},{"id":"ab1c97b9.3443b8","type":"json","z":"49f7aed8.60937","name":"","x":325,"y":420,"wires":[["53089f3b.e4a25"]]},{"id":"66ad421c.8763ec","type":"http response","z":"49f7aed8.60937","name":"","x":697,"y":345,"wires":[]},{"id":"d0355233.f7c02","type":"twitter in","z":"49f7aed8.60937","twitter":"","tags":"#starwars","user":"false","name":"","topic":"tweets","x":155,"y":89,"wires":[["7525f2c2.dc288c"]]},{"id":"4c90a634.72c4c8","type":"debug","z":"49f7aed8.60937","name":"","active":true,"console":"false","complete":"false","x":623,"y":93,"wires":[]},{"id":"bf59d485.a49d28","type":"mongodb out","z":"49f7aed8.60937","mongodb":"8ff7c7cd.26e048","name":"Save Tweets","collection":"tweets","payonly":false,"upsert":false,"multi":false,"operation":"store","x":621,"y":133,"wires":[]},{"id":"c068fa5f.5beb48","type":"http in","z":"49f7aed8.60937","name":"","url":"/tweets","method":"get","swaggerDoc":"","x":159,"y":154,"wires":[["34dfcae6.aa4756"]]},{"id":"38644a8b.eb24a6","type":"mongodb in","z":"49f7aed8.60937","mongodb":"8ff7c7cd.26e048","name":"Retrieve Tweets","collection":"tweets","operation":"find","x":394,"y":277,"wires":[["e2828cd0.51057"]]},{"id":"e2828cd0.51057","type":"template","z":"49f7aed8.60937","name":"Styled Tweets","field":"payload","format":"handlebars","template":"<html>\n<head>\n <style>\nbody {\n text-align:center;\n}\nul {\n text-align:left;\n width: 500px;\n margin: auto;\n list-style-type:none;\n}\nli {\n border: 1px solid #999;\n border-left-width: 10px;\n border-radius: 3px;\n margin-bottom: 20px;\n padding: 10px;\n}\nli.sentiment_positive {\n border-left: 10px solid #69B369;\n}\nli.sentiment_negative {\n border-left: 10px solid #E64444;\n}\n.tweet {\n display: inline-block;\n font-family: Helvetica;\n width: 380px;\n margin-left: 10px;\n}\nimg {\n width: 48px;\n height: 48px;\n border-radius: 5px;\n vertical-align: top;\n}\n</style>\n\n</head>\n<body>\n\n<ul>\n{{#payload}}\n<li class=\"sentiment_{{sentiment.text}}\">\n <img src=\"{{tweet.user.profile_image_url}}\"/>\n <div class=\"tweet\">\n <div class=\"user\"><b>{{tweet.user.name}}</b> <small>@{{tweet.user.screen_name}}</small></div>\n <div class=\"text\">{{tweet.text}}</div>\n </div></li>\n{{/payload}}\n</ul>\n</body>\n</html>","x":581,"y":297,"wires":[["66ad421c.8763ec"]]},{"id":"34dfcae6.aa4756","type":"function","z":"49f7aed8.60937","name":"Limit/Sort","func":"msg.sort = {\"tweet.id\":-1};\nmsg.limit = 5;\nmsg.skip = 0;\nreturn msg;","outputs":1,"noerr":0,"x":296,"y":208,"wires":[["38644a8b.eb24a6"]]},{"id":"7525f2c2.dc288c","type":"sentiment","z":"49f7aed8.60937","name":"","x":294,"y":89,"wires":[["85b30950.448128"]]},{"id":"85b30950.448128","type":"function","z":"49f7aed8.60937","name":"","func":"if(msg.sentiment.score > 0 ) {\n msg.sentiment.text = \"positive\";\n} else if (msg.sentiment.score < 0) {\n msg.sentiment.text = \"negative\";\n}\nreturn msg;","outputs":1,"noerr":0,"x":431,"y":89,"wires":[["4c90a634.72c4c8","bf59d485.a49d28"]]},{"id":"7be2a2ea.401dbc","type":"template","z":"49f7aed8.60937","name":"Simple Tweet","field":"payload","format":"handlebars","template":"<ul>\n{{#payload}}\n <li>{{tweet.text}}</li>\n{{/payload}}\n</ul>","x":587,"y":233,"wires":[[]]},{"id":"8ff7c7cd.26e048","type":"mongodb","z":"49f7aed8.60937","hostname":"127.0.0.1","port":"27017","db":"tweets","name":""}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment