optimize startup and filter events

next_batch now is saved to account_data and retreived on the first start,
so we don't get already processed events during startup

additionally there now is a huge filter, which extracts only the
events+fields we really need. this prevents problems like e.g. account_data
feedback loops uneccessary syncs because ephemeral events
master
lub 5 years ago
parent 88e06c726f
commit 40932d41cb

@ -5,13 +5,19 @@ param (
[Parameter(Mandatory=$true)] [Parameter(Mandatory=$true)]
[string] [string]
$User, $UserId,
[Parameter(Mandatory=$true)] [Parameter(Mandatory=$true)]
[securestring] [securestring]
$AccessToken $AccessToken
) )
$account_data_type_prefix = 'de.lubiland.pingposh.'
$account_data_types = @{
next_batch = $account_data_type_prefix+'next_batch'
}
function Send-MatrixEvent { function Send-MatrixEvent {
param ( param (
[Parameter(Mandatory=$true)] [Parameter(Mandatory=$true)]
@ -174,7 +180,7 @@ function Join-Pong {
FormattedBody = $formatted_body FormattedBody = $formatted_body
} }
} }
function Open-MatrixEvent { function Open-Event {
param ( param (
[Parameter(Mandatory=$true)] [Parameter(Mandatory=$true)]
$Event, $Event,
@ -195,11 +201,75 @@ function Open-MatrixEvent {
Send-Pong -RoomId $RoomId @bodies -OriginHomeServer $origin_homeserver -Duration $difference.TotalMilliseconds -PingEventId $Event.event_id Send-Pong -RoomId $RoomId @bodies -OriginHomeServer $origin_homeserver -Duration $difference.TotalMilliseconds -PingEventId $Event.event_id
} }
} }
function Start-MatrixSync { function Get-MatrixAccountData {
param (
[Parameter(Mandatory=$true)]
[string]
$Type
)
$uri = '{0}/_matrix/client/r0/user/{1}/account_data/{2}' -f $HomeServer,$UserId,$Type
$header_splat = @{
Authentication = 'Bearer'
Token = $AccessToken
ContentType = 'application/json'
}
$http_splat = @{
Uri = $uri
Method = 'Get'
}
$response = Invoke-RestMethod @header_splat @http_splat
return $response
}
function Set-MatrixAccountData {
param (
[Parameter(Mandatory=$true)]
[string]
$Type,
[Parameter(Mandatory=$true)]
[System.Object]
$Content
)
$uri = '{0}/_matrix/client/r0/user/{1}/account_data/{2}' -f $HomeServer,$UserId,$Type
$header_splat = @{
Authentication = 'Bearer'
Token = $AccessToken
ContentType = 'application/json'
}
$http_splat = @{
Uri = $uri
Method = 'Put'
Body = $Content | ConvertTo-Json -Compress
}
Invoke-RestMethod @header_splat @http_splat | Out-Null
}
function Get-NextBatchToken {
$account_data = Get-MatrixAccountData -Type $account_data_types.next_batch
return $account_data.next_batch
}
function Set-NextBatchToken {
param (
[Parameter(Mandatory=$true)]
[string]
$Token
)
Set-MatrixAccountData -Type $account_data_types.next_batch -Content @{next_batch = $Token}
}
function Invoke-MatrixSync {
param ( param (
[string] [string]
$Token, $Token,
[string]
$FilterId,
[int] [int]
$Timeout = 30000 $Timeout = 30000
) )
@ -208,6 +278,9 @@ function Start-MatrixSync {
if($Token) { if($Token) {
$uri += '&since={0}' -f $Token $uri += '&since={0}' -f $Token
} }
if($FilterId) {
$uri += '&filter={0}' -f $FilterId
}
$header_splat = @{ $header_splat = @{
Authentication = 'Bearer' Authentication = 'Bearer'
@ -225,17 +298,105 @@ function Start-MatrixSync {
foreach($room_id in $room_ids) { foreach($room_id in $room_ids) {
$events = $response.rooms.join.$room_id.timeline.events $events = $response.rooms.join.$room_id.timeline.events
foreach($event in $events) { foreach($event in $events) {
Open-MatrixEvent -Event $event -RoomId $room_id Open-Event -Event $event -RoomId $room_id
} }
} }
Write-Output $response.next_batch return $response.next_batch
}
function Get-MatrixFilterId {
param (
[System.Object]
$Filter
)
$uri = '{0}/_matrix/client/r0/user/{1}/filter' -f $HomeServer,$UserId
$header_splat = @{
Authentication = 'Bearer'
Token = $AccessToken
ContentType = 'application/json'
}
$http_splat = @{
Uri = $uri
Method = 'Post'
#a filter can be up to 3 layers deep according to spec
#https://matrix.org/docs/spec/client_server/r0.6.0#filtering
Body = $Filter | ConvertTo-Json -Compress -Depth 3
}
$response = Invoke-RestMethod @header_splat @http_splat
return $response.filter_id
}
function Get-FilterId {
$filter = @{
event_fields = @(
#all fields used in Open-Event
'event_id'
'sender'
'origin_server_ts'
'content.msgtype'
'content.body'
)
presence = @{
#we don't use presence information
types = @('invalid')
}
account_data = @{
#we only retrieve account_data via the account_data api endpoint
types = @('invalid')
}
room = @{
ephemeral = @{
#we don't use ephemeral events like typing or read receipts
types = @('invalid')
}
state = @{
#we don't use room state
types = @('invalid')
}
timeline = @{
#exclude ourself
not_senders = @(
$UserId
)
types = @(
#to receive !ping commands
'm.room.message'
)
}
account_data = @{
#we don't use room specific account_data
types = @('invalid')
}
}
}
$filter_id = Get-MatrixFilterId -Filter $filter
return $filter_id
}
function Start-MatrixSync {
#get last used next_batch from account_data
$token = Get-NextBatchToken
#get /sync filter
$filter_id = Get-FilterId
Try {
#try first sync with the old token
$token = Invoke-MatrixSync -Token $token -FilterId $filter_id
} Catch {
#if it fails start a fresh sync reset $token
$token = $null
}
while($true) {
#use $token of the previous sync
Set-NextBatchToken -Token $token
$token = Invoke-MatrixSync -Token $token -FilterId $filter_id
}
} }
#start sync loop Start-MatrixSync
while($true) {
#use the token of the last sync
#initial token is $null
$token = Start-MatrixSync -Token $token
}
Loading…
Cancel
Save