├── .nvmrc ├── .gitignore ├── .editorconfig ├── modules ├── about │ └── index.js ├── spam │ └── index.js └── logs │ └── index.js ├── terraform ├── variables.tf ├── providers.tf └── apps.tf ├── .eslintrc.json ├── bots └── midnabot.js ├── index.js ├── package.json ├── LICENSE ├── CONTRIBUTING.md └── Readme.md /.nvmrc: -------------------------------------------------------------------------------- 1 | 16 2 | 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | .terraform* 4 | *.tfvars 5 | 6 | .env 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | trim_trailing_whitespace = true 3 | insert_final_newline = true 4 | indent_style = space 5 | indent_size = 2 6 | 7 | -------------------------------------------------------------------------------- /modules/about/index.js: -------------------------------------------------------------------------------- 1 | const info = require('../../package.json') 2 | 3 | const about = (ctx) => { 4 | const about = `*Midnabot* v${info.version}\n` + `${info.homepage}` 5 | ctx.replyWithMarkdown(about) 6 | } 7 | 8 | module.exports = { about } 9 | -------------------------------------------------------------------------------- /terraform/variables.tf: -------------------------------------------------------------------------------- 1 | variable "do_token" { 2 | description = "digital ocean access token" 3 | type = string 4 | } 5 | 6 | variable "telegram_token" { 7 | description = "telegram bot token" 8 | type = string 9 | } 10 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "commonjs": true, 4 | "es2021": true, 5 | "node": true 6 | }, 7 | "extends": [ 8 | "standard" 9 | ], 10 | "parserOptions": { 11 | "ecmaVersion": 12 12 | }, 13 | "rules": { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /modules/spam/index.js: -------------------------------------------------------------------------------- 1 | let overflow = false 2 | 3 | const flow = (ctx, next) => { 4 | if (!overflow) { 5 | overflow = true 6 | setTimeout(() => { overflow = false }, 1000) 7 | next() 8 | } 9 | 10 | process.stdout.write('Overflow protection\n') 11 | } 12 | 13 | module.exports = { flow } 14 | -------------------------------------------------------------------------------- /terraform/providers.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | cloud { 3 | organization = "o0th" 4 | 5 | workspaces { 6 | name = "midnabot" 7 | } 8 | } 9 | 10 | required_providers { 11 | digitalocean = { 12 | source = "digitalocean/digitalocean" 13 | version = "~> 2.0" 14 | } 15 | } 16 | } 17 | 18 | provider "digitalocean" { 19 | token = var.do_token 20 | } 21 | -------------------------------------------------------------------------------- /bots/midnabot.js: -------------------------------------------------------------------------------- 1 | const { Telegraf } = require('telegraf') 2 | 3 | const { logs } = require('../modules/logs') 4 | const { spam } = require('../modules/spam') 5 | const { version, homepage } = require('../package.json') 6 | 7 | const midnabot = new Telegraf(process.env.TELEGRAM_TOKEN) 8 | 9 | midnabot.use(logs('midnabot')) 10 | midnabot.use(spam) 11 | 12 | midnabot.command('about', (ctx) => { 13 | const about = `*Midnabot* v${version}\n` + `${homepage}` 14 | ctx.replyWithMarkdown(about) 15 | }) 16 | 17 | module.exports = { midnabot } 18 | -------------------------------------------------------------------------------- /modules/logs/index.js: -------------------------------------------------------------------------------- 1 | const logs = (bot) => (ctx, next) => { 2 | if (ctx.update.message) { 3 | const user = ctx.update.message.from.username 4 | const text = ctx.update.message.text 5 | const type = ctx.update.message.chat.type 6 | const chat = ctx.update.message.chat.title 7 | const log = (type === 'private') 8 | ? `[${bot}] Request from "${user}" in ${type}: ${text}\n` 9 | : `[${bot}] Request from "${user}" in ${type} "${chat}": ${text}\n` 10 | process.stdout.write(log) 11 | } 12 | 13 | return next() 14 | } 15 | 16 | module.exports = { logs } 17 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config() 2 | 3 | const { midnabot } = require('./bots/midnabot') 4 | 5 | /** Start bots in development mode (polling) */ 6 | const development = () => { 7 | process.stdout.write('Bots starting in development mode...\n') 8 | midnabot.launch() 9 | } 10 | 11 | /** Start bots in production mode (webhook) */ 12 | const production = async () => { 13 | const app = require('express')() 14 | 15 | const domain = process.env.SERVICE_URL 16 | const port = Number(process.env.SERVICE_PORT) 17 | 18 | app.use(await midnabot.createWebhook({ domain })) 19 | app.get('/', (req, res) => res.send('OK')) 20 | 21 | app.listen(port, () => { 22 | process.stdout.write('Bots starting in production mode...\n') 23 | }) 24 | } 25 | 26 | process.env.NODE_ENV === 'production' 27 | ? (async () => await production())() 28 | : development() 29 | 30 | /** Graceful stop */ 31 | process.once('SIGINT', () => { 32 | midnabot.stop('SIGINT') 33 | }) 34 | 35 | process.once('SIGTERM', () => { 36 | midnabot.stop('SIGTERM') 37 | }) 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "midnabot", 3 | "version": "0.3.2", 4 | "description": "midnabot for telegram", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js", 8 | "dev": "nodemon index.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+ssh://git@github.com/o0th/midnabot.git" 14 | }, 15 | "author": "Sabato Luca Guadagno ", 16 | "license": "MIT", 17 | "bugs": { 18 | "url": "https://github.com/o0th/midnabot/issues" 19 | }, 20 | "homepage": "https://github.com/o0th/midnabot#readme", 21 | "devDependencies": { 22 | "eslint": "^7.26.0", 23 | "eslint-config-standard": "^16.0.2", 24 | "eslint-plugin-import": "^2.22.1", 25 | "eslint-plugin-node": "^11.1.0", 26 | "eslint-plugin-promise": "^4.3.1", 27 | "nodemon": "^2.0.7" 28 | }, 29 | "dependencies": { 30 | "axios": "^0.21.4", 31 | "dotenv": "^9.0.2", 32 | "express": "^4.18.2", 33 | "telegraf": "^4.10.0" 34 | }, 35 | "engines": { 36 | "node": ">= 16" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 - 2021 Sabato Luca Guadagno 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 | 23 | -------------------------------------------------------------------------------- /terraform/apps.tf: -------------------------------------------------------------------------------- 1 | resource "digitalocean_app" "midnabot" { 2 | spec { 3 | name = "midnabot" 4 | region = "fra" 5 | 6 | service { 7 | name = "midnabot-service" 8 | environment_slug = "node-js" 9 | 10 | instance_count = 1 11 | instance_size_slug = "basic-xxs" 12 | 13 | run_command = "npm start" 14 | http_port = 3000 15 | 16 | env { 17 | key = "NODE_ENV" 18 | value = "production" 19 | scope = "RUN_TIME" 20 | } 21 | 22 | env { 23 | key = "SERVICE_PORT" 24 | value = "$${_self.PRIVATE_PORT}" 25 | scope = "RUN_TIME" 26 | } 27 | 28 | env { 29 | key = "SERVICE_URL" 30 | value = "$${_self.PUBLIC_URL}" 31 | scope = "RUN_TIME" 32 | } 33 | 34 | env { 35 | key = "TELEGRAM_TOKEN" 36 | value = var.telegram_token 37 | scope = "RUN_TIME" 38 | } 39 | 40 | github { 41 | repo = "o0th/midnabot" 42 | branch = "master" 43 | 44 | deploy_on_push = true 45 | } 46 | 47 | health_check { 48 | failure_threshold = 0 49 | initial_delay_seconds = 0 50 | period_seconds = 0 51 | success_threshold = 0 52 | timeout_seconds = 0 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | This guide is for everyone who want to contribute or who want to run a personal 4 | instance of Midnabot. If you need help or you want to report a bug, just open 5 | an issue. 6 | 7 | ## Code Style 8 | 9 | [![standard][standard-image]][standard-url] 10 | 11 | This repository uses [`standard`][standard-url] to maintain code style and consistency, 12 | and to avoid style arguments. `npm test` runs `standard` automatically, so you don't have 13 | to! 14 | 15 | [standard-image]: https://cdn.rawgit.com/standard/standard/master/badge.svg 16 | [standard-url]: https://github.com/standard/standard 17 | 18 | 19 | ### Development 20 | 21 | Install dependencies 22 | ```bash 23 | npm install 24 | ``` 25 | 26 | Create a `.env` file 27 | ```bash 28 | PORT= 29 | TELEGRAM= 30 | ``` 31 | 32 | Start 33 | ```bash 34 | npm run dev 35 | ``` 36 | 37 | ### Deployment 38 | 39 | **Digitalocean app** 40 | 41 | In the `infrastructures` directory is avaliable a `terraform` script for an 42 | easy deployment on `digitalocean app`. Environment variables required are 43 | listen in `infrastructures/main.tf` if you want to deploy on a different 44 | service. 45 | 46 | **Systemd** 47 | 48 | First create a user and a group 49 | 50 | ```bash 51 | sudo useradd -r -s /bin/bash -G midnabot midnabot 52 | ``` 53 | 54 | Copy the configuration file 55 | 56 | ```bash 57 | sudo cp midnabot.service /etc/systemd/system/midnabot.service 58 | ``` 59 | 60 | Enable the service 61 | 62 | ```bash 63 | sudo systemctl enable midnabot 64 | ``` 65 | 66 | Start the service 67 | 68 | ```bash 69 | sudo systemctl start midnabot 70 | ``` 71 | 72 | Check logs 73 | 74 | ```bash 75 | sudo journalctl -u midnabot 76 | ``` 77 | 78 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | ## midnabot 2 | 3 |

