Compare commits
No commits in common. "v1.0.1" and "master" have entirely different histories.
13 changed files with 673 additions and 359 deletions
41
.gitignore
vendored
Normal file
41
.gitignore
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# Compiled Lua sources
|
||||||
|
luac.out
|
||||||
|
matrix-send
|
||||||
|
|
||||||
|
# luarocks build files
|
||||||
|
*.src.rock
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.os
|
||||||
|
*.ko
|
||||||
|
*.obj
|
||||||
|
*.elf
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
*.def
|
||||||
|
*.exp
|
||||||
|
|
||||||
|
# Shared objects (inc. Windows DLLs)
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
*.i*86
|
||||||
|
*.x86_64
|
||||||
|
*.hex
|
35
COMPILE
Normal file
35
COMPILE
Normal file
|
@ -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 <https://www.lua.org/manual/5.4/luac.html> 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
|
15
Makefile
15
Makefile
|
@ -1,14 +1,21 @@
|
||||||
VERSION = 1.0
|
VERSION = 2.1
|
||||||
PREFIX = /usr/local
|
PREFIX = /usr/local
|
||||||
MANPREFIX = ${PREFIX}/man
|
MANPREFIX = ${PREFIX}/man
|
||||||
|
|
||||||
config:
|
config:
|
||||||
cp matrix-send.conf ~/.config/matrix-send.conf
|
mkdir -p ~/.config/matrix-send
|
||||||
|
cp config.lua ~/.config/matrix-send/config.lua
|
||||||
|
|
||||||
install:
|
install:
|
||||||
|
@# How I wish luarocks was better than this
|
||||||
|
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
|
cp -f matrix-send ${DESTDIR}${PREFIX}/bin
|
||||||
chmod +x ${DESTDIR}${PREFIX}/bin/matrix-send
|
|
||||||
mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
||||||
cp -f matrix-send.1 ${DESTDIR}${MANPREFIX}/man1
|
cp -f matrix-send.1 ${DESTDIR}${MANPREFIX}/man1
|
||||||
mkdir -p ${DESTDIR}${MANPREFIX}/man5
|
mkdir -p ${DESTDIR}${MANPREFIX}/man5
|
||||||
cp -f matrix-send.conf.5 ${DESTDIR}${MANPREFIX}/man5
|
cp -f matrix-send-config.5 ${DESTDIR}${MANPREFIX}/man5
|
||||||
|
|
80
README.md
80
README.md
|
@ -1,52 +1,51 @@
|
||||||
# matrix-send
|
# 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)
|
[Read the manual page](https://jtbx.codeberg.page/man/matrix-send.1)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Syntax:** `matrix-send message room`
|
matrix-send is a simple script that sends messages to Matrix rooms.
|
||||||
|
|
||||||
**Example:** `matrix-send "Hello world\!" \!aBcDeFgHiJkLmNoP:example.org`
|
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.
|
||||||
|
|
||||||
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 is mainly designed for automation. I use it on a private Matrix room of mine.
|
|
||||||
|
|
||||||
There aren't any plans for matrix-send to support encryption.
|
There aren't any plans for matrix-send to support encryption.
|
||||||
|
|
||||||
## Get started
|
## 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.conf. You will see three (uncommented) lines.
|
Now edit the file ~/.config/matrix-send/config.lua. You will first see the `login` table.
|
||||||
|
|
||||||
```
|
```lua
|
||||||
Server ...
|
-- This is a comment
|
||||||
Username ...
|
login = {
|
||||||
Password ...
|
server = "matrix.org",
|
||||||
|
username = "user",
|
||||||
|
password = "password"
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Delete the example values and enter in your credentials.
|
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:
|
For more configuration options, see [matrix-send-config(5)](https://jtbx.codeberg.page/man/matrix-send-config.5).
|
||||||
|
|
||||||
```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).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 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.
|
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.
|
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.
|
||||||
|
|
||||||
|
@ -56,6 +55,33 @@ To send a message, type `matrix-send` followed by your message and then your Roo
|
||||||
matrix-send 'Hi!' \!asdfasdfasdfasdf:matrix.org
|
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.`
|
||||||
|
|
||||||
For more information, see [matrix-send(1)](https://jtbx.codeberg.page/man/matrix-send.1).
|
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) and [matrix-send-config(5)](https://jtbx.codeberg.page/man/matrix-send-config.5).
|
||||||
|
|
31
config.lua
Normal file
31
config.lua
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
login = {
|
||||||
|
-- The Matrix server to use.
|
||||||
|
server = "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.
|
||||||
|
}
|
49
default_config.lua
Normal file
49
default_config.lua
Normal file
|
@ -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"
|
||||||
|
}
|
200
matrix-send
200
matrix-send
|
@ -1,200 +0,0 @@
|
||||||
#!/usr/bin/env sh
|
|
||||||
# matrix-send: send a message to a Matrix room
|
|
||||||
|
|
||||||
version="1.0"
|
|
||||||
|
|
||||||
###########################
|
|
||||||
#### Generic Functions ####
|
|
||||||
###########################
|
|
||||||
|
|
||||||
error () {
|
|
||||||
printf "\033[31;1merror:\033[0m $1\n"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
conf_error () {
|
|
||||||
printf "\033[31;1mconfiguration error:\033[0m $1\n"
|
|
||||||
exit 2
|
|
||||||
}
|
|
||||||
|
|
||||||
vargrep () {
|
|
||||||
printf "$2\n" | grep "$1" $3
|
|
||||||
}
|
|
||||||
|
|
||||||
usage () {
|
|
||||||
printf "usage: matrix-send [-t type] [-c] [-h] [-V] message room\n"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
help () {
|
|
||||||
cat <<EOF
|
|
||||||
matrix-send: send a message to a Matrix room
|
|
||||||
Options:
|
|
||||||
-t type: change default event type
|
|
||||||
-c: clear cached access tokens
|
|
||||||
-h: show this help menu
|
|
||||||
-V: show version and program information
|
|
||||||
|
|
||||||
For more information, type 'man matrix-send'.
|
|
||||||
https://codeberg.org/jtbx/matrix-send
|
|
||||||
EOF
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
version () {
|
|
||||||
cat <<EOF
|
|
||||||
matrix-send: send a message to a Matrix room
|
|
||||||
Version $version
|
|
||||||
|
|
||||||
matrix-send is licensed under the GNU General Public License v2.
|
|
||||||
Made in New Zealand
|
|
||||||
https://codeberg.org/jtbx/matrix-send
|
|
||||||
EOF
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
##################################
|
|
||||||
#### Configuration Directives ####
|
|
||||||
##################################
|
|
||||||
|
|
||||||
Server () {
|
|
||||||
[ -z $1 ] && conf_error "No argument for directive Server"
|
|
||||||
server="$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
Username () {
|
|
||||||
[ -z $1 ] && conf_error "No argument for directive Username"
|
|
||||||
username="$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
Password () {
|
|
||||||
[ -z $1 ] && conf_error "No argument(s) for directive Password"
|
|
||||||
password="$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
AccessToken () {
|
|
||||||
[ -z $1 ] && conf_error "No argument for directive AccessToken"
|
|
||||||
manualAuth="true"
|
|
||||||
token="$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
CacheLocation () {
|
|
||||||
[ -z $1 ] && conf_error "No argument for directive CacheLocation"
|
|
||||||
if vargrep "^/.+$" "$1" -Eq || \
|
|
||||||
vargrep "^~.+$" "$1" -Eq;
|
|
||||||
then cacheloc="$1";
|
|
||||||
else conf_error "Cache location is not valid (does not begin with / or ~)"; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
DefaultEvent () {
|
|
||||||
[ -z $1 ] && conf_error "No argument for directive DefaultEvent"
|
|
||||||
if vargrep "m\.(text|notice)" "$1" -Eq
|
|
||||||
then defaultevent="$1"
|
|
||||||
else conf_error "Invalid default event type"; fi
|
|
||||||
}
|
|
||||||
|
|
||||||
##################################
|
|
||||||
#### Configuration Statements ####
|
|
||||||
##################################
|
|
||||||
|
|
||||||
NoCache () {
|
|
||||||
nocache="true"
|
|
||||||
}
|
|
||||||
|
|
||||||
############################
|
|
||||||
#### Specific Functions ####
|
|
||||||
############################
|
|
||||||
|
|
||||||
GetAccessToken () {
|
|
||||||
[ -z "$manualAuth" ] && printf "Getting access token...\n"
|
|
||||||
if [ "$manualAuth" = "true" ];
|
|
||||||
then printf "";
|
|
||||||
else token=$(curl -s -XPOST -d "{"'"'"type"'"'":"'"'"m.login.password"'"'", "'"'"user"'"'":"'"'"$username"'"'", "'"'"password"'"'":"'"'"$password"'"'"}" "https://$server/_matrix/client/r0/login" | grep -oE 'syt_.+_...................._......');
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
CacheAccessToken () {
|
|
||||||
if [ "$nocache" = "true" ];
|
|
||||||
then printf "";
|
|
||||||
else
|
|
||||||
mkdir -p "$cacheloc/matrix-send"
|
|
||||||
printf "$token\n" > "$cacheloc/matrix-send/access-token";
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearCache () {
|
|
||||||
[ -e "$cacheloc/matrix-send/access-token" ] || printf "There is no cache to be cleared.\n"
|
|
||||||
[ -e "$cacheloc/matrix-send/access-token" ] && rm -rf "$cacheloc/matrix-send/" && printf "Cleared cache\n"
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Send () {
|
|
||||||
curl -s -XPOST -d "{"'"'"msgtype"'"'":"'"'"$mtype"'"'", "'"'"body"'"'":"'"'"$message"'"'"}" "https://$server/_matrix/client/r0/rooms/%21$roomid/send/m.room.message?access_token=$token"
|
|
||||||
#cat <<EOF
|
|
||||||
#"{"'"'"msgtype"'"'":"'"'"$mtype"'"'", "'"'"body"'"'":"'"'"$message"'"'"}" "https://$server/_matrix/client/r0/rooms/%21$roomid/send/m.room.message?access_token=$token"
|
|
||||||
#EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
########################
|
|
||||||
#### Initial checks ####
|
|
||||||
########################
|
|
||||||
|
|
||||||
[ -e /usr/local/bin/curl ] || [ -e /usr/bin/curl ] || error "curl not found"
|
|
||||||
CacheLocation "$HOME/.cache"
|
|
||||||
|
|
||||||
[ -z "$1" ] && usage
|
|
||||||
while getopts :t:chV opt
|
|
||||||
do
|
|
||||||
case $opt in
|
|
||||||
t)
|
|
||||||
if vargrep "m\.(text|notice)" "$OPTARG" -Eq
|
|
||||||
then
|
|
||||||
mtype="$OPTARG"
|
|
||||||
optind="$OPTIND"
|
|
||||||
else error "Type not valid (-t)"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
c) ClearCache ;;
|
|
||||||
h) help ;;
|
|
||||||
V) version ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
###############################
|
|
||||||
#### Configuration loading ####
|
|
||||||
###############################
|
|
||||||
|
|
||||||
# Load configuration
|
|
||||||
if [ -e $HOME/.config/matrix-send.conf ];
|
|
||||||
then . $HOME/.config/matrix-send.conf;
|
|
||||||
else
|
|
||||||
mkdir -p $HOME/.config
|
|
||||||
touch $HOME/.config/matrix-send.conf
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Run checks for essential directives
|
|
||||||
[ -z $server ] && conf_error "Server directive is not present"
|
|
||||||
[ -z $username ] && conf_error "Username directive is not present"
|
|
||||||
[ -z "$password" ] && conf_error "Password directive is not present"
|
|
||||||
|
|
||||||
##############
|
|
||||||
#### Main ####
|
|
||||||
##############
|
|
||||||
|
|
||||||
# Get token and cache it (unless NoCache is set)
|
|
||||||
[ -e "$cacheloc/matrix-send/access-token" ] && token=$(cat $cacheloc/matrix-send/access-token)
|
|
||||||
[ -e "$cacheloc/matrix-send/access-token" ] || GetAccessToken
|
|
||||||
CacheAccessToken
|
|
||||||
|
|
||||||
if [ -z "$2" ];
|
|
||||||
then error "Room ID not specified.";
|
|
||||||
else
|
|
||||||
shift $((OPTIND-1))
|
|
||||||
message="$1"
|
|
||||||
roomid_input="$2"
|
|
||||||
if [ -z "$mtype" ]; then mtype="$defaultevent"; fi;
|
|
||||||
if vargrep '!' "$roomid_input" -qo
|
|
||||||
then roomid="$(printf "$roomid_input" | sed 's/!//g')"
|
|
||||||
else roomid="$roomid_input"; fi
|
|
||||||
Send
|
|
||||||
fi
|
|
65
matrix-send-config.5
Normal file
65
matrix-send-config.5
Normal file
|
@ -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 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.org, and the password 'supersecretpassword',
|
||||||
|
and sets the default event type to m.notice.
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
login = {
|
||||||
|
server = "matrix.org",
|
||||||
|
username = "john",
|
||||||
|
password = "supersecretpassword"
|
||||||
|
}
|
||||||
|
|
||||||
|
advanced.event = "m.notice"
|
||||||
|
.Ed
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr matrix-send 1
|
103
matrix-send.1
103
matrix-send.1
|
@ -1,4 +1,4 @@
|
||||||
.Dd $Mdocdate: August 3 2022 $
|
.Dd $Mdocdate: January 1 2023 $
|
||||||
.Dt MATRIX-SEND 1
|
.Dt MATRIX-SEND 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -8,20 +8,24 @@
|
||||||
.Nm matrix-send
|
.Nm matrix-send
|
||||||
.Bk -words
|
.Bk -words
|
||||||
.Op Fl t Ar type
|
.Op Fl t Ar type
|
||||||
.Op Fl c
|
.Op Fl c Ar config
|
||||||
.Op Fl h
|
.Op Fl CV
|
||||||
.Op Fl V
|
|
||||||
.Ar message room
|
.Ar message room
|
||||||
.Ek
|
.Ek
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm
|
.Nm
|
||||||
is a script that sends a message to a Matrix room.
|
sends messages to Matrix rooms.
|
||||||
It works by sending a JSON message to your Matrix server. The default message
|
The default event type is m.text (standard text message),
|
||||||
type is m.text, but you can specify a custom type with
|
but you can specify a custom type with
|
||||||
.Em -t .
|
.Em -t .
|
||||||
.Pp
|
.Pp
|
||||||
The options are as follows:
|
The options are as follows:
|
||||||
.Bl -tag -width keyword
|
.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
|
.It Fl t Ar type
|
||||||
Change the event type to
|
Change the event type to
|
||||||
.Ar type .
|
.Ar type .
|
||||||
|
@ -31,56 +35,37 @@ and
|
||||||
.Em m.notice .
|
.Em m.notice .
|
||||||
Default is
|
Default is
|
||||||
.Em m.text .
|
.Em m.text .
|
||||||
.It Fl c
|
|
||||||
Clear cached access tokens.
|
|
||||||
.It Fl h
|
|
||||||
Show the help menu, then exit.
|
|
||||||
.It Fl V
|
.It Fl V
|
||||||
Print version and program information, then exit.
|
Print version information and exit.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
To begin, start by making a configuration file. This always has the location of
|
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:
|
At the very least, your configuration file has to contain three values:
|
||||||
.Em Server ,
|
.Em login.server ,
|
||||||
.Em Username ,
|
.Em login.username ,
|
||||||
and
|
and
|
||||||
.Em Password .
|
.Em login.password .
|
||||||
Let's say your Matrix server is envs.net. Your username is john, and your 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:
|
is supersecretpassword. Your configuration could look like this:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
Server matrix.envs.net
|
login = {
|
||||||
Username john
|
server = "envs.net",
|
||||||
Password supersecretpassword
|
username = "john",
|
||||||
|
password = "supersecretpassword"
|
||||||
|
}
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
In that example, we used matrix.envs.net instead of envs.net. This is because
|
It could also look like this:
|
||||||
matrix.envs.net is the address in which the Client-Server API is listening on.
|
.Bd -literal -offset indent
|
||||||
You can find your server's Client-Server API URL in Element by entering in
|
login.server = "envs.net"
|
||||||
your server into the Homeserver dialogue in the sign-in screen, then hovering
|
login.username = "john"
|
||||||
over it once entered. Your server's Client-Server API URL should appear once
|
login.password = "supersecretpassword"
|
||||||
you hover over it. If it doesn't appear, you've already got it.
|
.Ed
|
||||||
.Pp
|
.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
|
|
||||||
replace the
|
|
||||||
.Em Password
|
|
||||||
line with something similar to this
|
|
||||||
.Pp
|
|
||||||
.Dl Password $(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
|
More information on configuration options can be found in
|
||||||
.Xr matrix-send.conf 5 .
|
.Xr matrix-send-config 5 .
|
||||||
.Pp
|
.Pp
|
||||||
To use
|
To use
|
||||||
.Nm ,
|
.Nm ,
|
||||||
|
@ -89,9 +74,9 @@ This will be something like
|
||||||
.Em !zyxwvutsrq:example.org .
|
.Em !zyxwvutsrq:example.org .
|
||||||
|
|
||||||
Type the Room ID as the argument after the message you wish to send.
|
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
|
.Pp
|
||||||
.Dl matrix-send "Hello world!" \\!zyxwvutsrq:example.org
|
.Dl matrix-send 'Hello world!' '!zyxwvutsrq:example.org'
|
||||||
.Pp
|
.Pp
|
||||||
That would send a message saying
|
That would send a message saying
|
||||||
.Em Hello world!
|
.Em Hello world!
|
||||||
|
@ -100,9 +85,13 @@ to the room with the Room ID !zyxwvutsrq:example.org.
|
||||||
By default,
|
By default,
|
||||||
.Nm
|
.Nm
|
||||||
caches access tokens in
|
caches access tokens in
|
||||||
.Em $HOME/.cache/matrix-send/access-token .
|
.Em $HOME/.cache/matrix-send/token .
|
||||||
If you would like to disable caching of access tokens, add NoCache to your
|
If you would like to disable caching of access tokens, add
|
||||||
.Em matrix-send.conf .
|
.Pp
|
||||||
|
.Dl cache.disable = true
|
||||||
|
.Pp
|
||||||
|
to your
|
||||||
|
.Em config.lua .
|
||||||
.Pp
|
.Pp
|
||||||
Encryption is not supported. All messages will be sent unencrypted.
|
Encryption is not supported. All messages will be sent unencrypted.
|
||||||
There are currently no plans to add encryption to
|
There are currently no plans to add encryption to
|
||||||
|
@ -110,19 +99,19 @@ There are currently no plans to add encryption to
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width ~/.config/matrix-send.conf
|
.Bl -tag -width ~/.config/matrix-send/config.lua
|
||||||
.It Pa ~/.config/matrix-send.conf
|
.It Pa ~/.config/matrix-send/config.lua
|
||||||
configuration file for
|
configuration file for
|
||||||
.Nm
|
.Nm
|
||||||
.It Pa ~/.cache/matrix-send/access-token
|
.It Pa ~/.cache/matrix-send
|
||||||
access token cache file
|
cache directory
|
||||||
.El
|
.El
|
||||||
|
|
||||||
.Sh EXAMPLES
|
.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
|
.Pp
|
||||||
.Dl matrix-send 'How are you?' !TfbDbeqp:example.org
|
.Dl matrix-send 'Hello world!' '!TfbDbeqp:example.org'
|
||||||
.Pp
|
.Pp
|
||||||
|
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr matrix-send.conf 5
|
.Xr matrix-send-config 5
|
||||||
|
|
|
@ -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
|
|
|
@ -1,54 +0,0 @@
|
||||||
.Dd $Mdocdate: August 3 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 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.
|
|
||||||
.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
|
|
342
matrix-send.lua
Executable file
342
matrix-send.lua
Executable file
|
@ -0,0 +1,342 @@
|
||||||
|
#!/usr/bin/env lua
|
||||||
|
--[[
|
||||||
|
The GPLv2 License (GPLv2)
|
||||||
|
Copyright (c) 2022 Jeremy Baxter
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
]]--
|
||||||
|
|
||||||
|
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"
|
||||||
|
|
||||||
|
version = "2.1"
|
||||||
|
confdir = string.gsub("~/.config/matrix-send", '~', os.getenv("HOME"), 1)
|
||||||
|
confpath = confdir .. "/config.lua"
|
||||||
|
confvarv = os.getenv("MATRIXSEND_CONFIG")
|
||||||
|
hostname = io.input("/etc/hostname"):read("l")
|
||||||
|
|
||||||
|
matrix = {}
|
||||||
|
json = {}
|
||||||
|
uri = {}
|
||||||
|
sh = os.execute
|
||||||
|
|
||||||
|
-----------------
|
||||||
|
--- Functions ---
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
-- Returns true if the given file name file exists, otherwise returns false.
|
||||||
|
function fileexists(file)
|
||||||
|
local f, err = io.open(file, 'r')
|
||||||
|
if f then
|
||||||
|
f:close()
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false, err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Prints a message to stdout in the following format:
|
||||||
|
-- matrix-send: s
|
||||||
|
function msg(s)
|
||||||
|
io.stdout:write(string.format("%s: %s\n", bname(arg[0]), s))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Prints an error message to stderr in the following format:
|
||||||
|
-- matrix-send: s
|
||||||
|
-- After that, exits and returns 1 to the OS.
|
||||||
|
function panic(s)
|
||||||
|
io.stderr:write(string.format("%s: %s\n", bname(arg[0]), s))
|
||||||
|
os.exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Prints an error message to stderr in the following format:
|
||||||
|
-- matrix-send: confpath: s
|
||||||
|
-- After that, exits and returns 1 to the OS.
|
||||||
|
function confpanic(s)
|
||||||
|
panic(string.format("%s: %s", bname(confpath), 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 = "envs.net",
|
||||||
|
-- username = "john",
|
||||||
|
-- password = "examplepassword
|
||||||
|
--}
|
||||||
|
|
||||||
|
-- You could also do it this way:
|
||||||
|
|
||||||
|
--login.server = "envs.net"
|
||||||
|
--login.username = "john"
|
||||||
|
--login.password = "examplepassword"
|
||||||
|
|
||||||
|
-- Both configurations do the same thing.
|
||||||
|
|
||||||
|
-- See matrix-send.conf(5) for more information
|
||||||
|
-- on configuration files.
|
||||||
|
]]
|
||||||
|
|
||||||
|
------------------------------------
|
||||||
|
--- Default configuration values ---
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
-- Initialise tables
|
||||||
|
login = {}
|
||||||
|
cache = {}
|
||||||
|
rooms = {}
|
||||||
|
advanced = {}
|
||||||
|
|
||||||
|
-- Cache location
|
||||||
|
cache.location = "~/.cache/matrix-send"
|
||||||
|
|
||||||
|
-- Disable caching access tokens?
|
||||||
|
cache.disable = false
|
||||||
|
|
||||||
|
-- Message type
|
||||||
|
advanced.event = "m.text"
|
||||||
|
|
||||||
|
----------------------
|
||||||
|
--- Initial checks ---
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
if arg[1] == nil then
|
||||||
|
io.stderr:write("usage: " .. bname(arg[0]) .. " [-c config] [-t type] [-CV] message room\n")
|
||||||
|
os.exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
if confvarv then
|
||||||
|
if fileexists(confvarv) then
|
||||||
|
confpath = os.getenv("MATRIXSEND_CONFIG")
|
||||||
|
else
|
||||||
|
local _, err = fileexists(os.getenv("MATRIXSEND_CONFIG"))
|
||||||
|
panic("error opening " .. err)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not fileexists(confpath) then
|
||||||
|
mkdir(confdir)
|
||||||
|
f = io.open(confpath, 'w')
|
||||||
|
f:write(default_config)
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
dofile(confpath)
|
||||||
|
|
||||||
|
cache.location = string.gsub(cache.location, '~', os.getenv("HOME"), 1)
|
||||||
|
|
||||||
|
-- Make sure all required values are set
|
||||||
|
if not login.server then
|
||||||
|
confpanic("required value 'login.server' left unset")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- login.token always supersedes login.username and password
|
||||||
|
if not login.token then
|
||||||
|
if not login.username then
|
||||||
|
confpanic("required value 'login.username' left unset")
|
||||||
|
elseif not login.password then
|
||||||
|
confpanic("required value 'login.password' left unset")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Parse options
|
||||||
|
for opt, optarg, ind in getopt(arg, ':Cc:t:V') do
|
||||||
|
optind = ind
|
||||||
|
if opt == 'C' then
|
||||||
|
msg("clearing cache")
|
||||||
|
os.execute("rm -rf " .. cache.location) -- TODO: replace this os.execute line
|
||||||
|
os.exit(0)
|
||||||
|
elseif opt == 'c' then
|
||||||
|
confpath = optarg
|
||||||
|
elseif opt == 't' then
|
||||||
|
if optarg:match("m%.text")
|
||||||
|
or optarg:match("m%.notice") then
|
||||||
|
advanced.event = optarg
|
||||||
|
else panic("unknown message type '" .. optarg .. "'")
|
||||||
|
end
|
||||||
|
elseif opt == 'V' then
|
||||||
|
io.stdout:write("matrix-send version " .. version .. '\n')
|
||||||
|
io.stdout:write(_VERSION .. '\n')
|
||||||
|
os.exit(0)
|
||||||
|
elseif opt == '?' then
|
||||||
|
panic("unknown option " .. arg[optind-1])
|
||||||
|
os.exit(1)
|
||||||
|
elseif opt == ':' then
|
||||||
|
panic("missing argument for option " .. arg[optind-1])
|
||||||
|
os.exit(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if optind == nil then
|
||||||
|
message = arg[1]
|
||||||
|
room = arg[2]
|
||||||
|
else
|
||||||
|
message = arg[optind+1]
|
||||||
|
room = arg[optind+2]
|
||||||
|
end
|
||||||
|
|
||||||
|
if room:match("^!") then
|
||||||
|
room_id = room
|
||||||
|
else
|
||||||
|
if rooms[room] ~= nil then
|
||||||
|
room_id = rooms[room]
|
||||||
|
else
|
||||||
|
panic("alias '" .. room .. "' invalid")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if fileexists(cache.location .. "/txnid") then
|
||||||
|
txnidf = io.open(cache.location .. "/txnid", 'r')
|
||||||
|
txnid = txnidf:read('l')
|
||||||
|
txnidf:close()
|
||||||
|
else
|
||||||
|
txnid = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 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)
|
||||||
|
|
||||||
|
json.message = string.format([[
|
||||||
|
{
|
||||||
|
"body": "%s",
|
||||||
|
"msgtype": "%s"
|
||||||
|
}
|
||||||
|
]], message, advanced.event)
|
||||||
|
|
||||||
|
-- Get the access token if credentials are used
|
||||||
|
if not login.token then
|
||||||
|
if fileexists(cache.location .. "/token") then
|
||||||
|
cf = io.open(cache.location .. "/token", 'r')
|
||||||
|
login.token = cf:read('l')
|
||||||
|
cf:close()
|
||||||
|
else
|
||||||
|
-- Login
|
||||||
|
login.token = matrix.login(uri.login, json.login)
|
||||||
|
|
||||||
|
-- Cache the access token
|
||||||
|
if not cache.disable then
|
||||||
|
mkdir(cache.location)
|
||||||
|
cf = io.open(cache.location .. "/token", 'w+')
|
||||||
|
cf:write(login.token)
|
||||||
|
cf:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
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!
|
||||||
|
matrix.send(uri.message, json.message, uri.login, json.login)
|
||||||
|
|
||||||
|
-- Increment txnid and cache
|
||||||
|
if not cache.disable then
|
||||||
|
txnidf = io.open(cache.location .. "/txnid", 'w+')
|
||||||
|
txnidf:write(txnid + 1)
|
||||||
|
txnidf:close()
|
||||||
|
end
|
Loading…
Add table
Add a link
Reference in a new issue