-
-
Notifications
You must be signed in to change notification settings - Fork 81
Expand file tree
/
Copy pathechobot.py
More file actions
95 lines (75 loc) · 3.48 KB
/
echobot.py
File metadata and controls
95 lines (75 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#!/usr/bin/env python3
# Copyright (c) 2022 Marc Ordinas i Llopis
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# A simple Matrix echo bot to show the usage of mautrix-python.
#
# To use it, you'll need an access token and a device ID.
# If you don't have those, first create a user (for example, 'echobot') in your homeserver. Then,
# log it in with
# curl -XPOST -d '{"type":"m.login.password", "user":"echobot", "password":"echobot"}' \
# http://localhost:8008/_matrix/client/v3/login
# This will return the device ID and token necessaries. Fill in the Echobot static vars and run.
#
# Once connected, invite the bot to a room and send a message starting with "!echo". You should get
# a notice from the bot.
import asyncio
from mautrix.client import Client
from mautrix.types import EventType, MessageEvent, StrippedStateEvent, Membership, \
TextMessageEventContent, MessageType, Format
class EchoBot:
# Change to the correct user and homeserver.
user_id = "@echobot:localhost"
base_url = "http://localhost:8008"
# Fill in with the login result.
token = "<token>"
device_id = "<device ID>"
def __init__(self):
# Create the client to access Matrix.
self.client = Client(mxid=EchoBot.user_id,
device_id=EchoBot.device_id,
base_url=EchoBot.base_url,
token=EchoBot.token)
# As we aren't passing any :class:SyncStore or :class:StateStore, just ignore anything sent
# before we connect.
self.client.ignore_initial_sync = True
self.client.ignore_first_sync = True
# Register two handlers, one for room memberships (invites) and another for room messages.
self.client.add_event_handler(EventType.ROOM_MEMBER, self.handle_invite)
self.client.add_event_handler(EventType.ROOM_MESSAGE, self.handle_message)
async def handle_invite(self, event: StrippedStateEvent) -> None:
# Ignore the message if it's not an invitation for us.
if event.state_key == self.user_id and event.content.membership == Membership.INVITE:
# If it is, join the room.
await self.client.join_room(event.room_id)
async def handle_message(self, event: MessageEvent) -> None:
if event.sender == self.user_id:
# Ignore our own messages
return
if event.content.relates_to:
# Don't echo replies to other messages
return
body = event.content.body
if body.startswith("!echo"):
response = TextMessageEventContent(
msgtype=MessageType.NOTICE,
body=body[5:].strip()
)
# If there's HTML-formatted content, echo that too
if event.content.format == Format.HTML:
response.format = Format.HTML
response.formatted_body = event.content.formatted_body[5:].strip()
# Send back the notice
await self.client.send_message(event.room_id, response)
async def start(self):
print("Starting EchoBot")
whoami = await self.client.whoami()
print(f"\tConnected, I'm {whoami.user_id} using {whoami.device_id}")
await self.client.start(None)
async def main():
bot = EchoBot()
await bot.start()
if __name__ == '__main__':
asyncio.run(main())