diff options
author | Daniel Friesel <derf@finalrewind.org> | 2019-05-06 16:59:48 +0200 |
---|---|---|
committer | Daniel Friesel <derf@finalrewind.org> | 2019-05-06 16:59:48 +0200 |
commit | 2ddab756440333fb42a9813df87b978a82e490d2 (patch) | |
tree | 6ead34dc431e564d1570718b741dd9652322b317 | |
parent | b36ba45aef6ce3a62079064a900915a9e222acde (diff) |
basic webhook support, onwards to betatesting
-rwxr-xr-x | lib/Travelynx.pm | 84 | ||||
-rw-r--r-- | lib/Travelynx/Controller/Account.pm | 1 | ||||
-rwxr-xr-x | lib/Travelynx/Controller/Api.pm | 65 | ||||
-rw-r--r-- | templates/webhooks.html.ep | 35 |
4 files changed, 106 insertions, 79 deletions
diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm index f058eee..51fe1a2 100755 --- a/lib/Travelynx.pm +++ b/lib/Travelynx.pm @@ -574,9 +574,10 @@ sub startup { } if ( $has_arrived or $force ) { - return ( 0, undef ); $self->run_hook( $uid, 'checkout' ); + return ( 0, undef ); } + $self->run_hook( $uid, 'update' ); return ( 1, undef ); } ); @@ -1009,6 +1010,10 @@ sub startup { $opt{uid} //= $self->current_user->{id}; + if ( $opt{token} ) { + $opt{token} =~ tr{\r\n}{}d; + } + my $res = $self->pg->db->insert( 'webhooks', { @@ -1029,8 +1034,8 @@ sub startup { 'mark_hook_status' => sub { my ( $self, $uid, $url, $success, $text ) = @_; - if ( length($text) > 1024 ) { - $text = "(output too long)"; + if ( length($text) > 1000 ) { + $text = substr( $text, 0, 1000 ) . '…'; } $self->pg->db->update( @@ -1059,7 +1064,7 @@ sub startup { return; } - my $status = { todo => 1 }; + my $status = $self->get_user_status_json_v1($uid); my $header = {}; my $hook_body = { reason => $reason, @@ -1067,7 +1072,6 @@ sub startup { }; if ( $hook->{token} ) { - $hook->{token} =~ tr{\r\n}{}d; $header->{Authorization} = "Bearer $hook->{token}"; } @@ -1700,6 +1704,76 @@ sub startup { ); $self->helper( + 'get_user_status_json_v1' => sub { + my ( $self, $uid ) = @_; + my $status = $self->get_user_status($uid); + + my $ret = { + deprecated => \0, + checkedIn => ( + $status->{checked_in} + or $status->{cancelled} + ) ? \1 : \0, + fromStation => { + ds100 => $status->{dep_ds100}, + name => $status->{dep_name}, + uic => undef, + longitude => undef, + latitude => undef, + scheduledTime => $status->{sched_departure}->epoch || undef, + realTime => $status->{real_departure}->epoch || undef, + }, + toStation => { + ds100 => $status->{arr_ds100}, + name => $status->{arr_name}, + uic => undef, + longitude => undef, + latitude => undef, + scheduledTime => $status->{sched_arrival}->epoch || undef, + realTime => $status->{real_arrival}->epoch || undef, + }, + train => { + type => $status->{train_type}, + line => $status->{train_line}, + no => $status->{train_no}, + id => $status->{train_id}, + }, + actionTime => $status->{timestamp}->epoch, + }; + + if ( $status->{dep_ds100} ) { + my @station_descriptions + = Travel::Status::DE::IRIS::Stations::get_station( + $status->{dep_ds100} ); + if ( @station_descriptions == 1 ) { + ( + undef, undef, + $ret->{fromStation}{uic}, + $ret->{fromStation}{longitude}, + $ret->{fromStation}{latitude} + ) = @{ $station_descriptions[0] }; + } + } + + if ( $status->{arr_ds100} ) { + my @station_descriptions + = Travel::Status::DE::IRIS::Stations::get_station( + $status->{arr_ds100} ); + if ( @station_descriptions == 1 ) { + ( + undef, undef, + $ret->{toStation}{uic}, + $ret->{toStation}{longitude}, + $ret->{toStation}{latitude} + ) = @{ $station_descriptions[0] }; + } + } + + return $ret; + } + ); + + $self->helper( 'get_travel_distance' => sub { my ( $self, $from, $to, $route_ref ) = @_; diff --git a/lib/Travelynx/Controller/Account.pm b/lib/Travelynx/Controller/Account.pm index 75b8f02..c02fb1a 100644 --- a/lib/Travelynx/Controller/Account.pm +++ b/lib/Travelynx/Controller/Account.pm @@ -244,6 +244,7 @@ sub webhook { token => $hook->{token}, enabled => $hook->{enabled} ); + $self->run_hook( $self->current_user->{id}, 'ping' ); $hook = $self->get_webhook; } else { diff --git a/lib/Travelynx/Controller/Api.pm b/lib/Travelynx/Controller/Api.pm index b0047b9..a442784 100755 --- a/lib/Travelynx/Controller/Api.pm +++ b/lib/Travelynx/Controller/Api.pm @@ -142,70 +142,7 @@ sub get_v1 { return; } if ( $api_action eq 'status' ) { - my $status = $self->get_user_status($uid); - - my $ret = { - deprecated => \0, - checkedIn => ( - $status->{checked_in} - or $status->{cancelled} - ) ? \1 : \0, - fromStation => { - ds100 => $status->{dep_ds100}, - name => $status->{dep_name}, - uic => undef, - longitude => undef, - latitude => undef, - scheduledTime => $status->{sched_departure}->epoch || undef, - realTime => $status->{real_departure}->epoch || undef, - }, - toStation => { - ds100 => $status->{arr_ds100}, - name => $status->{arr_name}, - uic => undef, - longitude => undef, - latitude => undef, - scheduledTime => $status->{sched_arrival}->epoch || undef, - realTime => $status->{real_arrival}->epoch || undef, - }, - train => { - type => $status->{train_type}, - line => $status->{train_line}, - no => $status->{train_no}, - id => $status->{train_id}, - }, - actionTime => $status->{timestamp}->epoch, - }; - - if ( $status->{dep_ds100} ) { - my @station_descriptions - = Travel::Status::DE::IRIS::Stations::get_station( - $status->{dep_ds100} ); - if ( @station_descriptions == 1 ) { - ( - undef, undef, - $ret->{fromStation}{uic}, - $ret->{fromStation}{longitude}, - $ret->{fromStation}{latitude} - ) = @{ $station_descriptions[0] }; - } - } - - if ( $status->{arr_ds100} ) { - my @station_descriptions - = Travel::Status::DE::IRIS::Stations::get_station( - $status->{arr_ds100} ); - if ( @station_descriptions == 1 ) { - ( - undef, undef, - $ret->{toStation}{uic}, - $ret->{toStation}{longitude}, - $ret->{toStation}{latitude} - ) = @{ $station_descriptions[0] }; - } - } - - $self->render( json => $ret ); + $self->render( json => $self->get_user_status_json_v1($uid) ); } else { $self->render( diff --git a/templates/webhooks.html.ep b/templates/webhooks.html.ep index fec485d..0bf8cc8 100644 --- a/templates/webhooks.html.ep +++ b/templates/webhooks.html.ep @@ -8,14 +8,9 @@ <div class="row"> <div class="col s12"> <p> - Die im Web Hook konfigurierte URL wird bei jedem Checkin und Checkout - des ausgewählten Zuges aufgerufen. Falls ein Token eingetragen - ist, wird er als Bearer Token verwendet. - </p> - <p> - Events werden als JSON POST übertragen. Das JSON-Dokument besteht aus - zwei Feldern: „reason“ gibt den Grund des API-Aufrufs an (checkin, - checkout, undo), „status“ den <a href="/api">aktuellen Status</a>. + Die im Web Hook konfigurierte URL wird bei Änderungen des aktuellen + Reisestatus (z.B. Checkin oder Ankunft am Ziel) aufgerufen. Falls ein + Token eingetragen ist, wird er als Bearer Token verwendet. </p> </div> %= form_for '/account/hooks' => (method => 'POST') => begin @@ -28,7 +23,7 @@ </div> <div class="input-field col s12"> <i class="material-icons prefix">link</i> - %= text_field 'url', id => 'url', class => 'validate', maxlength => 1000 + %= text_field 'url', id => 'url', class => 'validate', pattern => 'https?://.+', maxlength => 1000 <label for="url">URL</label> </div> <div class="input-field col s12"> @@ -38,7 +33,7 @@ </div> <div class="col s12"> % if ($hook->{latest_run}->epoch) { - Zuletzt ausgeführt: <%= $hook->{latest_run} %><br/> + Zuletzt ausgeführt <%= $hook->{latest_run}->strftime('am %d.%m.%Y um %H:%M:%S') %><br/> % if ($hook->{errored}) { <i class="material-icons left">error</i> Status: <%= $hook->{output} %> @@ -59,4 +54,24 @@ </button> </div> %= end + <div class="col s12"> + <p>Events werden als JSON POST mit folgender Payload übertragen.</p> + <p style="font-family: Monospace;"> + {<br/> + "reason" : "Grund für den Webhook-Aufruf",<br/> + "status" : { <a href="/api">Aktueller Nutzerstatus</a> }<br/> + }<br/> + </p> + <p> + Gültige Werte für reason sind derzeit: + <ul> + <li><b>ping</b> (nach jeder gespeicherten Änderung in diesem Formular)</li> + <li><b>checkin</b> (in einen Zug eingecheckt – Zielstation ist noch nicht bekannt)</li> + <li><b>update</b> (eingecheckt und Ziel gewählt oder geändert)</li> + <li><b>checkout</b> (aus einem Zug ausgecheckt)</li> + <li><b>undo</b> (checkin oder checkout wurde rückgängig gemacht)</li> + </ul> + Falls der Zug das Ziel bei der Zielwahl schon erreicht hat, wird ohne + <b>update</b> direkt ein <b>checkout</b> abgeschickt. + </p> </div> |