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>  | 
