tb0hdan / meshtastic-telegram-gateway

A Telegram bot that forwards messages to and from Meshtastic devices.
Apache License 2.0
73 stars 11 forks source link

meshtastic-telegram-gateway

Build CodeQL Python versions

Read this in other languages: English, Polski, Português

Telegram bot that forwards messages to and from Meshtastic device

The purpose of this bot is to act as a bridge between local Meshtastic conference and Telegram chat room. Nicks (Your Name field for Meshtastic) are passed through in both directions.

Supported Hardware

See official Meshtastic Python list

Online stores for HW purchase

Aliexpress NEO-6M

Aliexpress NEO-8M (better)

Amazon

Banggood

Ebay

Tindie

TomTop

Meshtastic T-Beam v1.1

Typical use case

Meshtastic diagram

Interconnecting cities

Using MQTT (recommended)

Meshtastic cross MQTT diagram

Using multiple telegram bots

Meshtastic cross diagram

Proposed hybrid architecture, used by community in Ukraine

Meshtastic Ukraine hybrid architecture

Legend:

Supported software

Python 3.8+ is required.

Webapp

When enabled, this bot listens on specified port and renders device map.

  1. Cluster markerer

Cluster Markerer

  1. Device details

Device Details

  1. Actual Kyiv community map

Kyiv map

  1. Tail duration

Default value is 3600 seconds. Can be changed using ?tail=xxx query string, e.g.

https://mesh.0x21h.net/?tail=7200

Setup

  1. Run cat mesh.ini.example|egrep -v '^#' > mesh.ini
  2. Create new Telegram bot using @BotFather contact. Copy token to clipboard.
  3. Put token from previous step into mesh.ini
  4. Put admin id and room id into mesh.ini
  5. Edit mesh.ini Meshtastic section to reflect your device configuration (usually not required, for Linux at least)
  6. Run sudo pip3 install -r requirements.txt
  7. Run gpasswd -a youruser dialout
  8. Relogin
  9. Run /start.sh
  10. Enjoy

Supported bot commands

Telegram only

  1. /start - basic command to confirm that bot is up and running
  2. /nodes - return list of known nodes (including those reachable via other hops)
  3. /qr - return active QR code for configuring new Meshtastic devices
  4. /map - return link to map

Meshtastic only

  1. /distance - print distance to other Meshtastic devices (in meters) Sample answer:
UR5YBM-aa60: 19m
UT3ULJ: 2,316m
  1. /ping - ping currently connected Meshtastic node and get response. Sample answer:
Pong from UR5YBM-aa60 at 10.00 SNR time=9.632s
  1. /stats - get some stats for current node Sample anwser:
Locations: 1234. Messages: 20

Common

/reboot - request Meshtastic device reboot. Requires respective admin privileges.

/uptime - returns bot version/uptime

Console only

$ ./mesh.py --help

usage: mesh.py [-h] {post2mesh,run,command} ...

optional arguments:
  -h, --help            show this help message and exit

commands:
  {post2mesh,run,command}
                        commands
    post2mesh           site command
    run                 run
    command             Send command

Sending messages to Meshtastic device:

$ ./mesh.py post2mesh -m "test"

Sending commands to Meshtastic device:

$ ./mesh.py command -c reboot

Advanced topics

MQTT-only bot

This bot has experimental support for MQTT-only mode. If you want to use the bot without Meshtastic hardware, you need to edit mqtt.ini file and enable MQTT section in mesh.ini file.

This requires setting [Meshtastic] section device to mqtt.

APRS

This bot provides bi-directional text messaging with APRS nodes using APRS-IS. Meshtastic nodes with valid amateur call signs will be announced to APRS network. See

[APRS] configuration section.

Custom plugins

  1. Store your plugin in external/plugins, along with an empty __init__.py
  2. Note that ExternalBase parent class is for dynamic plugin loading. No Handler methods will be called, but you will have access to bot connections.
  3. Sample
import asyncio

class Handler:
  def __init__(self, database, config, meshtastic_connection, telegram_connection, logger):
    self.database = database
    self.config = config
    self.meshtastic_connection = meshtastic_connection
    self.telegram_connection = telegram_connection
    self.logger = logger

  async def main(self):
    self.logger.info('Server started...')
    while True:
      try:
        await asyncio.sleep(1)
      except Exception as exc:
        pass

class FooBar(ExternalBase):
    def __init__(self, database, config, meshtastic_connection, telegram_connection, logger):
        # Init handler
        self.handler = Handler(database, config, meshtastic_connection, telegram_connection, logger)

    def run(self):
        asyncio.run(self.handler.main())