2024-06-11 04:17:03 +00:00
< ? php
namespace App\Notifications\Matrix ;
use Illuminate\Support\Facades\Http ;
use Illuminate\Support\Facades\Log ;
use App\Models\Echomail as EchomailModel ;
use App\Notifications\Matrix ;
class Echomail extends Matrix
{
private const LOGKEY = 'NME' ;
/**
* Post a message from Matrix .
*
* @ param EchomailModel $o
*/
public function __construct ( private EchomailModel $o )
{
parent :: __construct ();
}
/**
* Get the mail representation of the notification .
*
* @ param mixed $notifiable
* @ return mixed
* @ throws \Exception
*/
public function toMatrix ( object $notifiable ) : mixed
{
$room = $notifiable -> routeNotificationFor ( static :: via );
Log :: info ( sprintf ( '%s:+ Sending Echo Message to Matrix [%s]' , self :: LOGKEY , $room ));
$username = sprintf ( '%s^%d_%d/%d.%d' ,
$this -> o -> from ,
$this -> o -> fftn -> zone -> zone_id ,
$this -> o -> fftn -> host_id ,
$this -> o -> fftn -> node_id ,
$this -> o -> fftn -> point_id ,
);
$user = sprintf ( '@%s:%s' , $username , config ( 'matrix.server' ));
2024-11-01 02:01:55 +00:00
// @todo We need to force IP4 as running clrghouz in a container without a proper IPv6 address is problematic
$matrix = Http :: withToken ( config ( 'matrix.as_token' ))
-> withOptions ([
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4 ,
]);
2024-06-11 04:17:03 +00:00
// Set topic if it is different:
2024-11-01 02:01:55 +00:00
$subject = $matrix
2024-06-11 04:17:03 +00:00
-> get ( sprintf ( 'https://%s/_matrix/client/v3/rooms/%s/state/m.room.topic' , config ( 'matrix.server' ), $room ));
if (( $x = preg_replace ( '/^RE:\s*/i' , '' , $this -> o -> subject )) !== $subject -> json ( 'topic' , 'Message from Matrix' )) {
2024-11-01 02:01:55 +00:00
$topic = $matrix
2024-06-11 04:17:03 +00:00
-> put ( sprintf ( 'https://%s/_matrix/client/v3/rooms/%s/state/m.room.topic' , config ( 'matrix.server' ), $room ),[
'topic' => $x ,
]);
if ( $topic -> status () !== 200 )
Log :: error ( sprintf ( '%s:! Failed to set matrix room topic to [%s] in room [%s]' , self :: LOGKEY , $x , $room ),[ 'msg' => $topic -> body ()]);
}
2024-09-09 10:29:17 +00:00
$omsg = preg_replace ( " / \r ---.* $ /U " , '' , $this -> o -> msg );
2024-11-01 02:01:55 +00:00
$msg = $matrix
2024-06-11 04:17:03 +00:00
-> withQueryParameters ([ 'user_id' => $user ])
-> post ( sprintf ( 'https://%s/_matrix/client/v3/rooms/%s/send/m.room.message' , config ( 'matrix.server' ), $room ),[
'msgtype' => 'm.text' ,
2024-09-08 04:18:28 +00:00
'format' => 'org.matrix.custom.html' ,
2024-09-09 10:29:17 +00:00
'body' => mb_convert_encoding ( str_replace ( " \r " , " \n " , $omsg ), 'UTF-8' , 'IBM850' ),
'formatted_body' => sprintf ( " <pre> \n %s \n </pre> " , mb_convert_encoding ( str_replace ( " \r " , " \n " , $omsg ), 'UTF-8' , 'IBM850' )),
2024-06-11 04:17:03 +00:00
]);
switch ( $msg -> status ()) {
case 200 :
break ;
case 403 :
Log :: alert ( sprintf ( '%s:! Got 403 with errcode [%s] reason [%s]' , self :: LOGKEY , $msg -> json ( 'errcode' ), $msg -> json ( 'error' )));
// @todo Test that the user doesnt exist
// If the user doesnt exist in matrix yet
if ( str_starts_with ( $msg -> json ( 'error' ), 'Application service has not registered this user' )) {
// Register user
2024-11-01 02:01:55 +00:00
$msg = $matrix
2024-06-11 04:17:03 +00:00
-> post ( sprintf ( 'https://%s/_matrix/client/v3/register' , config ( 'matrix.server' )),[
'type' => 'm.login.application_service' ,
'username' => $username ,
]);
if ( $msg -> status () !== 200 ) {
Log :: error ( sprintf ( '%s:! Failed to register user [%s] to matrix' , self :: LOGKEY , $username ),[ 'msg' => $msg -> body ()]);
throw new \Exception ( sprintf ( 'Failed to invite user [%s] to matrix' , $username ));
}
// @todo Test that the user has been invited
// Invite user
2024-11-01 02:01:55 +00:00
$msg = $matrix
2024-06-11 04:17:03 +00:00
//->withQueryParameters(['user_id'=>$user])
-> post ( sprintf ( 'https://%s/_matrix/client/v3/rooms/%s/invite' , config ( 'matrix.server' ), $room ),[
'user_id' => $user ,
]);
if ( $msg -> status () !== 200 ) {
Log :: error ( sprintf ( '%s:! Failed to invite user [%s] to matrix room [%s]' , self :: LOGKEY , $user , $room ),[ 'msg' => $msg -> body ()]);
throw new \Exception ( sprintf ( 'Failed to invite user [%s] to matrix room [%s]' , $user , $room ));
}
// Join as user
2024-11-01 02:01:55 +00:00
$msg = $matrix
2024-06-11 04:17:03 +00:00
-> withQueryParameters ([ 'user_id' => $user ])
-> post ( sprintf ( 'https://%s/_matrix/client/v3/rooms/%s/join' , config ( 'matrix.server' ), $room ),[
'user_id' => $user ,
]);
if ( $msg -> status () !== 200 ) {
Log :: error ( sprintf ( '%s:! Failed to join user [%s] to matrix room [%s]' , self :: LOGKEY , $user , $room ),[ 'msg' => $msg -> body ()]);
throw new \Exception ( sprintf ( 'Failed to join user [%s] to matrix room [%s]' , $user , $room ));
}
// retry this message
throw new \Exception ( 'Need to create user on matrix first' );
}
break ;
default :
Log :: error ( sprintf ( '%s:! Unknown status [%d] with errcode [%s] reason [%s] when posting message [%d] to matrix' , self :: LOGKEY , $msg -> status (), $msg -> json ( 'errcode' ), $msg -> json ( 'error' ), $this -> o -> id ),[ 'msg' => $msg -> body ()]);
}
return $msg -> body ();
}
}