commit 619eca519aa8f65bf8b018fbd0ef1cbf644f72d6 Author: Thomas Forgione Date: Fri Mar 20 12:23:27 2020 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..29536b8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +package-lock.json +settings.json diff --git a/index.js b/index.js new file mode 100644 index 0000000..edc97a2 --- /dev/null +++ b/index.js @@ -0,0 +1,55 @@ +const port = 3000; + +const fs = require('fs'); +const tmi = require('tmi.js'); +const express = require('express'); +const app = express(); +const http = require('http').createServer(app); +const io = require('socket.io')(http); + +// Define configuration options +const opts = JSON.parse(fs.readFileSync('settings.json')); + +// Create a client with our options +const client = new tmi.client(opts); + +// Register our event handlers (defined below) +client.on('message', onMessageHandler); +client.on('connected', onConnectedHandler); + +// Connect to Twitch: +client.connect(); + +// Called every time a message comes in +function onMessageHandler (target, context, message, self) { + io.emit("message", { + target, + context, + message, + self + }); +} + +// Called every time the bot connects to Twitch chat +function onConnectedHandler() { + console.log("Connected to twitch"); +} + +app.get('/', function(req, res){ + res.sendFile(__dirname + '/static/index.html'); +}); + +app.use('/static', express.static('static')); + +io.on('connection', function(socket){ + socket.on('message', function(message) { + io.emit('message', message); + }); + + socket.on('disconnect', function() { + }); +}); + +http.listen(port, function(){ + console.log('Listening on port ' + port); +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..57dcd67 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "twitch-bot", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git@gitea.tforgione.fr:tforgione/twitch-bot" + }, + "author": "", + "license": "ISC", + "dependencies": { + "express": "^4.17.1", + "socket.io": "^2.3.0", + "tmi.js": "^1.5.0" + } +} diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..b2b85af --- /dev/null +++ b/static/index.html @@ -0,0 +1,13 @@ + + + + Twitch Chat + + + + + + + + + diff --git a/static/main.css b/static/main.css new file mode 100644 index 0000000..e95a929 --- /dev/null +++ b/static/main.css @@ -0,0 +1,47 @@ +body { + background-color: #18181b; + padding: 0px; + margin: 0px; + overflow: hidden; +} + +#messages { + color: white; + list-style-type: none; + position: absolute; + bottom: 0px; + margin: 0px; + padding: 0px; +} + +.slide { + animation: slide 0.5s forwards; +} + +.item { + width: 200px; + margin: 0.5rem; +} + +.destroy { + animation: disappear 1s; + opacity: 0; +} + +.text { + padding-right: 0.5rem; +} + +.name { + font-weight: bold; +} + +@keyframes slide { + from { } + to { bottom: 0rem; } +} + +@keyframes disappear { + from { opacity: 1; } + to { opacity: 0; } +} diff --git a/static/main.js b/static/main.js new file mode 100644 index 0000000..40b9f53 --- /dev/null +++ b/static/main.js @@ -0,0 +1,55 @@ +const timeout = 30000; + +class Message { + constructor(object, onDestroy) { + this.target = object.target; + this.context = object.context; + this.message = object.message; + this.self = object.self; + } + + createEl() { + this.element = document.createElement('li'); + this.element.className = "item"; + this.element.style.position = "relative"; + let name = document.createElement('span'); + name.className = "text name"; + name.style.color = this.context.color; + name.innerHTML = escapeHtml(this.context["display-name"]); + this.element.appendChild(name); + + let message = document.createElement('span'); + message.innerHTML = escapeHtml(this.message); + message.className = "text message"; + this.element.appendChild(message); + + setTimeout(() => this.destroy(), timeout); + return this.element; + } + + destroy() { + console.log(this.element); + this.element.className += ' destroy'; + } +} + +function escapeHtml(unsafe) { + return unsafe + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +} + +function addMessage(object) { + messages .className = ""; + let message = new Message(object); + messages.appendChild(message.createEl()); + messages.style.bottom = '-' + message.element.offsetHeight + 'px'; + messages.className = "slide"; +}; + +let messages = document.getElementById('messages'); +let socket = io(); +socket.on('message', addMessage);