Update snek core bot.
This commit is contained in:
parent
7c688c1c9b
commit
a91d4e72ec
20
README.md
20
README.md
@ -43,22 +43,18 @@ class ExampleBot(Bot):
|
|||||||
print(f"I joined!")
|
print(f"I joined!")
|
||||||
await self.send_message(
|
await self.send_message(
|
||||||
channel_uid,
|
channel_uid,
|
||||||
f"Hello, i'm actively part of the conversation in channel {channel_uid} now, you don't have to mention me anymore. "
|
f"Hello, i'm actively part of the conversation in channel {channel_uid} now, you don't have to mention me anymore. ",
|
||||||
)
|
)
|
||||||
|
|
||||||
async def on_leave(self, channel_uid):
|
async def on_leave(self, channel_uid):
|
||||||
print(f"I left!!")
|
print(f"I left!!")
|
||||||
await self.send_message(
|
await self.send_message(
|
||||||
channel_uid,
|
channel_uid, "I stop actively being part of the conversation now. Bye!"
|
||||||
"I stop actively being part of the conversation now. Bye!"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async def on_ping(self,username, user_nick, channel_uid, message):
|
async def on_ping(self, username, user_nick, channel_uid, message):
|
||||||
print(f"Ping from {user_nick} in channel {channel_uid}: {message}")
|
print(f"Ping from {user_nick} in channel {channel_uid}: {message}")
|
||||||
await self.send_message(
|
await self.send_message(channel_uid, "pong " + message)
|
||||||
channel_uid,
|
|
||||||
"pong " + message
|
|
||||||
)
|
|
||||||
|
|
||||||
async def on_own_message(self, data):
|
async def on_own_message(self, data):
|
||||||
print(f"Received my own message: {data.message}")
|
print(f"Received my own message: {data.message}")
|
||||||
@ -80,7 +76,9 @@ class ExampleBot(Bot):
|
|||||||
)
|
)
|
||||||
await self.send_message(channel_uid, result)
|
await self.send_message(channel_uid, result)
|
||||||
else:
|
else:
|
||||||
await self.send_message(channel_uid, f'Hey {user_nick}, Thanks for mentioning me "{message}".')
|
await self.send_message(
|
||||||
|
channel_uid, f'Hey {user_nick}, Thanks for mentioning me "{message}".'
|
||||||
|
)
|
||||||
|
|
||||||
async def on_message(self, sender_username, sender_nick, channel_uid, message):
|
async def on_message(self, sender_username, sender_nick, channel_uid, message):
|
||||||
print(f"Message from {sender_nick}: {message}")
|
print(f"Message from {sender_nick}: {message}")
|
||||||
@ -98,7 +96,9 @@ class ExampleBot(Bot):
|
|||||||
await self.send_message(channel_uid, result)
|
await self.send_message(channel_uid, result)
|
||||||
|
|
||||||
|
|
||||||
bot = ExampleBot(url="ws://snek.molodetz.nl/rpc.ws", username="example", password="example")
|
bot = ExampleBot(
|
||||||
|
url="ws://snek.molodetz.nl/rpc.ws", username="example", password="example"
|
||||||
|
)
|
||||||
asyncio.run(bot.run())
|
asyncio.run(bot.run())
|
||||||
```
|
```
|
||||||
|
|
||||||
|
20
example.py
20
example.py
@ -12,22 +12,18 @@ class ExampleBot(Bot):
|
|||||||
print(f"I joined!")
|
print(f"I joined!")
|
||||||
await self.send_message(
|
await self.send_message(
|
||||||
channel_uid,
|
channel_uid,
|
||||||
f"Hello, i'm actively part of the conversation in channel {channel_uid} now, you don't have to mention me anymore. "
|
f"Hello, i'm actively part of the conversation in channel {channel_uid} now, you don't have to mention me anymore. ",
|
||||||
)
|
)
|
||||||
|
|
||||||
async def on_leave(self, channel_uid):
|
async def on_leave(self, channel_uid):
|
||||||
print(f"I left!!")
|
print(f"I left!!")
|
||||||
await self.send_message(
|
await self.send_message(
|
||||||
channel_uid,
|
channel_uid, "I stop actively being part of the conversation now. Bye!"
|
||||||
"I stop actively being part of the conversation now. Bye!"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async def on_ping(self,username, user_nick, channel_uid, message):
|
async def on_ping(self, username, user_nick, channel_uid, message):
|
||||||
print(f"Ping from {user_nick} in channel {channel_uid}: {message}")
|
print(f"Ping from {user_nick} in channel {channel_uid}: {message}")
|
||||||
await self.send_message(
|
await self.send_message(channel_uid, "pong " + message)
|
||||||
channel_uid,
|
|
||||||
"pong " + message
|
|
||||||
)
|
|
||||||
|
|
||||||
async def on_own_message(self, data):
|
async def on_own_message(self, data):
|
||||||
print(f"Received my own message: {data.message}")
|
print(f"Received my own message: {data.message}")
|
||||||
@ -49,7 +45,9 @@ class ExampleBot(Bot):
|
|||||||
)
|
)
|
||||||
await self.send_message(channel_uid, result)
|
await self.send_message(channel_uid, result)
|
||||||
else:
|
else:
|
||||||
await self.send_message(channel_uid, f'Hey {user_nick}, Thanks for mentioning me "{message}".')
|
await self.send_message(
|
||||||
|
channel_uid, f'Hey {user_nick}, Thanks for mentioning me "{message}".'
|
||||||
|
)
|
||||||
|
|
||||||
async def on_message(self, sender_username, sender_nick, channel_uid, message):
|
async def on_message(self, sender_username, sender_nick, channel_uid, message):
|
||||||
print(f"Message from {sender_nick}: {message}")
|
print(f"Message from {sender_nick}: {message}")
|
||||||
@ -67,5 +65,7 @@ class ExampleBot(Bot):
|
|||||||
await self.send_message(channel_uid, result)
|
await self.send_message(channel_uid, result)
|
||||||
|
|
||||||
|
|
||||||
bot = ExampleBot(url="ws://snek.molodetz.nl/rpc.ws", username="example", password="xxxxxx")
|
bot = ExampleBot(
|
||||||
|
url="ws://snek.molodetz.nl/rpc.ws", username="example", password="xxxxxx"
|
||||||
|
)
|
||||||
asyncio.run(bot.run())
|
asyncio.run(bot.run())
|
||||||
|
@ -12,15 +12,16 @@
|
|||||||
# MIT License
|
# MIT License
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import logging
|
||||||
|
import traceback
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
from snekbot.rpc import RPC
|
from snekbot.rpc import RPC
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
logger = logging.getLogger("snekbot")
|
logger = logging.getLogger("snekbot")
|
||||||
|
|
||||||
|
|
||||||
class Bot:
|
class Bot:
|
||||||
|
|
||||||
def __init__(self, username, password, url="wss://snek.molodetz.nl/rpc.ws"):
|
def __init__(self, username, password, url="wss://snek.molodetz.nl/rpc.ws"):
|
||||||
@ -33,21 +34,42 @@ class Bot:
|
|||||||
self.ws = None
|
self.ws = None
|
||||||
self.joined = set()
|
self.joined = set()
|
||||||
|
|
||||||
|
async def on_join(self, channel_uid):
|
||||||
|
self.joined.add(channel_uid)
|
||||||
|
logger.debug("Joined channel: " + channel_uid)
|
||||||
|
|
||||||
|
async def on_leave(self, channel_uid):
|
||||||
|
self.joined.remove(channel_uid)
|
||||||
|
logger.debug("Left channel: " + channel_uid)
|
||||||
|
|
||||||
|
async def on_mention(self, username, user_nick, channel_uid, message):
|
||||||
|
logger.debug("Received mention from " + username + ": " + message)
|
||||||
|
|
||||||
|
async def on_idle(self):
|
||||||
|
logger.debug("Bot is idle.")
|
||||||
|
|
||||||
|
async def on_ping(self, username, user_nick, channel_uid, message):
|
||||||
|
logger.debug("Received ping from " + username + ": " + message)
|
||||||
|
|
||||||
|
async def on_own_message(self, channel_uid, message):
|
||||||
|
logger.debug("Received own message: " + message)
|
||||||
|
|
||||||
|
async def on_message(self, username, user_nick, channel_uid, message):
|
||||||
|
logger.debug("Received message from " + username + ": " + message)
|
||||||
|
|
||||||
async def run(self, reconnect=True):
|
async def run(self, reconnect=True):
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await self.run_once()
|
await self.run_once()
|
||||||
except Exception as ex:
|
except:
|
||||||
print(ex)
|
traceback.print_exc()
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
if not reconnect:
|
if not reconnect:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def has_joined(self, channel_uid):
|
def has_joined(self, channel_uid):
|
||||||
return channel_uid in self.joined
|
return channel_uid in self.joined
|
||||||
|
|
||||||
@ -55,25 +77,23 @@ class Bot:
|
|||||||
await self.rpc.send_message(channel_uid, message)
|
await self.rpc.send_message(channel_uid, message)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
async def get_channels(self):
|
||||||
|
return await (await self.rpc.get_channels())()
|
||||||
|
|
||||||
async def run_once(self):
|
async def run_once(self):
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.ws_connect(self.url) as ws:
|
async with session.ws_connect(self.url) as ws:
|
||||||
self.ws = ws
|
self.ws = ws
|
||||||
self.rpc = RPC(ws)
|
rpc = RPC(self.ws)
|
||||||
rpc = self.rpc
|
self.rpc = rpc
|
||||||
success = await (await rpc.login(self.username, self.password))()
|
await (await rpc.login(self.username, self.password))()
|
||||||
print(success)
|
self.channels = await self.get_channels()
|
||||||
self.channels = await (await rpc.get_channels())()
|
|
||||||
for channel in self.channels:
|
for channel in self.channels:
|
||||||
logger.debug("Found channel: " + channel["name"])
|
logger.debug("Found channel: " + channel["name"])
|
||||||
self.user = (await (await rpc.get_user(None))())
|
self.user = await (await rpc.get_user(None))()
|
||||||
logger.debug("Logged in as: " + self.user["username"])
|
logger.debug("Logged in as: " + self.user["username"])
|
||||||
while True:
|
while True:
|
||||||
try:
|
|
||||||
try:
|
|
||||||
await self.on_idle()
|
await self.on_idle()
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
data = await rpc.receive()
|
data = await rpc.receive()
|
||||||
|
|
||||||
@ -85,27 +105,43 @@ class Bot:
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if data.username == self.user['username']:
|
if data.username == self.user["username"]:
|
||||||
await self.on_own_message(data.channel_uid, message)
|
await self.on_own_message(data.channel_uid, message)
|
||||||
elif message.startswith("ping"):
|
elif message.startswith("ping"):
|
||||||
await self.on_ping(data.username, data.user_nick, data.channel_uid, data.message.lstrip("ping ").strip())
|
await self.on_ping(
|
||||||
elif any([
|
data.username,
|
||||||
"@" + self.user['nick'] + " join" in data.message,
|
data.user_nick,
|
||||||
"@" + self.user['username'] + " join" in data.message]):
|
data.channel_uid,
|
||||||
self.joined.add(data.channel_uid)
|
data.message.lstrip("ping ").strip(),
|
||||||
|
)
|
||||||
|
elif any(
|
||||||
|
[
|
||||||
|
"@" + self.user["nick"] + " join" in data.message,
|
||||||
|
"@" + self.user["username"] + " join" in data.message,
|
||||||
|
]
|
||||||
|
):
|
||||||
await self.on_join(data.channel_uid)
|
await self.on_join(data.channel_uid)
|
||||||
elif any([
|
elif any(
|
||||||
"@" + self.user['nick'] + " leave" in data.message,
|
[
|
||||||
"@" + self.user['username'] + " leave" in data.message]):
|
"@" + self.user["nick"] + " leave" in data.message,
|
||||||
self.joined.remove(data.channel_uid)
|
"@" + self.user["username"] + " leave" in data.message,
|
||||||
|
]
|
||||||
|
):
|
||||||
await self.on_leave(data.channel_uid)
|
await self.on_leave(data.channel_uid)
|
||||||
elif "@" + self.user['nick'] in data.message or "@" + self.user['username'] in data.message:
|
elif (
|
||||||
await self.on_mention(data.username, data.user_nick, data.channel_uid, data.message)
|
"@" + self.user["nick"] in data.message
|
||||||
|
or "@" + self.user["username"] in data.message
|
||||||
|
):
|
||||||
|
await self.on_mention(
|
||||||
|
data.username,
|
||||||
|
data.user_nick,
|
||||||
|
data.channel_uid,
|
||||||
|
data.message,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
await self.on_message(data.username, data.user_nick, data.channel_uid, data.message)
|
await self.on_message(
|
||||||
except AttributeError as ex:
|
data.username,
|
||||||
logger.exception(ex)
|
data.user_nick,
|
||||||
raise
|
data.channel_uid,
|
||||||
except Exception as ex:
|
data.message,
|
||||||
raise ex
|
)
|
||||||
|
|
||||||
|
@ -9,15 +9,16 @@
|
|||||||
|
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import subprocess
|
import logging
|
||||||
import pathlib
|
import pathlib
|
||||||
import aiohttp
|
import subprocess
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
import logging
|
import aiohttp
|
||||||
|
|
||||||
logger = logging.getLogger("snekbot.rpc")
|
logger = logging.getLogger("snekbot.rpc")
|
||||||
|
|
||||||
|
|
||||||
class RPC:
|
class RPC:
|
||||||
class Response:
|
class Response:
|
||||||
def __init__(self, msg):
|
def __init__(self, msg):
|
||||||
@ -38,13 +39,13 @@ class RPC:
|
|||||||
return self.__dict__[name]
|
return self.__dict__[name]
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return self.__dict__.get('data',{})[name]
|
return self.__dict__.get("data", {})[name]
|
||||||
|
|
||||||
def __setitem__(self, name, value):
|
def __setitem__(self, name, value):
|
||||||
if not name in self.__dict__.get('data',{}):
|
if name not in self.__dict__.get("data", {}):
|
||||||
self.__dict__[name] = value
|
self.__dict__[name] = value
|
||||||
else:
|
else:
|
||||||
self.__dict__['data'][name] = value
|
self.__dict__["data"][name] = value
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return json.dumps(self.__dict__, default=str, indent=2)
|
return json.dumps(self.__dict__, default=str, indent=2)
|
||||||
@ -55,12 +56,17 @@ class RPC:
|
|||||||
|
|
||||||
async def echo(self, data):
|
async def echo(self, data):
|
||||||
logger.debug("Schedule for retry: " + str(data))
|
logger.debug("Schedule for retry: " + str(data))
|
||||||
await self.ws.send_json(dict(method="echo",args=[data]))
|
await self.ws.send_json({"method": "echo", "args": [data]})
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
async def method(*args, **kwargs):
|
async def method(*args, **kwargs):
|
||||||
self.current_call_id = str(uuid.uuid4())
|
self.current_call_id = str(uuid.uuid4())
|
||||||
payload = dict(method=name, args=args, kwargs=kwargs, callId=self.current_call_id)
|
payload = {
|
||||||
|
"method": name,
|
||||||
|
"args": args,
|
||||||
|
"kwargs": kwargs,
|
||||||
|
"callId": self.current_call_id,
|
||||||
|
}
|
||||||
await self.ws.send_json(payload)
|
await self.ws.send_json(payload)
|
||||||
|
|
||||||
async def returner():
|
async def returner():
|
||||||
@ -71,7 +77,9 @@ class RPC:
|
|||||||
await self.echo(data)
|
await self.echo(data)
|
||||||
continue
|
continue
|
||||||
return self.Response(data)
|
return self.Response(data)
|
||||||
|
|
||||||
return returner
|
return returner
|
||||||
|
|
||||||
return method
|
return method
|
||||||
|
|
||||||
async def system(self, command):
|
async def system(self, command):
|
||||||
@ -114,7 +122,10 @@ class RPC:
|
|||||||
break
|
break
|
||||||
elif msg.type == aiohttp.WSMsgType.TEXT:
|
elif msg.type == aiohttp.WSMsgType.TEXT:
|
||||||
|
|
||||||
if self.current_call_id and not msg.json().get('callId') != self.current_call_id:
|
if (
|
||||||
|
self.current_call_id
|
||||||
|
and not msg.json().get("callId") != self.current_call_id
|
||||||
|
):
|
||||||
await self.echo(msg.json())
|
await self.echo(msg.json())
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
|
Loading…
Reference in New Issue
Block a user