Skip to content

Commit a7251fd

Browse files
feat: add doc for building plane app
1 parent 96e5987 commit a7251fd

File tree

2 files changed

+183
-0
lines changed

2 files changed

+183
-0
lines changed

guides/build-plane-app.mdx

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
---
2+
title: Build your Plane Integration app
3+
sidebarTitle: Build your Plane Integration app
4+
description: Step-by-step guide for developers to build and integrate an app with Plane.so using OAuth-based authentication and authorization workflow.
5+
---
6+
7+
This guide provides step-by-step instructions for developers to build and integrate an app with Plane.so using an OAuth-based authentication and authorization workflow.
8+
9+
## Introduction
10+
11+
Plane.so supports OAuth 2.0 for secure authentication and authorization of third-party applications. This ensures that apps can request and obtain access tokens on behalf of users, enabling seamless integration while maintaining security standards.
12+
13+
## Prerequisites
14+
15+
* A Plane.so workspace.
16+
* Access to Plane.so developer portal.
17+
* Familiarity with OAuth 2.0 concepts (authorization code flow).
18+
* A backend server to handle OAuth token exchange.
19+
20+
## High-Level Workflow
21+
22+
1. **Register your app on Plane.so developer portal**
23+
2. **Implement OAuth authorization code flow**
24+
3. **Obtain and store access tokens securely**
25+
4. **Make authenticated API requests to Plane.so**
26+
5. **Handle token refresh**
27+
28+
## Registering Your App
29+
30+
To build an OAuth application with Plane.so:
31+
32+
1. Navigate to `https://app.plane.so/<workspace_slug>/settings/applications/`.
33+
2. Click on the **Build your own** button.
34+
3. Fill out the form with the required details:
35+
36+
* **Redirect URIs**: Provide the URIs where Plane.so will send the authorization code.
37+
* **Contact Details**: Add your email or other contact information.
38+
* **Webhook URL Endpoint**: Update this with your service's webhook endpoint. Plane.so will send webhooks for all changes that happen in the installed workspace.
39+
* **Organization Details**: Include contact email, privacy policy URL, terms of service URL, and any other relevant information. This helps Plane.so validate and approve your application for listing in the marketplace.
40+
4. If you're building an agent (with or without using Plane's ADK) capable of performing operations when assigned or mentioned, enable the **Is Mentionable** checkbox during app creation.
41+
5. Once the app is created, securely store the **Client ID** and **Client Secret**. You will need these credentials to interact with Plane.so's API during the OAuth flow and for making authenticated API requests.
42+
43+
## Authentication Setup
44+
45+
### Generating Consent URL
46+
47+
Before handling types of authentication, if your app manages installation, you must generate the consent (authorization) URL to initiate the OAuth flow. Below is a sample implementation:
48+
49+
```python
50+
params = {
51+
"client_id": os.getenv("PLANE_CLIENT_ID"),
52+
"response_type": "code",
53+
"redirect_uri": os.getenv("PLANE_REDIRECT_URI"),
54+
# Optional: include state if needed
55+
}
56+
57+
consent_url = f"https://api.plane.so/auth/o/authorize-app/?{urlencode(params)}"
58+
```
59+
60+
There are two types of authenticated actions your application can perform:
61+
62+
1. **User-authorized actions** — Actions performed on behalf of a user after they grant permission to your app via OAuth.
63+
2. **App-authorized actions** — Actions that the app can perform independently within the workspace where it is installed (such as responding to webhooks or automation triggers).
64+
65+
We will describe how to configure and use each type in the following sections.
66+
67+
### App-Authorized Actions (Client Credentials Flow)
68+
69+
When the user or admin installs the app, Plane.so will send an `app_installation_id` as part of the callback to the `redirect_uri` provided during consent URL generation. You can use this `app_installation_id` to request a bot token for your app.
70+
71+
#### Example Pseudo-code
72+
73+
```python
74+
# Prepare basic auth header using client_id and client_secret
75+
basic_auth = base64encode("client_id:client_secret")
76+
77+
# Prepare request data
78+
payload = {
79+
"grant_type": "client_credentials",
80+
"app_installation_id": app_installation_id
81+
}
82+
83+
# Make a POST request to fetch bot token
84+
response = POST(
85+
url="https://api.plane.so/auth/o/token/",
86+
headers={"Authorization": f"Basic {basic_auth}",
87+
"Content-Type": "application/x-www-form-urlencoded"},
88+
data=payload
89+
)
90+
91+
bot_token = response.data['access_token']
92+
```
93+
94+
### User-Authorized Actions (Authorization Code Flow)
95+
96+
In this flow, your app exchanges the `code` received as a query parameter on the callback (to your `redirect_uri`) for an access token and refresh token. The access token is short-lived and must be refreshed using the refresh token when it expires. Both tokens should be securely stored.
97+
98+
#### Example Pseudo-code
99+
100+
```python
101+
# Exchange authorization code for access and refresh tokens
102+
payload = {
103+
"grant_type": "authorization_code",
104+
"code": code,
105+
"client_id": client_id,
106+
"client_secret": client_secret,
107+
"redirect_uri": redirect_uri
108+
}
109+
110+
response = POST(
111+
url="https://api.plane.so/auth/o/token/",
112+
headers={"Content-Type": "application/x-www-form-urlencoded"},
113+
data=payload
114+
)
115+
116+
if response.success:
117+
access_token = response.data["access_token"]
118+
refresh_token = response.data["refresh_token"]
119+
120+
121+
# When access token expires, use refresh token to get a new access token
122+
refresh_payload = {
123+
"grant_type": "refresh_token",
124+
"refresh_token": refresh_token,
125+
"client_id": client_id,
126+
"client_secret": client_secret
127+
}
128+
129+
refresh_response = POST(
130+
url="https://api.plane.so/auth/o/token/",
131+
headers={"Content-Type": "application/x-www-form-urlencoded"},
132+
data=refresh_payload
133+
)
134+
135+
if refresh_response.success:
136+
access_token = refresh_response.data["access_token"]
137+
```
138+
139+
### Fetching App Installation Details
140+
141+
In both user-authorized and app-authorized flows, the `app_installation_id` identifies the app's installation within a specific workspace. It is recommended that developers fetch workspace details after OAuth is successfully completed. Plane.so provides an `app-installation` endpoint that works with both types of tokens.
142+
143+
#### Example Pseudo-code
144+
145+
```python
146+
# Set authorization header with either access token or bot token
147+
headers = {
148+
"Authorization": f"Bearer {token}",
149+
}
150+
151+
# Make GET request to fetch installation/workspace details
152+
response = GET(
153+
url=f"https://api.plane.so/auth/o/app-installation/?id={app_installation_id}",
154+
headers=headers
155+
)
156+
157+
workspace_details = response.data
158+
```
159+
160+
## Using Plane SDKs
161+
162+
To simplify the OAuth flow and make it easier to build Plane apps, official SDKs are available:
163+
164+
* **Node.js**: `npm i @makeplane/plane-node-sdk`
165+
* **Python**: `pip install plane-sdk`
166+
167+
These SDKs provide helpers for OAuth and other common tasks, allowing developers to implement the above flows efficiently.
168+
169+
## Listing Your App on Plane Marketplace
170+
171+
Apps built using the OAuth flow can be listed on the Plane Marketplace: [https://plane.so/marketplace/integrations](https://plane.so/marketplace/integrations)
172+
173+
To list your app, please contact the Plane team at [**[email protected]**](mailto:[email protected]).

mint.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@
5353
{
5454
"name": "Webhooks",
5555
"url": "webhooks"
56+
},
57+
{
58+
"name": "Guides",
59+
"url": "guides"
5660
}
5761
],
5862
"navigation": [
@@ -341,6 +345,12 @@
341345
{
342346
"group": "Webhooks",
343347
"pages": ["webhooks/intro-webhooks"]
348+
},
349+
{
350+
"group": "Guides",
351+
"pages": [
352+
"guides/build-plane-app"
353+
]
344354
}
345355
],
346356
"footerSocials": {

0 commit comments

Comments
 (0)