├── .php_cs.dist.php ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json ├── psalm.xml.dist ├── src ├── Client │ └── NotionClient.php ├── Exceptions │ └── NotionResourceException.php ├── Notion.php └── Resources │ ├── ApiResource.php │ ├── Databases.php │ ├── Pages.php │ └── Types │ ├── Database.php │ └── Page.php └── undo_configure.sh /.php_cs.dist.php: -------------------------------------------------------------------------------- 1 | in([ 5 | __DIR__ . '/src', 6 | __DIR__ . '/tests', 7 | ]) 8 | ->name('*.php') 9 | ->notName('*.blade.php') 10 | ->ignoreDotFiles(true) 11 | ->ignoreVCS(true); 12 | 13 | return (new PhpCsFixer\Config()) 14 | ->setRules([ 15 | '@PSR2' => true, 16 | 'array_syntax' => ['syntax' => 'short'], 17 | 'ordered_imports' => ['sort_algorithm' => 'alpha'], 18 | 'no_unused_imports' => true, 19 | 'not_operator_with_successor_space' => true, 20 | 'trailing_comma_in_multiline' => true, 21 | 'phpdoc_scalar' => true, 22 | 'unary_operator_spaces' => true, 23 | 'binary_operator_spaces' => true, 24 | 'blank_line_before_statement' => [ 25 | 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'], 26 | ], 27 | 'phpdoc_single_line_var_spacing' => true, 28 | 'phpdoc_var_without_name' => true, 29 | 'method_argument_space' => [ 30 | 'on_multiline' => 'ensure_fully_multiline', 31 | 'keep_multiple_spaces_after_comma' => true, 32 | ], 33 | 'single_trait_insert_per_statement' => true, 34 | ]) 35 | ->setFinder($finder); 36 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `php-notion` will be documented in this file. 4 | 5 | ## 1.0.0 - 202X-XX-XX 6 | 7 | - initial release 8 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 64robots 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Access Notion API from you PHP application 2 | 3 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/64robots/php-notion.svg?style=flat-square)](https://packagist.org/packages/64robots/php-notion) 4 | [![GitHub Tests Action Status](https://img.shields.io/github/workflow/status/64robots/php-notion/run-tests?label=tests)](https://github.com/64robots/php-notion/actions?query=workflow%3Arun-tests+branch%3Amain) 5 | [![GitHub Code Style Action Status](https://img.shields.io/github/workflow/status/64robots/php-notion/Check%20&%20fix%20styling?label=code%20style)](https://github.com/64robots/php-notion/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain) 6 | [![Total Downloads](https://img.shields.io/packagist/dt/64robots/php-notion.svg?style=flat-square)](https://packagist.org/packages/64robots/php-notion) 7 | 8 | This package allows you to use the Notion API from PHP. 9 | 10 | ## Installation 11 | 12 | This package requires PHP => 7.4. 13 | You can install the package via composer: 14 | 15 | ```bash 16 | composer require 64robots/php-notion 17 | ``` 18 | 19 | ## Usage 20 | 21 | You need to create an instance of the `Notion` class using your [Notion Internal Integration Token](https://developers.notion.com/docs/getting-started) 22 | 23 | Now you can invoke the resource method you need (`databases` in this example) 24 | 25 | ```php 26 | use R64\PhpNotion\Notion; 27 | 28 | $notion = new Notion('secret_access_token'); 29 | 30 | $database = $notion->databases()->retrieve('a65b5216-46cb-479b-961e-67cc7b05a56d'); 31 | ``` 32 | ## Resources 33 | 34 | ### Databases 35 | 36 | #### Retrieve a Database 37 | [Notion Retrieve Database documentation](https://developers.notion.com/reference/get-database) 38 | ```php 39 | $database = $notion->databases()->retrieve('a65b5216-46cb-479b-961e-67cc7b05a56d'); 40 | ``` 41 | 42 | ## Testing 43 | 44 | ```bash 45 | composer test 46 | ``` 47 | 48 | ## Changelog 49 | 50 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. 51 | 52 | ## Contributing 53 | 54 | Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details. 55 | 56 | ## Security Vulnerabilities 57 | 58 | Please review [our security policy](../../security/policy) on how to report security vulnerabilities. 59 | 60 | ## Credits 61 | 62 | - [64 Robots](https://github.com/64robots) 63 | - [All Contributors](../../contributors) 64 | 65 | ## License 66 | 67 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 68 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "64robots/php-notion", 3 | "description": "Package to use Notion API from PHP", 4 | "keywords": [ 5 | "64robots", 6 | "php_notion", 7 | "notion" 8 | ], 9 | "homepage": "https://github.com/64robots/php-notion", 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "64 Robots", 14 | "email": "miguel@64robots.com", 15 | "role": "Developer" 16 | } 17 | ], 18 | "require": { 19 | "php": "^7.4|^8.0", 20 | "guzzlehttp/guzzle": "^7.3" 21 | }, 22 | "require-dev": { 23 | "friendsofphp/php-cs-fixer": "^2.17", 24 | "phpunit/phpunit": "^9.5", 25 | "vimeo/psalm": "^4.3", 26 | "spatie/ray": "^1.22" 27 | 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "R64\\PhpNotion\\": "src" 32 | } 33 | }, 34 | "autoload-dev": { 35 | "psr-4": { 36 | "R64\\PhpNotion\\Tests\\": "tests" 37 | } 38 | }, 39 | "scripts": { 40 | "psalm": "vendor/bin/psalm", 41 | "test": "vendor/bin/phpunit", 42 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage", 43 | "format": "vendor/bin/php-cs-fixer fix --allow-risky=yes" 44 | }, 45 | "config": { 46 | "sort-packages": true 47 | }, 48 | "minimum-stability": "dev", 49 | "prefer-stable": true 50 | } 51 | -------------------------------------------------------------------------------- /psalm.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/Client/NotionClient.php: -------------------------------------------------------------------------------- 1 | client = $restClient ?: new Client([ 23 | 'base_uri' => $baseUri, 24 | 'timeout' => $timeout, 25 | 'headers' => ['Authorization' => "Bearer {$accessToken}",'Notion-Version' => '2021-05-13'], 26 | ]); 27 | } 28 | 29 | public function getResource(string $resourceType, string $resourceId = null) 30 | { 31 | $uri = ! is_null($resourceId) ? "/v1/${resourceType}/${resourceId}" : "/v1/${resourceType}"; 32 | 33 | $response = $this->makeRequest('get', $uri); 34 | 35 | if ($this->attemptSuccessful()) { 36 | return $response; 37 | } 38 | 39 | throw new NotionResourceException($this->getMessage(), $this->statusCode()); 40 | } 41 | 42 | public function createResource(string $resourceType, array $payload = []) 43 | { 44 | $response = $this->makeRequest('POST', "/v1/$resourceType", $payload); 45 | 46 | if ($this->attemptSuccessful()) { 47 | return $response; 48 | } 49 | 50 | throw new NotionResourceException($this->getMessage(), $this->statusCode()); 51 | } 52 | 53 | public function updateResource(string $resourceType, string $resourceId, $payload) 54 | { 55 | $response = $this->makeRequest('PUT', "/v1/$resourceType/$resourceId", $payload); 56 | 57 | if ($this->attemptSuccessful()) { 58 | return $response; 59 | } 60 | 61 | throw new NotionResourceException($this->getMessage(), $this->statusCode()); 62 | } 63 | 64 | /** 65 | * @param string $resourceType 66 | * @param string $resourceId 67 | * @return mixed 68 | * @throws NotionResourceException 69 | */ 70 | public function deleteResource(string $resourceType, string $resourceId) 71 | { 72 | $response = $this->makeRequest('DELETE', "/v1/$resourceType/$resourceId"); 73 | 74 | if ($this->attemptSuccessful()) { 75 | return $response; 76 | } 77 | 78 | throw new NotionResourceException($this->getMessage(), $this->statusCode()); 79 | } 80 | 81 | /** 82 | * @param string $method 83 | * @param string $uri 84 | * @param array $params 85 | * @param array $headers 86 | * @return mixed 87 | */ 88 | public function makeRequest(string $method, string $uri, array $params = [], $headers = []) 89 | { 90 | try { 91 | $queryMethods = ['get', 'delete']; 92 | 93 | $method = strtolower($method); 94 | 95 | $requestOptions = in_array(strtolower($method), $queryMethods) ? ['query' => $params] : ['json' => $params]; 96 | 97 | $response = $this->client->$method($uri, $requestOptions); 98 | 99 | $this->successful = $response->getReasonPhrase() === 'OK'; 100 | $this->status = $response->getStatusCode(); 101 | 102 | return json_decode((string)$response->getBody()); 103 | } catch (Exception $exception) { 104 | $this->recordError($exception); 105 | } 106 | } 107 | 108 | public function attemptSuccessful(): bool 109 | { 110 | return $this->successful; 111 | } 112 | 113 | public function statusCode(): int 114 | { 115 | return $this->status; 116 | } 117 | 118 | public function getMessage() 119 | { 120 | return $this->message; 121 | } 122 | 123 | public function recordError($e) 124 | { 125 | $this->status = $e->getCode(); 126 | $this->successful = false; 127 | $this->message = $e->getMessage(); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/Exceptions/NotionResourceException.php: -------------------------------------------------------------------------------- 1 | notionClient = new NotionClient( 23 | self::NOTION_API_BASE_URI, 24 | $accessToken, 25 | self::DEFAULT_TIMEOUT_SECONDS 26 | ); 27 | } 28 | 29 | public function databases(): Databases 30 | { 31 | /** 32 | * @psalm-suppress RedundantPropertyInitializationCheck 33 | */ 34 | if (! isset($this->databases)) { 35 | $this->databases = new Databases($this->notionClient); 36 | } 37 | 38 | return $this->databases; 39 | } 40 | 41 | public function pages(): Pages 42 | { 43 | /** 44 | * @psalm-suppress RedundantPropertyInitializationCheck 45 | */ 46 | if (! isset($this->pages)) { 47 | $this->pages = new Pages($this->notionClient); 48 | } 49 | 50 | return $this->pages; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Resources/ApiResource.php: -------------------------------------------------------------------------------- 1 | notionClient = $notionClient; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Resources/Databases.php: -------------------------------------------------------------------------------- 1 | notionClient->getResource('databases', $databaseId); 14 | 15 | return new Database( 16 | $response->object, 17 | $response->id, 18 | $response->created_time, 19 | $response->last_edited_time, 20 | $response->title, 21 | $response->properties 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Resources/Pages.php: -------------------------------------------------------------------------------- 1 | notionClient->getResource('pages', $pageId); 16 | 17 | return new Page( 18 | $response->object, 19 | $response->id, 20 | $response->created_time, 21 | $response->last_edited_time, 22 | $response->properties, 23 | $response->archived, 24 | $response->parent 25 | ); 26 | } 27 | 28 | /** 29 | * @param array $payload 30 | * @return Page 31 | * @throws \R64\PhpNotion\Exceptions\NotionResourceException 32 | */ 33 | public function create(array $payload): Page 34 | { 35 | $response = $this->notionClient->createResource('pages', $payload); 36 | 37 | return new Page( 38 | $response->object, 39 | $response->id, 40 | $response->created_time, 41 | $response->last_edited_time, 42 | $response->properties, 43 | $response->archived, 44 | $response->parent 45 | ); 46 | } 47 | 48 | /** 49 | * @param string $pageId 50 | * @param array $payload 51 | * @return Page 52 | * @throws \R64\PhpNotion\Exceptions\NotionResourceException 53 | */ 54 | public function update(string $pageId, array $payload): Page 55 | { 56 | $response = $this->notionClient->updateResource('pages', $pageId, $payload); 57 | 58 | return new Page( 59 | $response->object, 60 | $response->id, 61 | $response->created_time, 62 | $response->last_edited_time, 63 | $response->properties, 64 | $response->archived, 65 | $response->parent 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Resources/Types/Database.php: -------------------------------------------------------------------------------- 1 | object = $object; 25 | $this->id = $id; 26 | $this->createdTime = $createdTime; 27 | $this->lastEditedTime = $lastEditedTime; 28 | $this->title = $title; 29 | $this->properties = $properties; 30 | } 31 | 32 | public function object(): string 33 | { 34 | return $this->object; 35 | } 36 | 37 | public function id(): string 38 | { 39 | return $this->id; 40 | } 41 | 42 | public function createdTime(): string 43 | { 44 | return $this->createdTime; 45 | } 46 | 47 | public function lastEditedTime(): string 48 | { 49 | return $this->lastEditedTime; 50 | } 51 | 52 | public function title(): array 53 | { 54 | return $this->title; 55 | } 56 | 57 | public function properties(): object 58 | { 59 | return $this->properties; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Resources/Types/Page.php: -------------------------------------------------------------------------------- 1 | object = $object; 30 | $this->id = $id; 31 | $this->createdTime = $createdTime; 32 | $this->lastEditedTime = $lastEditedTime; 33 | $this->properties = $properties; 34 | $this->archived = $archived; 35 | $this->parent = $parent; 36 | } 37 | 38 | /** 39 | * @return object|object 40 | */ 41 | public function getParent() 42 | { 43 | return $this->parent; 44 | } 45 | 46 | /** 47 | * @return bool|bool 48 | */ 49 | public function getArchived() 50 | { 51 | return $this->archived; 52 | } 53 | 54 | /** 55 | * @return object 56 | */ 57 | public function getProperties() 58 | { 59 | return $this->properties; 60 | } 61 | 62 | /** 63 | * @return string 64 | */ 65 | public function getCreatedTime() 66 | { 67 | return $this->createdTime; 68 | } 69 | 70 | /** 71 | * @return string 72 | */ 73 | public function getId() 74 | { 75 | return $this->id; 76 | } 77 | 78 | /** 79 | * @return string 80 | */ 81 | public function getLastEditedTime() 82 | { 83 | return $this->lastEditedTime; 84 | } 85 | 86 | /** 87 | * @return string|string 88 | */ 89 | public function getObject() 90 | { 91 | return $this->object; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /undo_configure.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "## revert to last commit" 3 | git reset head --hard 4 | git clean -f -d 5 | rm -fr vendor 6 | rm composer.lock 7 | --------------------------------------------------------------------------------