User Tools

Site Tools


projects:owncastmatrix

This is an old revision of the document!


Owncast/Matrix

I run this code to link an Owncast chat to a Matrix room. It's designed to be temporary (you just run it from the command line) but it would be easy to modify to always be searching for when a stream starts. I've seperated out the Owncast-to-Matrix and Matrix-to-Owncast components so you can choose which one you want (or run both). OwncastToMatrix uses my very simple Matrix PHP Class but MatrixToOwncast doesn't require it.

OwncastToMatrix.php
<?php
$url = "URL_TO_OWNCAST_WEBSERVER";
$token = "YOUR_TOKEN_HERE"; // you may have to manually escape hypens with a backslash
$tracker_file = "/tmp/owncast_to_matrix.json"; // tracks which messages have been sent to Matrix already
if(file_exists($tracker_file))
   $tracker = json_decode(file_get_contents($tracker_file), true);
 
$endpoint = "/api/chat";
 
require("matrix.class.php");
 
while(true) {
   $data = json_decode(file_get_contents($url.$endpoint), true);
   $last_slice = array_slice($data, -20);
 
   foreach($last_slice as $line) {
      if($line['type'] == "CHAT") {
         if(!array_key_exists($line['id'], $tracker)) {
            $str = "<Owncast: ".$line['author']."> ".htmlspecialchars_decode(strip_tags($line['body']));
            $tracker[$line['id']] = strip_tags($line['body']);
            if(!empty($str)) {
               $mat = new matrix();
               $room = "#geek";
               $mat->post($str, $room);
            }
         }
      }
   }
   file_put_contents($tracker_file, json_encode($tracker));
   sleep(20);
}
MatrixToOwncast.php
<?php
function get_new_events($room) {
   $tracking_file = "/tmp/listen_matrix_owncast.json";
   $since = file_get_contents($tracking_file);
   if(empty($since))
      $since = "s1022334_0_0_0_0_0_0_0_0";
   $homeserver = "matrix.homeserver.com";
   $access_token = "YOUR_MATRIX_ACCESS_TOKEN HERE";
   $url = "https://$homeserver/_matrix/client/r0/rooms/$room/messages?access_token=$access_token&from=$since";
   $data = json_decode(file_get_contents($url), true);
   $new_tracking_data = $data['end'];
   file_put_contents($tracking_file, $new_tracking_data);
   return $data;
}
 
$room_id = "!room_id:homeserver";
 
while(true) {
$data = get_new_events($room_id);
 
if(is_array($data['chunk']) and sizeof($data['chunk'])>0) {
   foreach($data['chunk'] as $message) {
      if($message['sender'] != '@adelaide:glasgow.social') {
         if($message['content']['msgtype'] == "m.text") {
            if(!empty($message['content']['body'])) {
               $nick_parts = explode(":", $message['sender']);
               $relay = "[".substr($nick_parts[0],1)."] ".$message['content']['body'];
               echo $relay."\n";
               send_owncast_system_message($relay);
            }
         }
      }
   }
}
 
sleep(10);
}
 
 
function send_owncast_system_message($str) {
   if(empty($str))
      return false;
   $url = "http://owncast_server.com";
   $access_token = "YOUR_OWNCAST_ACCESS_TOKEN_HERE"; // you may have to escape hyphens with a backslash
 
   $endpoint = "/api/integrations/chat/system";
 
   $post = array("body" => $str);
   $auth = "Authorization: Bearer $access_token";
 
   $ch = curl_init($url.$endpoint);
   $headers = array("Content-Type: application/json",
                 $auth);
   curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
   curl_setopt($ch, CURLOPT_POSTFIELDS,json_encode($post));
   $result = curl_exec($ch);
   curl_close($ch);
}

Then just run them on the command line with something like:

php OwncastToMatrix.php &
php MatrixToOwncast.php
projects/owncastmatrix.1617825449.txt.gz · Last modified: 2021/04/07 20:57 by admin