Skip to content

Instantly share code, notes, and snippets.

@AtsushiA
Last active May 24, 2025 11:12
Show Gist options
  • Select an option

  • Save AtsushiA/b2f17a7f8b062dc55daad6b309940101 to your computer and use it in GitHub Desktop.

Select an option

Save AtsushiA/b2f17a7f8b062dc55daad6b309940101 to your computer and use it in GitHub Desktop.
Convert Webhook (Backlog git to deployhq)
<?php
/**
* BacklogのWebhookを受信して指定形式で転送するスクリプト
* 転送先URLをGETパラメータで指定
* https://yourserver.com/webhook.php?url=https://destination-webhook.com/endpoint
*
* 転送先URLをPOSTパラメータで指定(BacklogのWebhook設定でurlパラメータを追加)
* POST /webhook.php
* Content-Type: application/x-www-form-urlencoded
* payload=...&url=https://destination-webhook.com/endpoint
*/
// Content-Typeの設定
header('Content-Type: application/json; charset=utf-8');
try {
// 転送先URLを取得(GETパラメータまたはPOSTパラメータから)
$FORWARD_WEBHOOK_URL = $_GET['url'] ?? $_POST['url'] ?? '';
if (empty($FORWARD_WEBHOOK_URL)) {
http_response_code(400);
echo json_encode(['error' => 'Forward URL is required. Please provide "url" parameter.']);
exit;
}
// URLの形式をチェック
if (!filter_var($FORWARD_WEBHOOK_URL, FILTER_VALIDATE_URL)) {
http_response_code(400);
echo json_encode(['error' => 'Invalid URL format']);
exit;
}
// POSTデータの取得
$raw_input = file_get_contents('php://input');
// URLエンコードされたデータをパース
parse_str($raw_input, $parsed_data);
// payloadが存在するかチェック
if (!isset($parsed_data['payload'])) {
http_response_code(400);
echo json_encode(['error' => 'payload not found']);
exit;
}
// JSONデコード
$payload = json_decode($parsed_data['payload'], true);
if ($payload === null) {
http_response_code(400);
echo json_encode(['error' => 'Invalid JSON in payload']);
exit;
}
// 必要なデータを抽出
$repository = $payload['repository'] ?? [];
$revisions = $payload['revisions'] ?? [];
$ref = $payload['ref'] ?? '';
$after = $payload['after'] ?? '';
// ブランチ名を抽出 (refs/heads/main -> main)
$branch = '';
if (preg_match('/refs\/heads\/(.+)$/', $ref, $matches)) {
$branch = $matches[1];
}
// 最新のリビジョン情報を取得
$latest_revision = !empty($revisions) ? $revisions[0] : [];
$author_email = $latest_revision['author']['email'] ?? '';
// リポジトリのクローンURLを生成
$clone_url = '';
if (isset($repository['url'])) {
$repo_url = $repository['url'];
// Backlog形式のURL変換: https://n-e-x-t.backlog.com/git/TEST/TEST -> [email protected]:/TEST/TEST.git
if (preg_match('/https:\/\/([^.]+)\.backlog\.com\/git\/([^\/]+)\/(.+)$/', $repo_url, $matches)) {
$space_key = $matches[1]; // n-e-x-t
$project = $matches[2]; // TEST
$repo_name = $matches[3]; // TEST
$clone_url = "{$space_key}@{$space_key}.git.backlog.com:/{$project}/{$repo_name}.git";
} else {
// 他の形式のURLの場合はそのまま使用
$clone_url = $repo_url;
}
}
// 送信用のデータを作成
$forward_payload = [
'payload' => [
'new_ref' => $after,
'branch' => $branch,
'email' => $author_email,
'clone_url' => $clone_url
]
];
// Webhookを送信
$result = sendWebhook($FORWARD_WEBHOOK_URL, $forward_payload);
if ($result['success']) {
http_response_code(200);
echo json_encode([
'status' => 'success',
'message' => 'Webhook forwarded successfully',
'forwarded_data' => $forward_payload
]);
} else {
http_response_code(500);
echo json_encode([
'status' => 'error',
'message' => 'Failed to forward webhook',
'error' => $result['error']
]);
}
} catch (Exception $e) {
http_response_code(500);
echo json_encode([
'status' => 'error',
'message' => 'Internal server error',
'error' => $e->getMessage()
]);
}
/**
* Webhookを送信する関数
*
* @param string $url 送信先URL
* @param array $data 送信するデータ
* @return array 結果
*/
function sendWebhook($url, $data) {
$json_data = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $json_data,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Content-Length: ' . strlen($json_data)
],
CURLOPT_TIMEOUT => 30,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_SSL_VERIFYPEER => true
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($response === false || !empty($error)) {
return [
'success' => false,
'error' => $error ?: 'Unknown curl error'
];
}
if ($http_code >= 200 && $http_code < 300) {
return [
'success' => true,
'response' => $response,
'http_code' => $http_code
];
} else {
return [
'success' => false,
'error' => "HTTP Error: {$http_code}",
'response' => $response
];
}
}
/**
* デバッグ用関数(開発時のみ使用)
*
* @param mixed $data
*/
function debugLog($data) {
error_log('[Webhook Debug] ' . print_r($data, true));
}
// デバッグモード(開発時にコメントアウトを外す)
// debugLog(['raw_input' => $raw_input, 'parsed_data' => $parsed_data, 'payload' => $payload]);
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment