|
<?php |
|
/* |
|
// [GitHub](https://github.com/) からの [Webhooks](https://developer.github.com/webhooks/) を受けて、 |
|
// 自分のサーバー上ディレクトリ下(例では https://<ドメイン名>/userjs)の配信用ユーザースクリプトを更新するサンプル |
|
*/ |
|
|
|
// === User settings { |
|
|
|
date_default_timezone_set( 'Asia/Tokyo' ); |
|
|
|
const DEBUG_FLAG = TRUE; // ■デバッグフラグ(※動作確認が済んだら FALSE に変えること) |
|
const SECRET_KEY = '<your-secret-key>'; // ■シークレットキー(※GitHub側 の Secret にも同じものを登録すること) |
|
|
|
$LOG_FILE = dirname( __FILE__ ) . '/log/github.log'; |
|
|
|
$USERJS_PATH_MAP = array( |
|
//■ レジストリ内のユーザースクリプトの場所を登録 |
|
//'<user-name>/<registory-name>' => array( |
|
// 'path/to/userscript.user.js', |
|
// // : |
|
// ), |
|
// : |
|
// |
|
//【設定例】 |
|
// [レジストリ](https://github.com/furyutei/twMediaDownloader) |
|
// [対象となるユーザースクリプトの場所](https://github.com/furyutei/twMediaDownloader/blob/master/src/js/twMediaDownloader.user.js) |
|
// の場合 |
|
//'furyutei/twMediaDownloader' => array( |
|
// 'src/js/twMediaDownloader.user.js', |
|
// ), |
|
); |
|
|
|
// } |
|
|
|
|
|
|
|
// === Main processing { |
|
|
|
main(); |
|
|
|
// } |
|
|
|
|
|
|
|
// === Functions { |
|
|
|
function main() { |
|
global $USERJS_PATH_MAP; |
|
|
|
header( 'Content-Type: text/plain; charset=utf-8' ); |
|
|
|
$payload = get_webhook_payload(); |
|
|
|
if ( @$payload[ 'error' ] ) { |
|
set_status( 401 ); |
|
return; |
|
} |
|
|
|
$ref = @$payload[ 'ref' ] ?: ''; |
|
$repository = @$payload[ 'repository' ] ?: array(); |
|
$master_branch_name = @$repository[ 'master_branch' ]; |
|
|
|
write_log_debug( "ref: '{$ref}', master_branch_name: '{$master_branch_name}'" ); |
|
|
|
if ( $ref ) { |
|
// 'refs/heads/<branch_name>' |
|
list( $dir1, $dir2, $branch_name ) = explode( '/', $ref, 3 ) + array( '', '', '' ); |
|
|
|
if ( $master_branch_name !== $branch_name ) { |
|
set_status( 200 ); |
|
write_log( "Note: '{$branch_name}' is not master branch" ); |
|
return; |
|
} |
|
} |
|
|
|
$full_name = @$repository[ 'full_name' ]; |
|
$html_url = @$repository[ 'html_url' ]; |
|
$owner = @$repository[ 'owner' ][ 'login' ]; |
|
|
|
$userjs_list = @$USERJS_PATH_MAP[ $full_name ]; |
|
|
|
if ( ( ! $userjs_list ) || ( ! $html_url ) || ( ! $owner ) ) { |
|
set_status( 400 ); |
|
return; |
|
} |
|
|
|
$output_dir = realpath( $_SERVER[ 'DOCUMENT_ROOT' ] . '/userjs' ) . '/' . $owner; |
|
write_log_debug( "output_dir: {$output_dir}" ); |
|
|
|
if ( ( ! file_exists( $output_dir ) ) && ( ! mkdir( $output_dir, 0777, TRUE ) ) ) { |
|
set_status( 500 ); |
|
write_log( "Error: Failed to create directory: {$output_dir}" ); |
|
return; |
|
} |
|
|
|
foreach( $userjs_list as $userjs_path ) { |
|
$userjs_url = "{$html_url}/raw/master/{$userjs_path}"; |
|
$userjs_filepath = $output_dir . '/' . basename( $userjs_path ); |
|
|
|
write_log( "Source URL: {$userjs_url}" ); |
|
write_log( "Destination file: {$userjs_filepath}" ); |
|
|
|
file_put_contents( $userjs_filepath, file_get_contents( $userjs_url ) ); |
|
} |
|
set_status( 200 ); |
|
} // end of main() |
|
|
|
|
|
function is_debug_mode() { |
|
return ( defined( 'DEBUG_FLAG' ) && DEBUG_FLAG ); |
|
} // end of is_debug_mode() |
|
|
|
|
|
function write_log_debug( $message ) { |
|
if ( ! is_debug_mode() ) { |
|
return; |
|
} |
|
|
|
write_log( $message ); |
|
} // end of write_log_debug() |
|
|
|
|
|
function write_log( $message ) { |
|
global $LOG_FILE; |
|
|
|
$remote_addr = @$_SERVER[ 'REMOTE_ADDR' ] ?: '(localhost)'; |
|
$log_message = date( 'Y-m-d H:i:s' ) . ' [' . $remote_addr . '] ' . $message . "\n"; |
|
|
|
file_put_contents( $LOG_FILE, $log_message, FILE_APPEND | LOCK_EX ); |
|
} // end of write_log() |
|
|
|
|
|
function set_status( $status_code ) { |
|
http_response_code( $status_code ); |
|
|
|
if ( ( 200 <= $status_code ) && ( $status_code < 300 ) ) { |
|
echo( 'OK' ); |
|
} |
|
else { |
|
echo( 'NG' ); |
|
} |
|
} // end of set_status() |
|
|
|
|
|
function get_webhook_payload() { |
|
$payload_body = file_get_contents( 'php://input' ); |
|
|
|
if ( ! is_correct_signature( $payload_body ) ) { |
|
write_log( 'Error: Incorrect signature' ); |
|
return array( |
|
'error' => TRUE |
|
); |
|
} |
|
|
|
$payload_string = @$_POST[ 'payload' ] ?: $payload_body; |
|
|
|
$payload = json_decode( $payload_string, TRUE ); |
|
|
|
if ( ( $payload === NULL ) && ( json_last_error() !== JSON_ERROR_NONE ) ) { |
|
write_log( 'Error: Incorrect payload' ); |
|
return array( |
|
'error' => TRUE |
|
); |
|
} |
|
|
|
if ( is_debug_mode() ) { |
|
write_log( '--------------------' ); |
|
ob_start(); |
|
var_export( $payload ); |
|
write_log( "[payload]\n" . ob_get_contents() ); |
|
ob_end_clean(); |
|
write_log( '--------------------' ); |
|
} |
|
|
|
return @$payload ?: array(); |
|
} // end of get_webhook_payload() |
|
|
|
|
|
function is_correct_signature( $payload_body ) { |
|
if ( ( ! defined( 'SECRET_KEY' ) ) || ( ! SECRET_KEY ) ) { |
|
return TRUE; |
|
} |
|
|
|
$signature = @$_SERVER[ 'HTTP_X_HUB_SIGNATURE' ] ?: NULL; |
|
|
|
if ( ! $signature ) { |
|
return FALSE; |
|
} |
|
|
|
list( $algo, $hash ) = explode( '=', $signature, 2 ) + array( '', '' ); |
|
|
|
if ( ! in_array( $algo, hash_algos(), TRUE ) ) { |
|
return FALSE; |
|
} |
|
|
|
$hash_calc = hash_hmac( $algo, $payload_body, SECRET_KEY ); |
|
|
|
if ( $hash !== $hash ) { |
|
return FALSE; |
|
} |
|
|
|
return TRUE; |
|
} // end of is_correct_signature() |
|
|
|
|
|
// } |
|
|
|
// end of file |