initial commit

This commit is contained in:
ale 2024-09-29 02:52:17 +02:00
commit 1ab6746d9a
5 changed files with 137 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

17
README.md Normal file
View File

@ -0,0 +1,17 @@
# Chess Bot for Mastodon
## Install
npm i or yarn
## Config
edit config.js
## Run
npm start
## License
MIT

5
config.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = {
nick: 'chessbot',
accessToken: '',
url: 'mastodon.manalejandro.com'
}

87
index.js Normal file
View File

@ -0,0 +1,87 @@
const { createRestAPIClient, createStreamingAPIClient } = require('masto'),
jsChessEngine = require('js-chess-engine'),
ChessImageGenerator = require('chess-image-generator'),
config = require('./config.js'),
fs = require('fs');
(async () => {
const nick = config.nick,
rest = createRestAPIClient({
url: `https://${config.url}`,
accessToken: config.accessToken,
requestInit: {
headers: [
['User-Agent', nick]
]
}
}),
ws = createStreamingAPIClient({
streamingApiUrl: `wss://${config.url}`,
accessToken: config.accessToken,
retry: true
}),
sendMessage = async (game, aimove, status, msg) => {
const imageGenerator = new ChessImageGenerator({
size: 720,
light: 'rgb(200, 200, 200)',
dark: '#333333',
style: 'merida'
})
await imageGenerator.loadFEN(game.exportFEN())
const buf = await imageGenerator.generateBuffer(),
statusImage = await rest.v2.media.create({
file: new Blob([buf], { type: 'image/png' }),
skipPolling: true,
description: aimove ? `Chessbot move ${Object.keys(aimove)[0]} to ${Object.values(aimove)[0]}` : 'Chessbot'
})
let canmove
if (aimove) {
moves = game.moves()
canmove = Object.keys(moves).map(key => `move ${key} to ${moves[key].join(', ')}`)
}
await rest.v1.statuses.create({
status: `${msg}${aimove ? '\nMovimientos posibles:\n' + canmove.join('\n') : ''}`,
mediaIds: [statusImage.id],
visibility: 'public',
inReplyToId: status?.id,
language: status?.language
})
}
let game
if (fs.existsSync('game.txt')) {
game = new jsChessEngine.Game(JSON.parse(fs.readFileSync('game.txt').toString()))
sendMessage(game, null, null, `Partida en juego. Su turno.`)
}
for await (const notification of ws.user.notification.subscribe()) {
if (notification.payload['type'] === 'mention' && notification.payload['status']) {
const status = notification.payload['status']
if (status && status.visibility !== 'direct' && status.account.acct !== nick && status.content.trim() !== '') {
const content = ('' + status.content).replace(/<[^>]*>?/gm, '').split(' ').filter(token => !token.startsWith('@'))
if (!game || game?.status?.isFinished) {
game = new jsChessEngine.Game()
sendMessage(game, status, 'Una partidita de ajedrez profesor Falken?')
}
else if (content.length > 1
&& content[0] === 'move'
&& content[1].match(/^[A-H]{1}[1-8]{1}$/)
&& content[2].match(/^[A-H]{1}[1-8]{1}$/)) {
game.move(content[1], content[2])
const d = Date.now(),
levelIA = Math.floor(Math.random() * 5),
aimove = game.aiMove(levelIA),
time = Date.now() - d
if (game?.status && game?.status?.checkMate) {
await sendMessage(game, aimove, status, 'Jaque.')
} else {
await sendMessage(game, aimove, status, `Su turno, movimiento IA ${Object.keys(aimove)[0]} a ${Object.values(aimove)[0]} nivel ${levelIA + 1} en ${time / 1000}s`)
}
}
if (game?.status?.isFinished) {
fs.rmSync('game.txt')
} else {
fs.writeFileSync('game.txt', JSON.stringify(game.exportJson()))
}
}
}
}
})()

27
package.json Normal file
View File

@ -0,0 +1,27 @@
{
"name": "chessbot-mastodon",
"version": "1.0.0",
"description": "Chess Bot for mastodon",
"main": "index.js",
"private": true,
"scripts": {
"start": "node index.js"
},
"repository": {
"type": "git",
"url": "https://git.manalejandro.com/ale/chessbot-mastodon"
},
"keywords": [
"bot",
"activity",
"mastodon",
"chess"
],
"author": "ale",
"license": "MIT",
"dependencies": {
"chess-image-generator": "^1.0.9",
"js-chess-engine": "^1.0.2",
"masto": "^6.8.0"
}
}