notion-sdk-php icon indicating copy to clipboard operation
notion-sdk-php copied to clipboard

Add support for file_upload type

Open utdrmac opened this issue 6 months ago • 0 comments

Notion recently added the ability to upload objects (eg: images, pdf, etc), and then use them directly in pages by using the uploaded object's id in the block object. This PR adds support for this filetype as part of an image block.

{
	"type": "image",
	"image": {
		"type": "file_upload",
		"file_upload": {
			"id": "{$FILE_UPLOAD_ID}"
		}
	}
}

https://developers.notion.com/reference/file-object https://developers.notion.com/docs/uploading-small-files

I was unsure how to add upload functionality within this SDK. My attempts at using the built-in http client failed, so I created my own NotionApi object with this static function to handle the upload, and return the upload id. This example is CakePHP-based

	/**
	 * @return string The Notion file ID of the uploaded image
	 */
	public static function addImage(string $imageLocation, string $imageName): string
	{
		/** @var string $apiKey **/
		$apiKey = Configure::read('App.notionApiKey');

		// Create a Guzzle client
		$headers = [
			'Authorization' => "Bearer {$apiKey}",
			'Notion-Version' => '2022-06-28',
		];

		$client = new GuzzleHttp\Client([
			'base_uri' => 'https://api.notion.com',
			'headers' => $headers,
		]);

		// Submit file_upload request to get file upload URL and Id
		$resp = $client->request('POST', '/v1/file_uploads', [
			'json' => [
				'mode' => 'single_part',
				'filename' => $imageName,
				'content_type' => 'image/png',
			],
		]);

		if ($resp->getStatusCode() !== 200) {
			throw new Exception('Unable to get Notion Upload ID');
		}

		// Parse response
		$body = $resp->getBody();

		/** @var array{upload_url: string} $uploadInfo */
		$uploadInfo = json_decode($body->getContents(), associative: true);
		$uploadUrl  = $uploadInfo['upload_url'];

		// Upload image to provided URL
		$resp = $client->request('POST', $uploadUrl, [
			'multipart' => [
				[
					'name' => 'file',
					'contents' => GuzzleHttp\Psr7\Utils::tryFopen($imageLocation, 'rb'),
				],
			],
		]);

		if ($resp->getStatusCode() !== 200) {
			throw new Exception('Failed to upload image to Notion');
		}

		$body = $resp->getBody();

		/** @var array{id: string} $fileInfo */
		$fileInfo = json_decode($body->getContents(), associative: true);

		Log::debug("Notion Image Id: {$fileInfo['id']}");

		return $fileInfo['id'];
	}

utdrmac avatar Oct 17 '25 20:10 utdrmac