I'm getting error:
{
"message":"Not Found",
"documentation_url":"https://docs.github.com/rest",
"status":"404"
}
when trying to create private repo on my GitHub account. My code in php:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.github.com/MY_USERNAME/repos',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => array(
"Accept: application/vnd.github+json",
"Authorization: Bearer MY_TOKEN",
"X-GitHub-Api-Version: 2022-11-28",
"User-Agent: MY_APP_NAME"
),
CURLOPT_POSTFIELDS => array(
"name" => "test-repo-123",
"description" => "This is your first repo!",
"homepage" => "https://MY_URL",
"private" => true,
"is_template" => true
),
));
$response = curl_exec($curl);
curl_close($curl);
I had to create GH App, and installed it on my GH Account.
When I cut line:
"User-Agent: MY_APP_NAME"
I get error:
Request forbidden by administrative rules. Please make sure your request has a User-Agent header (https://docs.github.com/en/rest/overview/resources-in-the-rest-api#user-agent-required). Check https://developer.github.com for other possible causes.
Ofcourse, in constants: MY_USERNAME, MY_TOKEN, MY_APP_NAME, MY_URL
I have my sensitive data.
What am I doing wrong?
Thanks Mike
I have correct the code. But now I get such error:
{
"message":"Not Found",
"documentation_url":"https://docs.github.com/rest/repos/repos#create-a-repository-for-the-authenticated-user",
"status":"404"
}
I've modified code, by gaining token from github oauth:
Route::get('/route1', function () {
if (Session::get('authorization') == '1') {
Session::put('authorization', '2');
$code = request()->input('code');
if (!$code) {
return abort(404);
}
$res = Http::post('https://github.com/login/oauth/access_token', [
'client_id' => 'MY_CLIENT_ID',
'client_secret' => 'MY_SECRET',
'code' => $code,
'redirect_uri' => 'https://MY_URL/route1',
]);
$query_str = $res->body();
$data = [];
parse_str($query_str, $data);
Session::forget('authorization');
if (!isset($data['access_token'])) {
return abort(404);
}
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api.github.com/user/repos',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => array(
"Accept: application/vnd.github+json",
"Authorization: Bearer {$data['access_token']}",
"X-GitHub-Api-Version: 2022-11-28",
"User-Agent: TryfonEuAuth"
),
CURLOPT_POSTFIELDS => array(
"name" => "my-new-repo-name",
"description" => "This is your first repo!",
"homepage" => "https://MY_HOMEPAGE",
"private" => true,
"is_template" => true
),
));
$response = curl_exec($curl);
curl_close($curl);
Log::info("aa", [$response]);
dd($response);
}
});
Route::get('/oauth', function () {
Session::put('authorization', '1');
return redirect('https://github.com/login/oauth/authorize?client_id=MY_CLIENT&state=MY_HASH');
})->middleware('auth.basic');
Whats wrong now?
Like Allan said, the misstake was, that body need to be RAW Json! Now its ok. I don't need to connect with outh. I just generated 30day valid token in my profile panel GitHub.
Below I put working code:
$res = Http::withHeaders([
'Authorization' => 'Bearer MY_TOKEN',
'Content-Type' => 'application/json',
'User-Agent' => 'Laravel/11.31',
])->withBody(
'{
"name":"my-test-repo-2",
"description":"test repo 2!",
"homepage":"https://github.com",
"private":true,
"is_template":true
}'
)->post('https://api.github.com/user/repos');
From what I've found, your URL shouldn't contain "MY_USERNAME" (your username) but thw word "user" instead.
// FROM
CURLOPT_URL => 'https://api.github.com/MY_USERNAME/repos',
// TO
CURLOPT_URL => 'https://api.github.com/user/repos',
Here GitHub made an endpoint for managing repos for user, so it's like a placeholder to precise you create a repo for the authenticated user.
Hope this helps!
EDIT POST UPDATE
From your updated code and based on GitHub's documentation, you're giving a body in an array format but GitHub's api asks for a json encoded one.
In your CURLOPT_HTTPHEADER
add the following line that specifies that the body is encoded in json :
CURLOPT_HTTPHEADER => array(
"Accept: application/vnd.github+json",
"Authorization: Bearer {$data['access_token']}",
"X-GitHub-Api-Version: 2022-11-28",
"User-Agent: TryfonEuAuth",
"Content-Type: application/json"
),
Also, to encode your body in JSON, in your line CURLOPT_POSTFIELDS => array([
replace array
by json_encode
.
This way, you'd get this modified header and body:
CURLOPT_HTTPHEADER => array(
"Accept: application/vnd.github+json",
"Authorization: Bearer {$data['access_token']}",
"X-GitHub-Api-Version: 2022-11-28",
"User-Agent: TryfonEuAuth",
"Content-Type: application/json"
),
CURLOPT_POSTFIELDS => json_encode([
"name" => "my-new-repo-name",
"description" => "This is your first repo!",
"homepage" => "https://MY_HOMEPAGE",
"private" => true,
"is_template" => true
]),