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')); // Set topic if it is different: $subject = Http::withToken(config('matrix.as_token')) ->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')) { $topic = Http::withToken(config('matrix.as_token')) ->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()]); } $msg = Http::withToken(config('matrix.as_token')) ->withQueryParameters(['user_id'=>$user]) ->post(sprintf('https://%s/_matrix/client/v3/rooms/%s/send/m.room.message',config('matrix.server'),$room),[ 'msgtype'=>'m.text', 'body'=>mb_convert_encoding(str_replace("\r","\n",$this->o->msg),'UTF-8','IBM850'), ]); 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 $msg = Http::withToken(config('matrix.as_token')) ->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 $msg = Http::withToken(config('matrix.as_token')) //->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 $msg = Http::withToken(config('matrix.as_token')) ->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(); } }