summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2019-05-06 16:59:48 +0200
committerDaniel Friesel <derf@finalrewind.org>2019-05-06 16:59:48 +0200
commit2ddab756440333fb42a9813df87b978a82e490d2 (patch)
tree6ead34dc431e564d1570718b741dd9652322b317
parentb36ba45aef6ce3a62079064a900915a9e222acde (diff)
basic webhook support, onwards to betatesting
-rwxr-xr-xlib/Travelynx.pm84
-rw-r--r--lib/Travelynx/Controller/Account.pm1
-rwxr-xr-xlib/Travelynx/Controller/Api.pm65
-rw-r--r--templates/webhooks.html.ep35
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>