4 | 5 | Version 6 | 7 | 8 | Standard 9 | 10 | 11 | Telegram 12 | 13 | 14 | License 15 | 16 |

17 | 18 | `midnabot` is a opensource [telegram](https://telegram.org/) bot written in 19 | `JavaScript` for the [Node.js](https://nodejs.org/en/) runtime, it use the 20 | [telegraf](https://github.com/telegraf/telegraf) framework and the 21 | [axios](https://github.com/axios/axios) http client, both released under 22 | the [MIT License](https://en.wikipedia.org/wiki/MIT_License). You can start 23 | using it by searching `midnabot` on telegram or following the version badge 24 | link. `midnabot` is deployed on [`digitalocean`](https://www.digitalocean.com/) 25 | [`app platform`](https://www.digitalocean.com/products/app-platform/) via 26 | [`terraform`](https://www.terraform.io/) configuration files. 27 | 28 | 29 | ### Contribute 30 | 31 | `midnabot` is an opensource project that runs on donations to pay the 32 | cloud infrastructures where it runs. If you want to contribute or just 33 | run your own instance you can follow the [contributing](/CONTRIBUTING.md) 34 | guide. If you want to say thank you and/or support the active development 35 | add a :star: to the project or donate a :coffee:. 36 | 37 | 38 | 39 | 40 | 41 | --------------------------------------------------------------------------------