Compare commits

..

No commits in common. "9d4cd8c5744f9ff7ebdb64cc3b4639e096f39672" and "64152fe7d8c57ac140b31e61d599a22ac0eadd8d" have entirely different histories.

4 changed files with 25 additions and 62 deletions

View file

@ -1,11 +1,7 @@
> **Migrated to [code.randogoth.com/randogoth/lxmf-bot](https://code.randogoth.com/randogoth/lxmf-bot)**
# LXMFBot
Python class to easily develop a simple Telethon style chatbot for the LXMF protocol.
![screenshot](screenshot.png)
## Installation
```
@ -14,13 +10,12 @@ $ pip install -r requirements.txt
## Usage
- Instantiate the class with a `name` for the bot as parameter.
- Two additional options the class takes as parameters are `announce` to define the announce interval in seconds (defaults to `360`) and an `announce_immediately` boolean to define whether the bot should announce itself immediately after instantiation or not (defaults to `False`)
- Instantiate the class with a name for the bot as parameter
- Use the `received` decorator to define functions for parsing received messages
- Use the `<instance>.send(recipient_hash, message)` or `msg.reply(message)` methods to send messages
- Launch the bot using the `run` method
### Message Object
## Message Object
Functions decorated by `received` have access to a `msg` parameter that has the following content:
@ -29,12 +24,10 @@ Functions decorated by `received` have access to a `msg` parameter that has the
- `msg.reply` : function that takes a string parameter and sends it as reply to the sender
- `msg.lxmf` : the complete `LXMessage` object for more complex parsing
### Example
Example of a bot that echos a message back to the sender:
```Python
from lxmfbot import LXMFBot
from bot import LXMFBot
bot = LXMFBot("NodeBot")
@ -43,14 +36,4 @@ def echo_msg(msg):
msg.reply(msg.content)
bot.run()
```
### Identity & Announce Files
The bots' identity and announce file location
| OS | Path |
|:-- |:--- |
| Linux: | `~/.local/share/LXMFBot/<botname>` |
| MacOS: | `~/Library/Application Support/LXMFBot/<botname>` |
| Windows: | `C:\Users\<username>\AppData\Local\LXMFBot\<botname>` |
```

View file

@ -1,6 +1,6 @@
from lxmfbot import LXMFBot
bot = LXMFBot("testbot")
bot = LXMFBot("NodeBot")
@bot.received
def echo_msg(msg):

View file

@ -11,33 +11,21 @@ from types import SimpleNamespace
class LXMFBot:
delivery_callbacks = []
receipts = []
queue = Queue(maxsize = 5)
announce_time = 360
def __init__(self, name='LXMFBot', announce=360, announce_immediately=False):
def __init__(self, name='LXMFBot'):
# initialize identiy
self.name = name
self.announce_time = announce
dirs = AppDirs("LXMFBot", "randogoth")
self.config_path = os.path.join(dirs.user_data_dir, name)
idfile = os.path.join(self.config_path, "identity")
if not os.path.isdir(dirs.user_data_dir):
os.mkdir(dirs.user_data_dir)
if not os.path.isdir(self.config_path):
os.mkdir(self.config_path)
if not os.path.isfile(idfile):
idpath = os.path.join(dirs.user_data_dir, "identity")
self.announce_path = os.path.join(dirs.user_data_dir, "announce")
if not os.path.isfile(idpath):
RNS.log('No Primary Identity file found, creating new...', RNS.LOG_INFO)
id = RNS.Identity(True)
id.to_file(idfile)
self.id = RNS.Identity.from_file(idfile)
id = RNS.Identity()
id.to_file(idpath)
self.id = RNS.Identity.from_file(idpath)
RNS.log('Loaded identity from file', RNS.LOG_INFO)
if announce_immediately:
af = os.path.join(self.config_path, "announce")
if os.path.isfile(af):
os.remove(af)
RNS.log('Announcing now. Timer reset.', RNS.LOG_INFO)
# start RNS and LXMFRouter
RNS.Reticulum(loglevel=RNS.LOG_VERBOSE)
@ -48,9 +36,8 @@ class LXMFBot:
self._announce()
def _announce(self):
announce_path = os.path.join(self.config_path, "announce")
if os.path.isfile(announce_path):
with open(announce_path, "r") as f:
if os.path.isfile(self.announce_path):
with open(self.announce_path, "r") as f:
announce = int(f.readline())
else:
RNS.log('failed to open announcepath', RNS.LOG_DEBUG)
@ -58,8 +45,8 @@ class LXMFBot:
if announce > int(time.time()):
RNS.log('Recent announcement', RNS.LOG_DEBUG)
else:
with open(announce_path, "w+") as af:
next_announce = int(time.time()) + self.announce_time
with open(self.announce_path, "w") as af:
next_announce = int(time.time()) + 1800
af.write(str(next_announce))
self.local.announce()
RNS.log('Announcement sent, expr set 1800 seconds', RNS.LOG_INFO)
@ -70,24 +57,17 @@ class LXMFBot:
def _message_received(self, message):
sender = RNS.hexrep(message.source_hash, delimit=False)
receipt = RNS.hexrep(message.hash, delimit=False)
RNS.log(f'Message receipt <{receipt}>', RNS.LOG_INFO)
def reply(msg):
self.send(sender, msg)
if receipt not in self.receipts:
self.receipts.append(receipt)
if len(self.receipts) > 100:
self.receipts.pop(0)
for callback in self.delivery_callbacks:
obj = {
'lxmf' : message,
'reply' : reply,
'sender' : sender,
'content' : message.content.decode('utf-8'),
'hash' : receipt
}
msg = SimpleNamespace(**obj)
callback(msg)
for callback in self.delivery_callbacks:
obj = {
'lxmf' : message,
'reply' : reply,
'sender' : sender,
'content' : message.content.decode('utf-8')
}
msg = SimpleNamespace(**obj)
callback(msg)
def send(self, destination, message, title='Reply'):
try:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB