In this tutorial we will setup a python bot for our matrix chat server. We will only do a couple of basic commands, so that you have a solid base to build from.
Matrix Server
In our previous post we’ve setup a matrix and element server, so if you are following along, head over to that post to setup your matrix server before continuing.
Matrix Python Bot
We will be using simple-matrix-bot-lib as our bot, so first we need to install it:
1
2
python3 -m pip install simplematrixbotlib
python3 -m pip install requests
We will need to authenticate with a user, so I will create a dedicated bot user:
1
2
3
4
5
6
7
8
9
$ docker exec -it matrix_synapse_1 bash
> register_new_matrix_user -c /data/homeserver.yaml http://localhost:8008
New user localpart [ root] : bot
Password:
Confirm password:
Make admin [ no] : no
Sending registration request...
Success!
The most basic bot is the echo bot, which just returns your message:
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
import subprocess
import simplematrixbotlib as botlib
from urllib.request import ssl , socket
import datetime , smtplib
MATRIX_URL = "https://matrix.foodmain.co.za"
MATRIX_USER = "@foobot:matrix.foodmain.co.za"
MATRIX_PASS = "foo"
creds = botlib . Creds ( MATRIX_URL , MATRIX_USER , MATRIX_PASS )
bot = botlib . Bot ( creds )
PREFIX = '!'
# Help
@bot.listener.on_message_event
async def help ( room , message ):
match = botlib . MessageMatch ( room , message , bot , PREFIX )
if match . is_not_from_this_bot () and match . prefix () and match . command ( "help" ):
help_message = """
Help:
- !help
Echo
- !echo your message
"""
await bot . api . send_markdown_message ( room . room_id , help_message )
# Echo
@bot.listener.on_message_event
async def echo ( room , message ):
"""
Example function that "echoes" arguements.
Usage:
user: !echo say something
bot: say something
"""
match = botlib . MessageMatch ( room , message , bot , PREFIX )
if match . is_not_from_this_bot () and match . prefix () and match . command ( "echo" ):
print ( "Room: {r}, User: {u}, Message: {m}" . format ( r = room . room_id , u = str ( message ) . split ( ':' )[ 0 ], m = str ( message ) . split ( ':' )[ - 1 ] . strip ()))
await bot . api . send_text_message ( room . room_id , " " . join ( arg for arg in match . args ()))
bot . run ()
Run the bot, invite the bot user to a room and test it with !echo hi
For a bot having to use the requests library, such as getting a quote from an api, we can use the following:
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
import random
import subprocess
import simplematrixbotlib as botlib
import requests
from urllib.request import ssl , socket
import datetime , smtplib
MATRIX_URL = "https://matrix.foodmain.co.za"
MATRIX_USER = "@foobot:matrix.foodmain.co.za"
MATRIX_PASS = "foo"
creds = botlib . Creds ( MATRIX_URL , MATRIX_USER , MATRIX_PASS )
bot = botlib . Bot ( creds )
PREFIX = '!'
# Help
@bot.listener.on_message_event
async def help ( room , message ):
match = botlib . MessageMatch ( room , message , bot , PREFIX )
if match . is_not_from_this_bot () and match . prefix () and match . command ( "help" ):
help_message = """
Help:
- !help
Echo
- !echo msg
Fortune:
- !fortune
Quote:
- !quote
"""
await bot . api . send_markdown_message ( room . room_id , help_message )
# Echo
@bot.listener.on_message_event
async def echo ( room , message ):
"""
Example function that "echoes" arguements.
Usage:
user: !echo say something
bot: say something
"""
match = botlib . MessageMatch ( room , message , bot , PREFIX )
if match . is_not_from_this_bot () and match . prefix () and match . command ( "echo" ):
print ( "Room: {r}, User: {u}, Message: {m}" . format ( r = room . room_id , u = str ( message ) . split ( ':' )[ 0 ], m = str ( message ) . split ( ':' )[ - 1 ] . strip ()))
await bot . api . send_text_message ( room . room_id , " " . join ( arg for arg in match . args ()))
# Fortune
@bot.listener.on_message_event
async def fortune ( room , message ):
match = botlib . MessageMatch ( room , message , bot )
if match . is_not_from_this_bot and match . command ( '!fortune' ):
fortune = subprocess . run ([ '/usr/games/fortune' ], capture_output = True ) . stdout . decode ( 'UTF-8' )
print ( fortune )
await bot . api . send_text_message ( room . room_id , fortune )
# Quotes
@bot.listener.on_message_event
async def quote ( room , message ):
match = botlib . MessageMatch ( room , message , bot , PREFIX )
if match . is_not_from_this_bot () and match . prefix () and (
match . command ( "quote" ) or match . command ( "q" )):
response = requests . get ( 'https://goquotes-api.herokuapp.com/api/v1/random?count=1' ) . json ()[ 'quotes' ][ 0 ]
quote = response [ 'text' ]
author = response [ 'author' ]
tag = response [ 'tag' ]
formatted_message = f """{quote}
- {author}
"""
#await bot.api.send_text_message(room.room_id, formatted_message)
await bot . api . send_markdown_message ( room . room_id , formatted_message )
bot . run ()
Resources
For more information, have a look at their documentation
Thank You
Thanks for reading, if you like my content, check out my website , read my newsletter or follow me at @ruanbekker on Twitter.