|
| 1 | +<?php |
| 2 | +//Petit Note 2021-2025 (c)satopian MIT Licence |
| 3 | +//https://paintbbs.sakura.ne.jp/ |
| 4 | + |
| 5 | +//Misskey APIに接続 |
| 6 | + |
| 7 | +require_once(__DIR__.'/config.php'); |
| 8 | +require_once(__DIR__.'/functions.php'); |
| 9 | + |
| 10 | +$lang = ($http_langs = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '') |
| 11 | +? explode( ',', $http_langs )[0] : ''; |
| 12 | +$en= (stripos($lang,'ja')!==0); |
| 13 | + |
| 14 | +session_sta(); |
| 15 | + |
| 16 | +if((!isset($_SESSION['sns_api_session_id'])) || (!isset($_SESSION['sns_api_val']))) { |
| 17 | + die("Error: セッションがありません。Misskey投稿フローが正しく動作していません。"); |
| 18 | +}; |
| 19 | + |
| 20 | +$baseUrl = $_SESSION['misskey_server_radio'] ?? ""; |
| 21 | +if(!filter_var($baseUrl,FILTER_VALIDATE_URL)){ |
| 22 | + die("Error: サーバのURLが無効です。: " . $baseUrl); |
| 23 | +} |
| 24 | + |
| 25 | +$skip_auth_check = (bool)filter_input_data('GET','skip_auth_check',FILTER_VALIDATE_BOOLEAN); |
| 26 | +if($skip_auth_check){ |
| 27 | + if((string)filter_input_data('GET','s_id') !== $_SESSION['sns_api_session_id']){ |
| 28 | + die("Error: " . ($en ? "Operation failed." :"失敗しました。")); |
| 29 | + } |
| 30 | + return connect_misskey_api::create_misskey_note(); |
| 31 | +} |
| 32 | + |
| 33 | +connect_misskey_api::mi_auth_check(); |
| 34 | + |
| 35 | +// 認証チェック |
| 36 | +class connect_misskey_api{ |
| 37 | + |
| 38 | + public static function mi_auth_check(): void { |
| 39 | + global $en,$baseUrl; |
| 40 | + $sns_api_session_id = $_SESSION['sns_api_session_id']; |
| 41 | + $checkUrl = $baseUrl . "/api/miauth/{$sns_api_session_id}/check"; |
| 42 | + |
| 43 | + $checkCurl = curl_init(); |
| 44 | + curl_setopt($checkCurl, CURLOPT_URL, $checkUrl); |
| 45 | + curl_setopt($checkCurl, CURLOPT_POST, true); |
| 46 | + curl_setopt($checkCurl, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); |
| 47 | + curl_setopt($checkCurl, CURLOPT_POSTFIELDS, json_encode([]));//空のData |
| 48 | + curl_setopt($checkCurl, CURLOPT_RETURNTRANSFER, true); |
| 49 | + |
| 50 | + $checkResponse = curl_exec($checkCurl); |
| 51 | + curl_close($checkCurl); |
| 52 | + |
| 53 | + if (!$checkResponse) { |
| 54 | + die("Error: " . ($en ? "Authentication failed." :"認証に失敗しました。") . " (Curl error)"); |
| 55 | + } |
| 56 | + |
| 57 | + $responseData = json_decode($checkResponse, true); |
| 58 | + if(!isset($responseData['token'])){ |
| 59 | + die("Error: " . ($en ? "Authentication failed." :"認証に失敗しました。") . " (No token in response)"); |
| 60 | + } |
| 61 | + $accessToken = $responseData['token']; |
| 62 | + $_SESSION['accessToken'] = $accessToken; |
| 63 | + $user = $responseData['user']; |
| 64 | + self::create_misskey_note(); |
| 65 | + } |
| 66 | + |
| 67 | + public static function create_misskey_note(): void { |
| 68 | + |
| 69 | + global $en,$baseUrl,$root_url; |
| 70 | + |
| 71 | + $accessToken = $_SESSION['accessToken'] ?? ""; |
| 72 | + if(!$accessToken){ |
| 73 | + die("Error: " . ($en ? "Authentication failed." :"認証に失敗しました。") . " (No access token)"); |
| 74 | + } |
| 75 | + |
| 76 | + list($com,$src_image,$tool,$painttime,$hide_thumbnail,$no,$article_url_link,$cw) = $_SESSION['sns_api_val']; |
| 77 | + |
| 78 | + $src_image=basename($src_image); |
| 79 | + |
| 80 | + // 画像のアップロード |
| 81 | + $imagePath = __DIR__.'/src/'.$src_image; |
| 82 | + |
| 83 | + if(!is_file($imagePath)){ |
| 84 | + die("Error: " . ($en ? "Image does not exist." : "画像がありません。") . ": " . $imagePath); |
| 85 | + }; |
| 86 | + |
| 87 | + $uploadUrl = $baseUrl . "/api/drive/files/create"; |
| 88 | + $uploadHeaders = array( |
| 89 | + 'Content-Type: multipart/form-data' |
| 90 | + ); |
| 91 | + $uploadFields = array( |
| 92 | + 'i' => $accessToken, |
| 93 | + 'file' => new CURLFile($imagePath), |
| 94 | + ); |
| 95 | + $uploadCurl = curl_init(); |
| 96 | + curl_setopt($uploadCurl, CURLOPT_URL, $uploadUrl); |
| 97 | + curl_setopt($uploadCurl, CURLOPT_POST, true); |
| 98 | + curl_setopt($uploadCurl, CURLOPT_POSTFIELDS, $uploadFields); |
| 99 | + curl_setopt($uploadCurl, CURLOPT_RETURNTRANSFER, true); |
| 100 | + |
| 101 | + $uploadResponse = curl_exec($uploadCurl); |
| 102 | + $uploadStatusCode = curl_getinfo($uploadCurl, CURLINFO_HTTP_CODE); |
| 103 | + $curlError = curl_error($uploadCurl); |
| 104 | + curl_close($uploadCurl); |
| 105 | + |
| 106 | + if ($uploadResponse === false) { |
| 107 | + die("Error: 画像のアップロードに失敗しました (cURL Error: " . $curlError . ")"); |
| 108 | + } |
| 109 | + |
| 110 | + $responseData = json_decode($uploadResponse, true); |
| 111 | + |
| 112 | + if ($uploadStatusCode !== 200 && $uploadStatusCode !== 204) { |
| 113 | + $errorDetails = isset($responseData['error']['message']) ? $responseData['error']['message'] : 'Unknown API Error'; |
| 114 | + die("Error: 画像のアップロードに失敗しました (API Status: " . $uploadStatusCode . ", Details: " . $errorDetails . ")"); |
| 115 | + } |
| 116 | + |
| 117 | + $fileId = $responseData['id'] ?? ''; |
| 118 | + |
| 119 | + if(!$fileId){ |
| 120 | + die("Error: " . ($en ? "Failed to upload the image." : "画像のアップロードに失敗しました。") . " (No file ID in response)"); |
| 121 | + } |
| 122 | + |
| 123 | + $updateUrl = $baseUrl . "/api/drive/files/update"; |
| 124 | + $updateHeaders = array( |
| 125 | + 'Content-Type: application/json' |
| 126 | + ); |
| 127 | + $updateData = array( |
| 128 | + 'i' => $accessToken, |
| 129 | + 'fileId' => $fileId, |
| 130 | + 'isSensitive' => (bool)($hide_thumbnail), |
| 131 | + ); |
| 132 | + |
| 133 | + $updateCurl = curl_init(); |
| 134 | + curl_setopt($updateCurl, CURLOPT_URL, $updateUrl); |
| 135 | + curl_setopt($updateCurl, CURLOPT_POST, true); |
| 136 | + curl_setopt($updateCurl, CURLOPT_HTTPHEADER, $updateHeaders); |
| 137 | + curl_setopt($updateCurl, CURLOPT_POSTFIELDS, json_encode($updateData)); |
| 138 | + curl_setopt($updateCurl, CURLOPT_RETURNTRANSFER, true); |
| 139 | + $updateResponse = curl_exec($updateCurl); |
| 140 | + $updateStatusCode = curl_getinfo($updateCurl, CURLINFO_HTTP_CODE); |
| 141 | + $updateCurlError = curl_error($updateCurl); |
| 142 | + curl_close($updateCurl); |
| 143 | + |
| 144 | + if ($updateResponse === false) { |
| 145 | + die("Error: ファイルの更新に失敗しました (cURL Error: " . $updateCurlError . ")"); |
| 146 | + } |
| 147 | + if ($updateStatusCode !== 200 && $updateStatusCode !== 204) { |
| 148 | + $updateResponseData = json_decode($updateResponse, true); |
| 149 | + $errorDetails = isset($updateResponseData['error']['message']) ? $updateResponseData['error']['message'] : 'Unknown API Error'; |
| 150 | + die("Error: ファイルの更新に失敗しました (API Status: " . $updateStatusCode . ", Details: " . $errorDetails . ")"); |
| 151 | + } |
| 152 | + |
| 153 | + $uploadResult = json_decode($uploadResponse, true); |
| 154 | + |
| 155 | + if (!$fileId) { |
| 156 | + die("Error: " . ($en ? "Failed to post the content." : "投稿に失敗しました。") . " (No file ID in response)"); |
| 157 | + } |
| 158 | + |
| 159 | + sleep(10); |
| 160 | + |
| 161 | + $tool= $tool ? 'Tool:'.$tool."\n" :''; |
| 162 | + $painttime= $painttime ? 'Paint time:'.$painttime."\n" :''; |
| 163 | + |
| 164 | + $src_image_filename = pathinfo($src_image, PATHINFO_FILENAME );//拡張子除去 |
| 165 | + |
| 166 | + $fixed_link = BASE.'?resno='.$no.'#'.$src_image_filename; |
| 167 | + $fixed_link = filter_var($fixed_link,FILTER_VALIDATE_URL) ? $fixed_link : ''; |
| 168 | + $article_url_link = $article_url_link ? $fixed_link : ''; |
| 169 | + $com=str_replace(["\r\n","\r"],"\n",$com); |
| 170 | + $com=$com ? $com."\n" :''; |
| 171 | + $com = preg_replace("/(\s*\n){2,}/u","\n",$com); //不要改行カット |
| 172 | + |
| 173 | + $status = $tool.$painttime.$com.$article_url_link; |
| 174 | + |
| 175 | + $postUrl = $baseUrl . "/api/notes/create"; |
| 176 | + $postHeaders = array( |
| 177 | + 'Content-Type: application/json' |
| 178 | + ); |
| 179 | + $postData = array( |
| 180 | + 'i' => $accessToken, |
| 181 | + 'cw' => $cw, |
| 182 | + 'text' => $status, |
| 183 | + 'fileIds' => array($fileId), |
| 184 | + ); |
| 185 | + |
| 186 | + $postCurl = curl_init(); |
| 187 | + curl_setopt($postCurl, CURLOPT_URL, $postUrl); |
| 188 | + curl_setopt($postCurl, CURLOPT_POST, true); |
| 189 | + curl_setopt($postCurl, CURLOPT_HTTPHEADER, $postHeaders); |
| 190 | + curl_setopt($postCurl, CURLOPT_POSTFIELDS, json_encode($postData)); |
| 191 | + curl_setopt($postCurl, CURLOPT_RETURNTRANSFER, true); |
| 192 | + $postResponse = curl_exec($postCurl); |
| 193 | + $postStatusCode = curl_getinfo($postCurl, CURLINFO_HTTP_CODE); |
| 194 | + $postCurlError = curl_error($postCurl); |
| 195 | + curl_close($postCurl); |
| 196 | + |
| 197 | + if ($postResponse === false) { |
| 198 | + die("Error: Misskeyへの投稿に失敗しました (cURL Error: " . $postCurlError . ")"); |
| 199 | + } |
| 200 | + |
| 201 | + if ($postStatusCode !== 200 && $postStatusCode !== 204) { |
| 202 | + $postResponseData = json_decode($postResponse, true); |
| 203 | + $errorDetails = isset($postResponseData['error']['message']) ? $postResponseData['error']['message'] : 'Unknown API Error'; |
| 204 | + die("Error: Misskeyへの投稿に失敗しました (API Status: " . $postStatusCode . ", Details: " . $errorDetails . ")"); |
| 205 | + } |
| 206 | + |
| 207 | + $postResult = json_decode($postResponse, true); |
| 208 | + if (!empty($postResult['createdNote']["fileIds"])) { |
| 209 | + |
| 210 | + unset($_SESSION['sns_api_session_id']); |
| 211 | + unset($_SESSION['sns_api_val']); |
| 212 | + unset($_SESSION['userdel']); |
| 213 | + |
| 214 | + redirect(BASE.'?mode=misskey_success&no='.$no); |
| 215 | + } |
| 216 | + else { |
| 217 | + die("Error: " . ($en ? "Failed to post the content." : "投稿に失敗しました。") . " (API response missing createdNote)"); |
| 218 | + } |
| 219 | + } |
| 220 | +} |
0 commit comments