User Tools

Site Tools


matrix_tools

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
matrix_tools [2020/05/28 23:54]
admin
matrix_tools [2023/12/27 13:45] (current)
admin old revision restored (2023/04/27 19:16)
Line 1: Line 1:
-====== Matrix Tools ====== +====== Matrix ​Command Line Tools ====== 
-It can be very simple to post a message to a channel ​on Matrix. + 
-==== Bash posting ​====+===== Git ===== 
 +You can [[https://​coding.openguide.co.uk/​gitweb/?​p=matrix-cli;​a=summary|view the repository]] or clone the code directory from my repository:​ 
 +<code bash> 
 +git clone https://​coding.openguide.co.uk/​git/​gemini-php/​ 
 +</​code>​ 
 + 
 + 
 +===== Documentation ===== 
 +  * https://​matrix.org/​docs/​api/​client-server/#/​ 
 +  * https://​matrix.org/​docs/​spec/​ 
 +===== Getting your access token ===== 
 +  * Using Riot (that'​s whats running on https://​matrix.glasgow.social) - Click on your profile name at the top left corner and select ''​Settings''​ 
 +  * Click ''​Help & About''​ from the list then scroll down to the '​Advanced'​ section. 
 +  * You should see the bottom line that reads ''​Access Token <click to reveal>''​ 
 +  * Copy and paste that into the example below 
 + 
 +===== Getting a room ID ===== 
 +  * Click on the three dots at the edge of a room name and click ''​Settings''​ 
 +  * Choose ''​Advanced''​ to see the ''​Internal Room ID''​ 
 +  * #glasgow on the server is ''​!BOrDFgeDdZZbUvfjjs:​glasgow.social''​ 
 + 
 +===== Posting messages to a room ===== 
 +It can be very simple to post a message to a room on Matrix ​(note: you have to be a member of the room)
 +==== Via bash/​curl ​====
 This script requires ''​jq'',​ the command line JSON processor. This script requires ''​jq'',​ the command line JSON processor.
 <code bash> <code bash>
Line 16: Line 39:
 access_token=put_your_user_access_token_here access_token=put_your_user_access_token_here
  
-curl -XPOST -d "$( jq -Rsc --arg msgtype "​$msgtype"​ '​{$msgtype,​ body:​.}'​)"​ "​https://​$homeserver/​_matrix/​client/​r0/​rooms/​$room/​send/​m.room.message?​access_token=$accesstoken"+curl -XPOST -d "$( jq -Rsc --arg msgtype "​$msgtype"​ '​{$msgtype,​ body:​.}'​)"​ "​https://​$homeserver/​_matrix/​client/​r0/​rooms/​$room/​send/​m.room.message?​access_token=$access_token"
 </​file>​ </​file>​
  
-==== PHP posting with Curl ====+==== PHP example using Curl ====
 <file php post_to_matrix.php>​ <file php post_to_matrix.php>​
 <?php <?php
Line 39: Line 62:
 ?> ?>
 </​file>​ </​file>​
 +
 +===== Listening to rooms =====
 +This is pretty straightforward. ​ This is just how to see messages that are posted, but if you explore what is returned then you can see all sorts of things too (like joins, images, likes, invites etc).  I run something like this on a terminal so I can see what's going on in all my rooms at a glance. ​ Very cool.
 +
 +<code php ListenToMatrix.php>​
 +<?php
 +$homeserver = "​glasgow.social";​
 +$access_token = "​access_token_goes_here";​
 +
 +// this is so you can start and stop the program, and it'll continue where it left off
 +$tracking_file "/​tmp/​listen_matrix.json";​
 +
 +while(true) {
 +$since = file_get_contents($tracking_file);​
 +$messages = get_new_events($since);​
 +if(!empty($messages['​rooms'​]['​join'​] and is_array($messages['​rooms'​]['​join'​]))) {
 +   ​foreach($messages['​rooms'​]['​join'​] as $room_id=>​$data) {
 +      foreach($data['​timeline'​]['​events'​] as $event_id=>​$event) {
 +         ​if($event['​type'​] == "​m.room.message"​) {
 +            $sender = $event['​sender'​];​
 +            $content = "not text";
 +            if($event['​content'​]['​msgtype'​] == "​m.text"​)
 +               ​$content = $event['​content'​]['​body'​];​
 +            echo "​$sender $room_id $content\n";​
 +         }
 +      }
 +   }
 +}
 +$new_tracking_data = $messages['​next_batch'​];​
 +file_put_contents($tracking_file,​ $new_tracking_data);​
 +}
 +
 +function get_new_events($since) {
 +   ​global $homeserver,​$access_token;​
 +   // timeout means the server will wait and only respond after 30 seconds, ​
 +   // however if a message is returned before that time, it will return immediately
 +   $url = "​https://​$homeserver/​_matrix/​client/​r0/​sync?​access_token=$access_token&​timeout=30000";​
 +   ​if(!empty($since))
 +      $url .= "&​since=$since";​
 +   $data = json_decode(file_get_contents($url),​ true);
 +   ​return $data;
 +}
 +
 +
 +?>
 +</​code>​
 +
 +You can follow one particular room just using GET requests, by doing something like this:
 +
 +<code php>
 +function get_new_events($room) {
 +   ​$homeserver = "​glasgow.social";​
 +   ​$access_token = "​access_token_goes_here"​
 +   $url = "​https://​$homeserver/​_matrix/​client/​r0/​rooms/​$room/​messages?​access_token=$access_token&​from=$tracking_id";​
 +   $data = json_decode(file_get_contents($url),​ true);
 +   ​return $data;
 +}
 +</​code>​
 +
 +===== Matrix Bot =====
 +The basis of my bot's interaction with Matrix is basically the above code.  Replace the echo line with with whatever you want to do (in my case, I look up a list of rules [i.e. pairs of regexes and their response functions] I use in IRC from a database and act accordingly). ​
 +
 +===== Posting images to a room =====
 +Media must first be uploaded to your homeserver, then you can send a new message, as above, using the ''​m.image''​ event type.  Here is an example in PHP that works as a '​copy'​ command.
 +<code php matrix_cp.php>​
 +#​!/​usr/​bin/​php
 +# Usage example: matrix_cp /​tmp/​test.jpg glasgow
 +# this will send the test.jpg to the glasgow room
 +# this also supports remote URLs
 +<?php
 +$usage = "​Usage:​ "​.$argv[0]."​ filename room_name alt_text[optional]\n";​
 +$filename = "";​
 +$room_name = "#​pythia";​
 +$alt_text = "Image attachment";​
 +$homeserver = "​glasgow.social";​
 +$access_token = "​access_token_goes_here"​
 +// I have a lookup list of friendly room names to full IDs here
 +$channels["​glasgow"​] = "​!BOrDFgeDdZZbUvfjjs:​glasgow.social";​
 +
 +if(!empty($argv[2]))
 +   ​$room_name = $argv[2];
 +if(!empty($argv[3]))
 +   ​$alt_text = $argv[3];
 +
 +$room = $channels[$room_name];​
 +if(empty($room))
 +   ​die($room_name."​ not in room list"​);​
 +
 +if(empty($argv[1]))
 +   ​die("​Filename is required. $usage"​);​
 +
 +$filename = $argv[1];
 +$image_data = file_get_contents($filename);​
 +
 +// this whole temporary file saving is all done to support mime_type lookups for remote URLs
 +$tmp_filename = "/​tmp/"​.md5($argv[0].time());​
 +
 +if(empty($image_data))
 +   ​die("​Unable to read file location"​);​
 +file_put_contents($tmp_filename,​ $image_data);​
 +$mime_type = mime_content_type($tmp_filename);​
 +
 +$url = "​https://​$homeserver/​_matrix/​media/​r0/​upload?​access_token=$access_token";​
 +$ch = curl_init($url);​
 +curl_setopt($ch,​ CURLOPT_RETURNTRANSFER,​ true);
 +curl_setopt($ch,​ CURLOPT_HTTPHEADER,​ array("​Content-Type:​ $mime_type"​));​
 +curl_setopt($ch,​ CURLOPT_POSTFIELDS,​ $image_data);​
 +$response = curl_exec($ch);​
 +
 +if(!empty($response_json['​content_uri'​])) {
 +      $url = "​https://​$homeserver/​_matrix/​client/​r0/​rooms/​$room/​send/​m.room.message?​access_token=$access_token";​
 +      $msgtype = "​m.image";​
 +      $mxc_url = $response_json['​content_uri'​];​
 +      $ch = curl_init($url);​
 +      $payload = json_encode(array("​msgtype"​=>​$msgtype,​ "​body"​=>​$alt_text,​ "​url"​=>​$mxc_url));​
 +      curl_setopt($ch,​ CURLOPT_RETURNTRANSFER,​ true);
 +      curl_setopt($ch,​ CURLOPT_POSTFIELDS,​ $payload);
 +      $response = curl_exec($ch);​
 +      // SUCCESS. ​ No output.
 +   } else {
 +      echo "Error uploading $filename. ";
 +      echo implode("​ : ", $response_json)."​\n";​
 +   }
 +</​code>​
 +
 +You can copy this file to your bin directory and use it on the command line with:
 +
 +<code bash>
 +matrix_cp /​tmp/​example.jpg glasgow "This is an example image"
 +</​code>​
 +
 +
matrix_tools.1590706451.txt.gz · Last modified: 2020/05/28 23:54 by admin