├── .gitignore ├── .env.example ├── fission.js ├── package.json ├── README.md ├── lambda.js ├── Dockerfile ├── webhook.js ├── .github └── workflows │ └── docker.yml ├── index.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | .env 4 | release.zip -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | BOT_TOKEN= 2 | WEBHOOK_PATH=/secret-path 3 | WEBHOOK_PORT=5000 -------------------------------------------------------------------------------- /fission.js: -------------------------------------------------------------------------------- 1 | const bot = require('./index') 2 | 3 | module.exports = async function(ctx) { 4 | await bot.handleUpdate(ctx.request.body, ctx.response); // make Telegraf process that data 5 | ctx.response.status(200).end() 6 | }; 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "build": "zip -r release.zip . -x '*.git*' -x '*node_modules*'", 4 | "start:webhook": "node webhook.js" 5 | }, 6 | "dependencies": { 7 | "dotenv": "^8.2.0", 8 | "grapheme-splitter": "^1.0.4", 9 | "telegraf": "^3.25.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 打字带空格的Bot 2 | 3 | 一个 Telegram Bot,支持`inline`模式 4 | 5 | 方便书写 恶 臭 文 字 6 | 7 | 部署在 AWS Lambda 8 | 9 | ## 使用方式 10 | 11 | 1. 直接发送消息给机器人 [@kongebot](https://t.me/kongebot) 帮你转换 12 | 2. 在消息框内使用`inline mode`:`@kongebot {需要加空格的文字}` 13 | 14 | ## 入口 15 | 16 | - [AWS Lambda](./lambda.js) 17 | - [Fission.io/default](./fission.js) -------------------------------------------------------------------------------- /lambda.js: -------------------------------------------------------------------------------- 1 | const bot = require('./index') 2 | 3 | /* AWS Lambda handler function */ 4 | exports.handler = (event, context, callback) => { 5 | const tmp = JSON.parse(event.body); // get data passed to us 6 | bot.handleUpdate(tmp); // make Telegraf process that data 7 | return callback(null, { // return something for webhook, so it doesn't try to send same stuff again 8 | statusCode: 200, 9 | body: '', 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:lts-alpine3.16 2 | 3 | # Create app directory 4 | WORKDIR /usr/src/app 5 | 6 | ENV BOT_TOKEN= 7 | ENV WEBHOOK_PATH /secret-path 8 | ENV WEBHOOK_PORT 5000 9 | 10 | # Install app dependencies 11 | # A wildcard is used to ensure both package.json AND package-lock.json are copied 12 | # where available (npm@5+) 13 | COPY package*.json ./ 14 | 15 | RUN npm install 16 | 17 | COPY . . 18 | 19 | EXPOSE 5000 20 | 21 | CMD [ "npm", "run", "start:webhook" ] -------------------------------------------------------------------------------- /webhook.js: -------------------------------------------------------------------------------- 1 | const bot = require('./index') 2 | if (!process.env.WEBHOOK_PATH) { 3 | const path = require('path') 4 | const envpath = path.resolve(__dirname, '.env') 5 | require('dotenv').config({ path: envpath }) 6 | } 7 | 8 | const webhook_path = process.env.WEBHOOK_PATH ? process.env.WEBHOOK_PATH : "/secret-path"; 9 | const webhook_port = process.env.WEBHOOK_PORT ? process.env.WEBHOOK_PORT : 5000; 10 | 11 | console.log(`HTTP webhook started at ${webhook_path} and port ${webhook_port}`) 12 | bot.startWebhook(webhook_path, null, webhook_port) -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: docker 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'master' 7 | 8 | jobs: 9 | docker: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - 13 | name: Set up QEMU 14 | uses: docker/setup-qemu-action@v2 15 | - 16 | name: Set up Docker Buildx 17 | uses: docker/setup-buildx-action@v2 18 | - 19 | name: Login to DockerHub 20 | uses: docker/login-action@v2 21 | with: 22 | username: ${{ secrets.DOCKERHUB_USERNAME }} 23 | password: ${{ secrets.DOCKERHUB_TOKEN }} 24 | - 25 | name: Build and push 26 | uses: docker/build-push-action@v3 27 | with: 28 | push: true 29 | tags: neverbehave/kongebot:latest -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | if (!process.env.BOT_TOKEN) { 2 | const path = require('path') 3 | const envpath = path.resolve(__dirname, '.env') 4 | require('dotenv').config({ path: envpath }) 5 | } 6 | const bot_token = process.env.BOT_TOKEN 7 | if (!bot_token) { 8 | console.error("No Bot token provided. Please double check.") 9 | } 10 | 11 | const Telegraf = require('telegraf') 12 | const GraphemeSplitter = require('grapheme-splitter'); 13 | const splitter = new GraphemeSplitter(); 14 | 15 | // generate id for result 16 | function hash(str) { 17 | var hash = 0, i, chr; 18 | if (str.length === 0) return hash; 19 | for (i = 0; i < str.length; i++) { 20 | chr = str.charCodeAt(i); 21 | hash = ((hash << 5) - hash) + chr; 22 | hash |= 0; // Convert to 32bit integer 23 | } 24 | return hash; 25 | } 26 | 27 | function split(str) { 28 | return splitter.splitGraphemes(str).join(' ') 29 | } 30 | 31 | const bot = new Telegraf(bot_token) 32 | 33 | bot.start((ctx) => ctx.reply('你 打 字 带 空 格?\r\n 直接发送要转换的消息,或者在inline模式输入文字')) 34 | bot.on('text', (ctx) => ctx.reply(split(ctx.message.text))) 35 | bot.on('callback_query', (ctx) => ctx.answerCbQuery()) 36 | bot.on('inline_query', (ctx) => { 37 | const result = [] 38 | let str = ctx.inlineQuery.query 39 | if (!str) { 40 | str = "114514" 41 | } 42 | result.push({ 43 | type: 'article', 44 | id: hash(str), 45 | title: '全部都来个空!', 46 | description: split(str).substring(0,30), 47 | input_message_content: { 48 | message_text: split(str) 49 | } 50 | }) 51 | // Using shortcut 52 | ctx.answerInlineQuery(result) 53 | }) 54 | 55 | module.exports = bot -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/node@^10.1.2": 6 | "integrity" "sha512-Zh5Z4kACfbeE8aAOYh9mqotRxaZMro8MbBQtR8vEXOMiZo2rGEh2LayJijKdlu48YnS6y2EFU/oo2NCe5P6jGw==" 7 | "resolved" "https://registry.npmjs.org/@types/node/-/node-10.12.7.tgz" 8 | "version" "10.12.7" 9 | 10 | "debug@^4.0.1": 11 | "integrity" "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==" 12 | "resolved" "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz" 13 | "version" "4.1.0" 14 | dependencies: 15 | "ms" "^2.1.1" 16 | 17 | "dotenv@^8.2.0": 18 | "integrity" "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" 19 | "resolved" "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz" 20 | "version" "8.2.0" 21 | 22 | "grapheme-splitter@^1.0.4": 23 | "integrity" "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" 24 | "resolved" "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz" 25 | "version" "1.0.4" 26 | 27 | "ms@^2.1.1": 28 | "integrity" "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 29 | "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz" 30 | "version" "2.1.1" 31 | 32 | "node-fetch@^2.2.0": 33 | "integrity" "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==" 34 | "resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz" 35 | "version" "2.3.0" 36 | 37 | "sandwich-stream@^2.0.1": 38 | "integrity" "sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ==" 39 | "resolved" "https://registry.npmjs.org/sandwich-stream/-/sandwich-stream-2.0.2.tgz" 40 | "version" "2.0.2" 41 | 42 | "telegraf@^3.25.0": 43 | "integrity" "sha512-W2L/9LIOndtzqgEnJPlDJS8Q/gwoRS/a7FvoV9kPhKwRWtJtiP8xhkr66GMbOhnB0RgSK6GMrgeZtXNzLn/bQg==" 44 | "resolved" "https://registry.npmjs.org/telegraf/-/telegraf-3.25.0.tgz" 45 | "version" "3.25.0" 46 | dependencies: 47 | "@types/node" "^10.1.2" 48 | "debug" "^4.0.1" 49 | "node-fetch" "^2.2.0" 50 | "sandwich-stream" "^2.0.1" 51 | "telegram-typings" "^3.6.0" 52 | 53 | "telegram-typings@^3.6.0": 54 | "integrity" "sha512-njVv1EAhIZnmQVLocZEADYUyqA1WIXuVcDYlsp+mXua/XB0pxx+PKtMSPeZ/EE4wPWTw9h/hA9ASTT6yQelkiw==" 55 | "resolved" "https://registry.npmjs.org/telegram-typings/-/telegram-typings-3.6.1.tgz" 56 | "version" "3.6.1" 57 | --------------------------------------------------------------------------------