From a112ef195a5bb71f6861b4ba559bc36b8d139ecc Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 1 Jan 2023 12:03:47 +1300 Subject: [PATCH 01/10] Update documentation for version 2.0 --- Makefile | 5 ++- README.md | 12 ++---- config.lua | 31 +++++++++++++++ default_config.lua | 49 +++++++++++++++++++++++ matrix-send | 52 ------------------------ matrix-send-config.5 | 65 ++++++++++++++++++++++++++++++ matrix-send.1 | 94 +++++++++++++++++++++++++------------------- matrix-send.conf | 17 -------- matrix-send.conf.5 | 60 ---------------------------- 9 files changed, 204 insertions(+), 181 deletions(-) create mode 100644 config.lua create mode 100644 default_config.lua create mode 100644 matrix-send-config.5 delete mode 100644 matrix-send.conf delete mode 100644 matrix-send.conf.5 diff --git a/Makefile b/Makefile index cf63374..cd74faf 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,8 @@ PREFIX = /usr/local MANPREFIX = ${PREFIX}/man config: - cp matrix-send.conf ~/.config/matrix-send.conf + mkdir -p ~/.config/matrix-send + cp config.lua ~/.config/matrix-send/config.lua install: cp -f matrix-send ${DESTDIR}${PREFIX}/bin @@ -11,4 +12,4 @@ install: mkdir -p ${DESTDIR}${MANPREFIX}/man1 cp -f matrix-send.1 ${DESTDIR}${MANPREFIX}/man1 mkdir -p ${DESTDIR}${MANPREFIX}/man5 - cp -f matrix-send.conf.5 ${DESTDIR}${MANPREFIX}/man5 + cp -f matrix-send-config.5 ${DESTDIR}${MANPREFIX}/man5 diff --git a/README.md b/README.md index 3b5d4ec..a71f45c 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,16 @@ # matrix-send -A script that sends a message to a Matrix room. +A script that sends messages to Matrix rooms. [Read the manual page](https://jtbx.codeberg.page/man/matrix-send.1) --- -**Syntax:** `matrix-send message room` - -**Example:** `matrix-send "Hello world\!" \!aBcDeFgHiJkLmNoP:example.org` - ---- - matrix-send is a simple script that sends a message to a Matrix room. -It does this by sending a JSON message to your Matrix server. The message types that are supported are *m.text*, and *m.notice*. +It does this by sending a JSON message to your Matrix server. The message types that are supported are `m.text`, and `m.notice`. -It is mainly designed for automation. I use it on a private Matrix room of mine. +It is mainly designed for automation. There aren't any plans for matrix-send to support encryption. diff --git a/config.lua b/config.lua new file mode 100644 index 0000000..f271a49 --- /dev/null +++ b/config.lua @@ -0,0 +1,31 @@ +login = { + -- The Matrix server to use. + server = "matrix-client.matrix.org", -- matrix.org + + -- The user to log in to. + username = "user", + + -- The password for the user. + password = "password", + + -- The access token to use (instead of credentials). + -- If token equals nil, credentials are used. + -- If token is not nil, credentials are ignored. + token = nil + + -- The server value needs to be provided. + -- You can choose to login with user credentials or a + -- token. One of them needs to be provided. +} + +rooms = { + -- Room aliases. + -- Here you can add aliases for rooms, + -- instead of having to type the confusing + -- Room ID every single time you send a message. + -- Examples: + --my_alias = "!AbCdEfGhIjKl:burger.land", + --lounge = "!MnOpQrSTuVWxYz:gaming.bruvs" + -- When you want to send to a Matrix room, you + -- can just type the alias instead of the long Room ID. +} diff --git a/default_config.lua b/default_config.lua new file mode 100644 index 0000000..76cd492 --- /dev/null +++ b/default_config.lua @@ -0,0 +1,49 @@ +-- The configuration file for matrix-send is written in Lua format. +-- Here is a list of all possible options in the configuration file. +-- Default values appear after the '=' sign. + +login = { + -- The Matrix server to use. + server = nil, + + -- The user to log in to. + username = nil, + + -- The password for the user. + password = nil, + + -- The access token to use (instead of credentials). + -- If token equals nil, credentials are used. + -- If token is not nil, credentials are ignored. + token = nil + + -- The server value needs to be provided. + -- You can choose to login with user credentials or a + -- token. One of them needs to be provided. +} + +cache = { + -- The path to cache access tokens at. + location = "~/.cache/matrix-send", + + -- Disable caching access tokens? + disable = false +} + +rooms = { + -- Room aliases. + -- Here you can add aliases for rooms, + -- instead of having to type the confusing + -- Room ID every single time you send a message. + -- Examples: + --my_alias = "!AbCdEfGhIjKl:burger.land", + --lounge = "!MnOpQrSTuVWxYz:gaming.bruvs" + -- When you want to send to a Matrix room, you + -- can just type the alias instead of the long Room ID. +} + +advanced = { + -- The default event type. + -- Can be either m.text or m.notice. + event = "m.text" +} diff --git a/matrix-send b/matrix-send index 392e393..f042356 100755 --- a/matrix-send +++ b/matrix-send @@ -104,58 +104,6 @@ function confpanic(s) os.exit(1) end ---[[ - The configuration file for matrix-send is written in Lua format. - Here is a list of all possible options in the configuration file. - Default values appear after the '=' sign. - - login = { - -- The Matrix server to use. - server = nil, - - -- The user to log in to. - username = nil, - - -- The password for the user. - password = nil, - - -- The access token to use (instead of credentials). - -- If token equals nil, credentials are used. - -- If token is not nil, credentials are ignored. - token = nil - - -- The server value needs to be provided. - -- You can choose to login with user credentials or a - -- token. One of them needs to be provided. - } - - cache = { - -- The path to cache access tokens at. - location = "~/.cache/matrix-send", - - -- Disable caching access tokens? - disable = false - } - - rooms = { - -- Room aliases. - -- Here you can add aliases for rooms, - -- instead of having to type the confusing - -- Room ID every single time you send a message. - -- Examples: - --my_alias = "!AbCdEfGhIjKl:burger.land", - --lounge = "!MnOpQrSTuVWxYz:gaming.bruvs" - -- When you want to send to a Matrix room, you - -- can just type the alias instead of the long Room ID. - } - - advanced = { - -- The default event type. - -- Can be either m.text or m.notice. - event = "m.text" - } ---]] - -- Default configuration file default_config = [[ -- Default configuration file for matrix-send diff --git a/matrix-send-config.5 b/matrix-send-config.5 new file mode 100644 index 0000000..b2c468c --- /dev/null +++ b/matrix-send-config.5 @@ -0,0 +1,65 @@ +.Dd $Mdocdate: January 1 2023 $ +.Dt MATRIX-SEND-CONFIG 5 +.Os +.Sh NAME +.Nm config.lua +.Nd configuration file for +.Xr matrix-send 1 +.Sh DESCRIPTION +.Xr matrix-send 1 +sends messages to Matrix rooms. In order to send a message however, it needs +credentials for the account sending the message. These credentials are provided +in the +.Nm +configuration file, as well as other options if you need them. +.Pp +The configuration file is in Lua format, meaning +you can write whatever Lua code you wish inside. +.Pp +The following configuration options are available: +.Bl -tag -width 11n +.Bl -tag -width login.server +.It Ic login.server Ar server +The Client-Server API address of the Matrix server being used. +.It Ic login.username Ar username +The username of the account being used. +.It Ic login.password Ar password +The password for the account being used. +.It Ic login.token Ar token +Instead of authenticating via username and password to obtain an access token, use +.Ar token +as the access token. +.It Ic cache.location Ar location +Use +.Ar location +as the cache location. +.It Ic cache.disable +Don't cache anything. +.It Ic advanced.event Ar type +Modify the default event type from the default (m.text) to +.Ar type . +Supported types are m.text, and m.notice. +.El +.Sh FILES +.Bl -tag -width ~/.config/matrix-send/config.lua -compact +.It Pa ~/.config/matrix-send/config.lua +.Xr matrix-send 1 +configuration file +.It Pa ~/.cache/matrix-send +default cache directory +.El +.Sh EXAMPLES +The following example logs into the user 'john' of the server +matrix-client.matrix.org, and the password 'supersecretpassword', +and sets the default event type to m.notice. +.Bd -literal -offset indent +login = { + server = "matrix-client.matrix.org", + username = "john", + password = "supersecretpassword" +} + +advanced.event = "m.notice" +.Ed +.Sh SEE ALSO +.Xr matrix-send 1 diff --git a/matrix-send.1 b/matrix-send.1 index bd4bc75..9b57606 100644 --- a/matrix-send.1 +++ b/matrix-send.1 @@ -1,4 +1,4 @@ -.Dd $Mdocdate: August 4 2022 $ +.Dd $Mdocdate: January 1 2023 $ .Dt MATRIX-SEND 1 .Os .Sh NAME @@ -8,19 +8,24 @@ .Nm matrix-send .Bk -words .Op Fl t Ar type -.Op Fl C Ar config -.Op Fl chV +.Op Fl c Ar config +.Op Fl CV .Ar message room .Ek .Sh DESCRIPTION .Nm -is a script that sends a message to a Matrix room. -It works by sending a JSON message to your Matrix server. The default message -type is m.text, but you can specify a custom type with +sends messages to Matrix rooms. +The default event type is m.text (standard text message), +but you can specify a custom type with .Em -t . .Pp The options are as follows: .Bl -tag -width keyword +.It Fl C +Clear cached access tokens and transaction IDs then exit. +.It Fl c Ar config +Instead of reading the default configuration file (~/.config/matrix-send.conf), read +.Ar config . .It Fl t Ar type Change the event type to .Ar type . @@ -30,49 +35,52 @@ and .Em m.notice . Default is .Em m.text . -.It Fl C Ar config -Instead of reading the default configuration file (~/.config/matrix-send.conf), read -.Ar config . -.It Fl c -Clear cached access tokens. -.It Fl h -Show the help menu, then exit. .It Fl V -Print version and program information, then exit. +Print version information and exit. .El .Pp To begin, start by making a configuration file. This always has the location of -.Em ~/.config/matrix-send.conf . +.Em ~/.config/matrix-send/config.lua . -At the very least, your configuration file has to contain 3 directives: -.Em Server , -.Em Username , +At the very least, your configuration file has to contain three values: +.Em login.server , +.Em login.username , and -.Em Password . -Let's say your Matrix server is envs.net. Your username is john, and your password +.Em login.password . +Let's say your Matrix server is envs.net, your username is john, and your password is supersecretpassword. Your configuration could look like this: .Bd -literal -offset indent -Server matrix.envs.net -Username john -Password supersecretpassword +login = { + server = "matrix.envs.net", + username = "john", + password = "supersecretpassword" +} .Ed .Pp -In that example, we used matrix.envs.net instead of envs.net. This is because +It could also look like this: +.Bd -literal -offset indent +login.server = "matrix.envs.net" +login.username = "john" +login.password = "supersecretpassword" +.Ed +.Pp +In those examples, we used matrix.envs.net instead of envs.net. This is because matrix.envs.net is the address in which the Client-Server API is listening on. -You can find your server's Client-Server API URL in Element by entering in -your server into the Homeserver dialogue in the sign-in screen, then hovering +You can find this address in Element by entering in your server into the +Homeserver dialogue in the sign-in screen, then hovering over it once entered. Your server's Client-Server API URL should appear once -you hover over it. If it doesn't appear, you've already got it. +you hover over it. If it doesn't appear, you should already have it. .Pp You may have noticed that with this configuration, your password is visible in plain sight. -At its most basic, matrix-send.conf is a shell script. This means you could +If you would like to have to encrypt your password before use, +you could replace the -.Em Password +.Em login.password line with something similar to this .Pp -.Dl Password $(gpg -d /path/to/passwd.gpg) + login.password = sh "gpg -d /path/to/passwd.gpg" .Pp where .Em /path/to/passwd.gpg @@ -82,7 +90,7 @@ decrypt your password file before authenticating. This way, your password is not in plain text. More information on configuration options can be found in -.Xr matrix-send.conf 5 . +.Xr matrix-send-config 5 . .Pp To use .Nm , @@ -102,9 +110,13 @@ to the room with the Room ID !zyxwvutsrq:example.org. By default, .Nm caches access tokens in -.Em $HOME/.cache/matrix-send/access-token . -If you would like to disable caching of access tokens, add NoCache to your -.Em matrix-send.conf . +.Em $HOME/.cache/matrix-send/token . +If you would like to disable caching of access tokens, add +.Pp +.Dl cache.disable = true +.Pp +to your +.Em config.lua . .Pp Encryption is not supported. All messages will be sent unencrypted. There are currently no plans to add encryption to @@ -112,19 +124,19 @@ There are currently no plans to add encryption to .El .Sh FILES -.Bl -tag -width ~/.config/matrix-send.conf -.It Pa ~/.config/matrix-send.conf +.Bl -tag -width ~/.config/matrix-send/config.lua +.It Pa ~/.config/matrix-send/config.lua configuration file for .Nm -.It Pa ~/.cache/matrix-send/access-token -access token cache file +.It Pa ~/.cache/matrix-send +cache directory .El .Sh EXAMPLES -Send a message saying "How are you?" to the Matrix room !TfbDbeqp:example.org: +Send a message saying "Hello world!" to the Matrix room !TfbDbeqp:example.org: .Pp -.Dl matrix-send 'How are you?' !TfbDbeqp:example.org +.Dl matrix-send 'Hello world!' \\!TfbDbeqp:example.org .Pp .Sh SEE ALSO -.Xr matrix-send.conf 5 +.Xr matrix-send-config 5 diff --git a/matrix-send.conf b/matrix-send.conf deleted file mode 100644 index a7582ab..0000000 --- a/matrix-send.conf +++ /dev/null @@ -1,17 +0,0 @@ -## Example basic configuration for matrix-send -# A line with an option (e.g. 'Username jeremy') is a "directive". -# A line with only one word (e.g. 'NoCache') is a "statement". -# Comments start with a pound (#) -# Additional options can be found in matrix-send.conf(5) - -# The Server directive is for your server's Matrix Client-Server API URL. -# matrix-send assumes that this is valid. -# matrix.org's CS API URL is matrix-client.matrix.org. -# You can find it by typing it into Element's sign in page and hovering your mouse over it. -Server matrix.envs.net - -# The Username directive is your username for that server. -Username john - -# The Password directive is your password for your account. -Password supersecretpassword diff --git a/matrix-send.conf.5 b/matrix-send.conf.5 deleted file mode 100644 index 55a1c50..0000000 --- a/matrix-send.conf.5 +++ /dev/null @@ -1,60 +0,0 @@ -.Dd $Mdocdate: August 4 2022 $ -.Dt MATRIX-SEND.CONF 5 -.Os -.Sh NAME -.Nm matrix-send.conf -.Nd configuration file for -.Xr matrix-send 1 -.Sh DESCRIPTION -.Xr matrix-send 1 -sends messages to Matrix rooms. In order to send a message however, it needs -credentials for the account sending the message. These credentials are provided -in the -.Nm -configuration file, as well as other options if you need them. -.Pp -The following configuration options are available: -.Bl -tag -width 11n -.Bl -tag -width keepenv -.It Ic Server Ar server -The Client-Server API address of the Matrix server being used. -.It Ic Username Ar username -The username of the account being used. -.It Ic Password Ar password -The password for the account being used. -.It Ic AccessToken Ar token -Instead of authenticating via username and password to obtain an access token, use -.Ar token -as the access token. -.It Ic CacheLocation Ar location -Modify the cache location from the default (~/.cache) to -.Ar location . -.It Ic NoCache -Don't cache access tokens. -.It Ic DefaultEvent Ar type -Modify the default event type from the default (m.text) to -.Ar type . -Supported types are m.text, and m.notice. -.It Ic PrettyPrint -Pretty-print the JSON server messages. -.El -.Sh FILES -.Bl -tag -width ~/.config/matrix-send.conf -compact -.It Pa ~/.config/matrix-send.conf -.Xr matrix-send 1 -configuration file. -.It Pa ~/.cache -Default cache location. -.El -.Sh EXAMPLES -The following example logs into the user johndoe of the server with the -Client-Server API address of matrix-client.matrix.org with the password -supersecretpassword, and sets the default event type to m.notice. -.Bd -literal -offset indent -Server matrix-client.matrix.org -Username johndoe -Password supersecretpassword -DefaultEvent m.notice -.Ed -.Sh SEE ALSO -.Xr matrix-send 1 From d133316183ff925782805baba234e122bff6dbe5 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 1 Jan 2023 12:29:03 +1300 Subject: [PATCH 02/10] Update version no. and dependencies in Makefile --- Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index cd74faf..88cb218 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION = 1.1 +VERSION = 2.0 PREFIX = /usr/local MANPREFIX = ${PREFIX}/man @@ -7,6 +7,10 @@ config: cp config.lua ~/.config/matrix-send/config.lua install: + # How I wish luarocks was better than this + luarocks install luaposix + luarocks install luasocket + luarocks install lua-cjson cp -f matrix-send ${DESTDIR}${PREFIX}/bin chmod +x ${DESTDIR}${PREFIX}/bin/matrix-send mkdir -p ${DESTDIR}${MANPREFIX}/man1 From a9c47a81b47c011c646e1c9316ab85a453c8548b Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 1 Jan 2023 12:29:50 +1300 Subject: [PATCH 03/10] Update README and fix manpage format problems --- README.md | 59 +++++++++++++++++++++++++++++++++++++++------------ matrix-send.1 | 24 +++------------------ 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index a71f45c..fbe0354 100644 --- a/README.md +++ b/README.md @@ -18,29 +18,33 @@ There aren't any plans for matrix-send to support encryption. In order to start using matrix-send, you need a config file. To copy the default configuration to .config, clone this repository and type `make config` as the desired user (not root). -Now edit the file ~/.config/matrix-send.conf. You will see three (uncommented) lines. +Now edit the file ~/.config/matrix-send/config.lua. You will first see the `login` table. -``` -Server ... -Username ... -Password ... +```lua +-- This is a comment +login = { + server = "matrix-client.matrix.org" -- matrix.org + username = "user" + password = "password" +} ``` Delete the example values and enter in your credentials. -If you don't want to put your password in plain text, as matrix-send.conf is a shell script, you could do something like this: - -```shell -Password $(gpg -d /path/to/passwd.gpg) -``` - -/path/to/passwd.gpg is a GPG-encrypted file containing only your password, once decrypted. - -For more configuration options, see [matrix-send.conf(5)](https://jtbx.codeberg.page/man/matrix-send.conf.5). +For more configuration options, see [matrix-send-config(5)](https://jtbx.codeberg.page/man/matrix-send-config.5). --- +## Installation + +Before you install, you will need a few dependencies: + + * lua: >= 5.3 + * [luarocks](https://luarocks.org) + * plus some luarocks packages... + To install matrix-send, run `make install` as root, in the cloned repository's directory. +This will install all required packages, and copy matrix-send and its documentation to your system. In order to send messages, you will need the Room ID of your choice. Find the room you want to send to, and find its Room ID in the settings or somewhere else. It will likely be under Advanced or something similar. @@ -52,4 +56,31 @@ matrix-send 'Hi!' \!asdfasdfasdfasdf:matrix.org That will send the message "Hi!" to the Matrix room !asdfasdfasdfasdf:matrix.org. +If you don't want to type the long room ID every time, you can add an alias. + +Open your configuration file, and create a `rooms` table like so: + +```lua +rooms = { +} +``` + +Now, you can add aliases. Say you wanted to add an alias called `lounge` for a room with room ID `!AbCdEfGhIjKlMn:matrix.org`. +You would make it this way: + +```lua +rooms = { + lounge = "!AbCdEfGhIjKlMn:matrix.org" +} +``` + +Multiple aliases are separated by commas (as with any Lua table): + +```lua +rooms = { + lounge = "!AbCdEfGhIjKlMn:matrix.org", -- <-- notice the comma + bathroom = "!OpQrStUvWxYz:matrix.org" +} +``` + For more information, see [matrix-send(1)](https://jtbx.codeberg.page/man/matrix-send.1). diff --git a/matrix-send.1 b/matrix-send.1 index 9b57606..e4aebc8 100644 --- a/matrix-send.1 +++ b/matrix-send.1 @@ -71,24 +71,6 @@ Homeserver dialogue in the sign-in screen, then hovering over it once entered. Your server's Client-Server API URL should appear once you hover over it. If it doesn't appear, you should already have it. .Pp -You may have noticed that with this configuration, your password -is visible in plain sight. - -If you would like to have to encrypt your password before use, -you could -replace the -.Em login.password -line with something similar to this -.Pp - login.password = sh "gpg -d /path/to/passwd.gpg" -.Pp -where -.Em /path/to/passwd.gpg -is a GPG-encrypted plain text file containing only your password. -This line would mean that you would be asked for the passphrase required to -decrypt your password file before authenticating. This way, your password -is not in plain text. - More information on configuration options can be found in .Xr matrix-send-config 5 . .Pp @@ -99,9 +81,9 @@ This will be something like .Em !zyxwvutsrq:example.org . Type the Room ID as the argument after the message you wish to send. -You may have to escape the exclamation mark with a backslash. For example: +You may have to write the Room ID in quotes to avoid shell patterns. .Pp -.Dl matrix-send "Hello world!" \\!zyxwvutsrq:example.org +.Dl matrix-send 'Hello world!' '!zyxwvutsrq:example.org' .Pp That would send a message saying .Em Hello world! @@ -135,7 +117,7 @@ cache directory .Sh EXAMPLES Send a message saying "Hello world!" to the Matrix room !TfbDbeqp:example.org: .Pp -.Dl matrix-send 'Hello world!' \\!TfbDbeqp:example.org +.Dl matrix-send 'Hello world!' '!TfbDbeqp:example.org' .Pp .Sh SEE ALSO From bc1272a3e4fe5b8cb65774a75128be6d5b5451dd Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sat, 31 Dec 2022 23:30:51 +0000 Subject: [PATCH 04/10] Oops --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fbe0354..79097c6 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,8 @@ Now edit the file ~/.config/matrix-send/config.lua. You will first see the `logi ```lua -- This is a comment login = { - server = "matrix-client.matrix.org" -- matrix.org - username = "user" + server = "matrix-client.matrix.org", -- matrix.org + username = "user", password = "password" } ``` From 91e9801c0fc818bdfd51ee4b0e3f3851a426b84f Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 1 Jan 2023 02:44:27 +0000 Subject: [PATCH 05/10] Update 'README.md' --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 79097c6..7fbe876 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,10 @@ A script that sends messages to Matrix rooms. --- -matrix-send is a simple script that sends a message to a Matrix room. +matrix-send is a simple script that sends messages to Matrix rooms. -It does this by sending a JSON message to your Matrix server. The message types that are supported are `m.text`, and `m.notice`. +It does this by directly making requests to the API of your Matrix server. +The supported event types are `m.text` and `m.notice`. It is mainly designed for automation. @@ -16,7 +17,7 @@ There aren't any plans for matrix-send to support encryption. ## Get started -In order to start using matrix-send, you need a config file. To copy the default configuration to .config, clone this repository and type `make config` as the desired user (not root). +In order to start using matrix-send, you need a config file. To copy the default configuration to .config, clone this repository and type `make config` as your user (not root). Now edit the file ~/.config/matrix-send/config.lua. You will first see the `login` table. @@ -54,7 +55,7 @@ To send a message, type `matrix-send` followed by your message and then your Roo matrix-send 'Hi!' \!asdfasdfasdfasdf:matrix.org ``` -That will send the message "Hi!" to the Matrix room !asdfasdfasdfasdf:matrix.org. +That will send the message "Hi!" to the Matrix room `!asdfasdfasdfasdf:matrix.org.` If you don't want to type the long room ID every time, you can add an alias. @@ -83,4 +84,4 @@ rooms = { } ``` -For more information, see [matrix-send(1)](https://jtbx.codeberg.page/man/matrix-send.1). +For more information, see [matrix-send(1)](https://jtbx.codeberg.page/man/matrix-send.1) and [matrix-send-config(5)](https://jtbx.codeberg.page/man/matrix-send-config.5). From 2d8788afd9372402bbf1955f54233ce2b216863d Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 1 Jan 2023 13:08:08 +1300 Subject: [PATCH 06/10] another oopsy --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 88cb218..d8e1712 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ config: cp config.lua ~/.config/matrix-send/config.lua install: - # How I wish luarocks was better than this + @# How I wish luarocks was better than this luarocks install luaposix luarocks install luasocket luarocks install lua-cjson From 932ee958c084df419b1b934df3245b7202165756 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Sun, 1 Jan 2023 17:41:17 +1300 Subject: [PATCH 07/10] Implement server discovery (.well-known/matrix/client), and re-authenticate if access token expired or was invalidated somehow --- matrix-send | 181 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 104 insertions(+), 77 deletions(-) diff --git a/matrix-send b/matrix-send index f042356..ab3cc7d 100755 --- a/matrix-send +++ b/matrix-send @@ -19,11 +19,11 @@ require "luarocks.loader" getopt = require "posix.unistd".getopt -mkdir = require "posix.sys.stat".mkdir -bname = require "posix.libgen".basename -http = require "socket.http" -cjson = require "cjson" -ltn12 = require "ltn12" + mkdir = require "posix.sys.stat".mkdir + bname = require "posix.libgen".basename + http = require "socket.http" + cjson = require "cjson" + ltn12 = require "ltn12" version = "2.0" confdir = string.gsub("~/.config/matrix-send", '~', os.getenv("HOME"), 1) @@ -31,9 +31,10 @@ confpath = confdir .. "/config.lua" confvarv = os.getenv("MATRIXSEND_CONFIG") hostname = io.input("/etc/hostname"):read("l") -json = {} - uri = {} - sh = os.execute +matrix = {} + json = {} + uri = {} + sh = os.execute ----------------- --- Functions --- @@ -50,38 +51,6 @@ function fileexists(file) end end --- Makes an HTTP POST request to uri and sends body. Returns the output of the HTTP server. -function post(uri, body) - local respbody = {} -- for the response body - local result, respcode, respheaders, respstatus = http.request { - method = "POST", - url = uri, - source = ltn12.source.string(body), - headers = { - ["content-type"] = "application/json", - ["content-length"] = tostring(#body) - }, - sink = ltn12.sink.table(respbody) - } - return table.concat(respbody) -end - --- Makes an HTTP PUT request to uri and sends body. Returns the output of the HTTP server. -function put(uri, body) - local respbody = {} -- for the response body - local result, respcode, respheaders, respstatus = http.request { - method = "PUT", - url = uri, - source = ltn12.source.string(body), - headers = { - ["content-type"] = "application/json", - ["content-length"] = tostring(#body) - }, - sink = ltn12.sink.table(respbody) - } - return table.concat(respbody) -end - -- Prints a message to stdout in the following format: -- matrix-send: s function msg(s) @@ -104,20 +73,87 @@ function confpanic(s) os.exit(1) end +------------------------ +--- Matrix functions --- +------------------------ + +function matrix.login(uri, json) + local respbody = {} + local result, respcode, respheaders, respstatus = http.request { + method = "POST", + url = uri, + source = ltn12.source.string(json), + headers = { + ["content-type"] = "application/json", + ["content-length"] = tostring(#json) + }, + sink = ltn12.sink.table(respbody) + } + local body = table.concat(respbody) + local t = cjson.decode(body) + if t.error then + panic("server: " .. t.error) + else + return t.access_token + end +end + +function matrix.send(uri, json, login_uri, login_json) + local respbody = {} + local result, respcode, respheaders, respstatus = http.request { + method = "PUT", + url = uri, + source = ltn12.source.string(json), + headers = { + ["content-type"] = "application/json", + ["content-length"] = tostring(#json) + }, + sink = ltn12.sink.table(respbody) + } + local body = table.concat(respbody) + local t = cjson.decode(body) + if t.error then + if t.errcode == "M_UNKNOWN_TOKEN" then + msg("token expired/invalidated; re-authenticating") + -- I mean, it works + t = setmetatable({}, { + __concat = function(left, right) + if type(left) == "string" then + return left .. tostring(right) + end + return tostring(left) .. tostring(right) + end + }) + t.token = matrix.login(login_uri, login_json) + if not cache.disable then + mkdir(cache.location) + cf = io.open(cache.location .. "/token", 'w+') + cf:write(t.token) + cf:close() + end + matrix.send(string.gsub(uri, "access_token=.+", "access_token=" .. t.token), json, login_uri, login_json) + else + panic("server: " .. t.error) + end + else + return t + end +end + -- Default configuration file default_config = [[ -- Default configuration file for matrix-send -- In comments, here is a simple example configuration. --login = { --- server = "matrix.envs.net", +-- server = "envs.net", -- username = "john", -- password = "examplepassword --} -- You could also do it this way: ---login.server = "matrix.envs.net" +--login.server = "envs.net" --login.username = "john" --login.password = "examplepassword" @@ -242,9 +278,29 @@ else txnid = 0 end -uri.login = string.format("https://%s/_matrix/client/v3/login", login.server) +-- Get .well-known +uri.well_known = string.format("https://%s/.well-known/matrix/client", login.server) +wellknown_body, errno = http.request(uri.well_known) +if errno ~= 200 then + panic("server: Error " .. errno .. " while getting /.well-known/matrix/client") +end +wellknown_t = cjson.decode(wellknown_body) +login.server = wellknown_t["m.homeserver"].base_url + +-- Assign URIs and JSON bodies +uri.login = string.format("%s/_matrix/client/v3/login", login.server) +json.login = string.format([[ +{ + "identifier": { + "type": "m.id.user", + "user": "%s" + }, + "initial_device_display_name": "matrix-send@%s", + "password": "%s", + "type": "m.login.password" +} +]], login.username, hostname, login.password) --- Assemble various JSON messages json.message = string.format([[ { "body": "%s", @@ -259,33 +315,8 @@ if not login.token then login.token = cf:read('l') cf:close() else - -- json.login should only be assigned if it needs to be assigned - json.login = string.format([[ - { - "identifier": { - "type": "m.id.user", - "user": "%s" - }, - "initial_device_display_name": "matrix-send@%s", - "password": "%s", - "type": "m.login.password" - } - - ]], login.username, hostname, login.password) - - -- Send the request! - local body = post(uri.login, json.login) - - -- What else do I call it? - local t = cjson.decode(body) - - -- If there was a server side error, print the error and exit. - if t.error then - panic(login.server .. ": " .. t.error) - end - - -- Log the access token - login.token = t.access_token + -- Login + login.token = matrix.login(uri.login, json.login) -- Cache the access token if not cache.disable then @@ -297,15 +328,11 @@ if not login.token then end end -uri.message = string.format("https://%s/_matrix/client/v3/rooms/%s/send/m.room.message/%d?access_token=%s", +uri.message = string.format("%s/_matrix/client/v3/rooms/%s/send/m.room.message/%d?access_token=%s", login.server, room_id, txnid, login.token) -- Send the message! -body = put(uri.message, json.message) -t = cjson.decode(body) -if t.error then - panic(login.server .. ": " .. t.error) -end +matrix.send(uri.message, json.message, uri.login, json.login) -- Increment txnid and cache if not cache.disable then From a6ee41a6ab51296a6f766688d44d250deb074488 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 9 Jan 2023 12:36:48 +1300 Subject: [PATCH 08/10] Precompile Lua into bytecode before running it (see COMPILE) --- .gitignore | 2 +- COMPILE | 35 ++++++++++++++++++++++++++++++++++ Makefile | 4 +++- matrix-send => matrix-send.lua | 0 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 COMPILE rename matrix-send => matrix-send.lua (100%) diff --git a/.gitignore b/.gitignore index 6fd0a37..74ae39b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Compiled Lua sources luac.out +matrix-send # luarocks build files *.src.rock @@ -38,4 +39,3 @@ luac.out *.i*86 *.x86_64 *.hex - diff --git a/COMPILE b/COMPILE new file mode 100644 index 0000000..5caca11 --- /dev/null +++ b/COMPILE @@ -0,0 +1,35 @@ + ___________________ + < Manually building > + ------------------- + +Since matrix-send uses Lua, an interpreted programming language, +building is not necessary; you could just move matrix-send.lua to +/usr/local/bin and be done with it. However, for additional speed, +the Makefile precompiles it to Lua bytecode using +luac which is included +in the Lua distribution. To do this yourself, follow these steps: + + => Create the shebang + +In order to be run by a shell, the compiled bytecode needs a +shebang at the start. To do this, run this command: + + printf '#!/usr/bin/env lua\n' > matrix-send + + + => Precompile + +Now, let's append the bytecode to the file: + + luac -o - matrix-send.lua >> matrix-send + + + => Mark as an executable + +Finally, mark the file as executable: + + chmod +x matrix-send + +The file `matrix-send` is now ready to be run by a shell. + +# vi: ft=txt diff --git a/Makefile b/Makefile index d8e1712..0b18e1e 100644 --- a/Makefile +++ b/Makefile @@ -11,8 +11,10 @@ install: luarocks install luaposix luarocks install luasocket luarocks install lua-cjson + printf '#!/usr/bin/env lua\n' > matrix-send + luac -o - matrix-send.lua >> matrix-send + chmod +x matrix-send cp -f matrix-send ${DESTDIR}${PREFIX}/bin - chmod +x ${DESTDIR}${PREFIX}/bin/matrix-send mkdir -p ${DESTDIR}${MANPREFIX}/man1 cp -f matrix-send.1 ${DESTDIR}${MANPREFIX}/man1 mkdir -p ${DESTDIR}${MANPREFIX}/man5 diff --git a/matrix-send b/matrix-send.lua similarity index 100% rename from matrix-send rename to matrix-send.lua From 59b9ba67b7b3ed8e31d23ee30ef3d942189ca6d9 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 9 Jan 2023 12:48:51 +1300 Subject: [PATCH 09/10] Remove need for Client-Server API addresses in docs --- README.md | 2 +- config.lua | 2 +- matrix-send-config.5 | 6 +++--- matrix-send.1 | 11 ++--------- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 7fbe876..27fdd89 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Now edit the file ~/.config/matrix-send/config.lua. You will first see the `logi ```lua -- This is a comment login = { - server = "matrix-client.matrix.org", -- matrix.org + server = "matrix.org", username = "user", password = "password" } diff --git a/config.lua b/config.lua index f271a49..87ce0c4 100644 --- a/config.lua +++ b/config.lua @@ -1,6 +1,6 @@ login = { -- The Matrix server to use. - server = "matrix-client.matrix.org", -- matrix.org + server = "matrix.org", -- The user to log in to. username = "user", diff --git a/matrix-send-config.5 b/matrix-send-config.5 index b2c468c..717a286 100644 --- a/matrix-send-config.5 +++ b/matrix-send-config.5 @@ -20,7 +20,7 @@ The following configuration options are available: .Bl -tag -width 11n .Bl -tag -width login.server .It Ic login.server Ar server -The Client-Server API address of the Matrix server being used. +The address of the Matrix server being used. .It Ic login.username Ar username The username of the account being used. .It Ic login.password Ar password @@ -50,11 +50,11 @@ default cache directory .El .Sh EXAMPLES The following example logs into the user 'john' of the server -matrix-client.matrix.org, and the password 'supersecretpassword', +matrix.org, and the password 'supersecretpassword', and sets the default event type to m.notice. .Bd -literal -offset indent login = { - server = "matrix-client.matrix.org", + server = "matrix.org", username = "john", password = "supersecretpassword" } diff --git a/matrix-send.1 b/matrix-send.1 index e4aebc8..3a4f4a0 100644 --- a/matrix-send.1 +++ b/matrix-send.1 @@ -51,7 +51,7 @@ Let's say your Matrix server is envs.net, your username is john, and your passwo is supersecretpassword. Your configuration could look like this: .Bd -literal -offset indent login = { - server = "matrix.envs.net", + server = "envs.net", username = "john", password = "supersecretpassword" } @@ -59,18 +59,11 @@ login = { .Pp It could also look like this: .Bd -literal -offset indent -login.server = "matrix.envs.net" +login.server = "envs.net" login.username = "john" login.password = "supersecretpassword" .Ed .Pp -In those examples, we used matrix.envs.net instead of envs.net. This is because -matrix.envs.net is the address in which the Client-Server API is listening on. -You can find this address in Element by entering in your server into the -Homeserver dialogue in the sign-in screen, then hovering -over it once entered. Your server's Client-Server API URL should appear once -you hover over it. If it doesn't appear, you should already have it. -.Pp More information on configuration options can be found in .Xr matrix-send-config 5 . .Pp From 3ed1af15d039b1226f656175a5283b01a212ba27 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 9 Jan 2023 12:58:47 +1300 Subject: [PATCH 10/10] Version 2.0 -> 2.1 --- Makefile | 2 +- matrix-send.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 0b18e1e..a230233 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION = 2.0 +VERSION = 2.1 PREFIX = /usr/local MANPREFIX = ${PREFIX}/man diff --git a/matrix-send.lua b/matrix-send.lua index ab3cc7d..feee075 100755 --- a/matrix-send.lua +++ b/matrix-send.lua @@ -25,7 +25,7 @@ getopt = require "posix.unistd".getopt cjson = require "cjson" ltn12 = require "ltn12" - version = "2.0" + version = "2.1" confdir = string.gsub("~/.config/matrix-send", '~', os.getenv("HOME"), 1) confpath = confdir .. "/config.lua" confvarv = os.getenv("MATRIXSEND_CONFIG")