commit 84e7727484007d588cc8c38d8d1d0871a6479595 Author: Nils Date: Sat Aug 30 16:53:36 2025 +0200 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0ad007c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +package-lock.json +package.json \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..b39f0bf --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# 🤖 MeshCore Bot + +This script is a command bot that connects to a MeshCore device and responds to commands received in private channels. + +## Installation + +1. **Node.js**: Make sure you have Node.js installed. You can download it from [https://nodejs.org/](https://nodejs.org/). +2. **Dependencies**: Open a terminal in the directory of the `meshcore-bot.js` script and run: + + ```bash + npm install @liamcottle/meshcore.js + ``` + +## Usage + +To run the bot use the following command: + +```bash +node meshcore-bot.js [serial_port] +``` + +- `[serial_port]` is optional. If not provided, the script will default to `/dev/cu.usbmodem1101`. + +### Example + +```bash +node meshcore-bot.js /dev/tty.usbmodem12345 +``` + +### Commands + +- `!ping`: The bot will respond with "PONG! 🏓". +- `!date`: The bot will respond with the current date and time in ISO format. diff --git a/meshcore-bot.js b/meshcore-bot.js new file mode 100644 index 0000000..604fe2f --- /dev/null +++ b/meshcore-bot.js @@ -0,0 +1,80 @@ +import { Constants, NodeJSSerialConnection } from "@liamcottle/meshcore.js"; + +// get port from cli arguments +const port = process.argv[2] || "/dev/cu.usbmodem1101"; +console.log(`Connecting to ${port}`); + +// create connection +const connection = new NodeJSSerialConnection(port); + +let reconnectInterval; + +// wait until connected +connection.on("connected", async () => { + + // we are now connected + console.log("Connected"); + + // clear reconnect interval if it exists + if (reconnectInterval) { + clearInterval(reconnectInterval); + reconnectInterval = null; + } + + // update clock on meshcore device + await connection.syncDeviceTime(); + +}); + +// listen for new messages +connection.on(Constants.PushCodes.MsgWaiting, async () => { + try { + const waitingMessages = await connection.getWaitingMessages(); + for(const message of waitingMessages){ + if(message.contactMessage){ + await onContactMessageReceived(message.contactMessage); + } else if(message.channelMessage) { + await onChannelMessageReceived(message.channelMessage); + } + } + } catch(e) { + console.log(e); + } +}); + +async function onContactMessageReceived(message) { + console.log("Received contact message", message); +} + +async function onChannelMessageReceived(message) { + console.log(`Received channel message`, message); + // handle commands only in own channels, not in public channel with id 0 + if(message.channelIdx > 0){ + if(message.text.includes("!ping")){ + await connection.sendChannelTextMessage(message.channelIdx, "PONG! 🏓"); + return; + } + if(message.text.includes("!date")){ + await connection.sendChannelTextMessage(message.channelIdx, (new Date()).toISOString()); + return; + } + } +} + +// auto reconnect on disconnect +connection.on("disconnected", () => { + console.log("Disconnected, trying to reconnect..."); + if (reconnectInterval) { + clearInterval(reconnectInterval); + } + reconnectInterval = setInterval(async () => { + try { + await connection.connect(); + } catch (e) { + // ignore, we will retry + } + }, 3000); +}); + +// connect to meshcore device +await connection.connect();