@resolution/confluence-api-client v0.7.7
confluence-api-client
Atlassian Confluence API client based on OpenAPI schema.
Compatible with the following request/fetch Atlassian libraries:
Installation
Note that this package requires zod
as a peer dependency.
Install using npm
npm add @resolution/confluence-api-client zod
Or using yarn
yarn add @resolution/confluence-api-client zod
Usage
Connect
Inside Connect iframe:
import { ConfluenceApiV1, ConfluenceApiV2 } from '@resolution/confluence-api-client';
async function test() {
const confluenceApiV1 = new ConfluenceApiV1({ AP: window.AP });
const currentUser = await confluenceApiV1.users.getCurrentUser();
console.log("Current User:", currentUser);
const confluenceApiV2 = new ConfluenceApiV2({ AP: window.AP });
const spaces = await confluenceApiV2.space.getSpaces({ keys: ["SPACE"] });
console.log("Space:", spaces.results[0]);
}
test().catch(console.error);
On the server side using atlassian-connect-express
:
import atlassianConnectExpress from 'atlassian-connect-express';
import { ConfluenceApiV1, ConfluenceApiV2 } from '@resolution/confluence-api-client';
const app = express();
const ace = atlassianConnectExpress(app);
app.use(ace.authenticate());
app.get('/current-user', async () => {
const confluenceApiV1 = new ConfluenceApiV1({
ace,
clientKey: req.context.clientKey,
userAccountId: req.context.userAccountId
});
const currentUser = await confluenceApiV1.users.getCurrentUser();
res.status(200).send(currentUser);
});
app.get('/spaces/:spaceKey', async () => {
const confluenceApiV2 = new ConfluenceApiV2({ ace, clientKey: req.context.clientKey });
const spaces = await confluenceApiV2.space.getSpaces({ keys: [req.params.spaceKey] });
res.status(200).send(spaces.results[0]);
});
app.listen(3000);
Forge
Inside Forge iframe:
import { ConfluenceApiV1, ConfluenceApiV2 } from '@resolution/confluence-api-client';
import { requestConfluence } from '@forge/bridge';
async function test() {
const confluenceApiV1 = new ConfluenceApiV1({ requestConfluence });
const currentUser = await confluenceApiV1.users.getCurrentUser();
console.log("Current User:", currentUser);
const confluenceApiV2 = new ConfluenceApiV2({ requestConfluence });
const spaces = await confluenceApiV2.space.getSpaces({ keys: ["SPACE"] });
console.log("Space:", spaces.results[0]);
}
test().catch(console.error);
On the server side using @forge/api
:
import { ConfluenceApiV1, ConfluenceApiV2 } from '@resolution/confluence-api-client';
import * as forgeApi from '@forge/api';
export const handler = async ({ payload }) => {
const confluenceApiV1 = new ConfluenceApiV1({ forgeApi });
const currentUser = await confluenceApiV1.users.getCurrentUser();
const confluenceApiV2 = new ConfluenceApiV2({ forgeApi });
const spaces = await confluenceApiV2.space.getSpaces({ keys: [payload.spaceKey] });
return { currentUser, space: spaces.results[0] };
}
External fetch on the server side:
import { ConfluenceApiV1, ConfluenceApiV2 } from '@resolution/confluence-api-client';
import { fetch } from "@forge/api";
const baseUrl = "https://your-jira-instance.atlassian.net";
export const handler = async ({ payload }) => {
const confluenceApiV1 = new ConfluenceApiV1({ fetch, baseUrl });
const currentUser = await confluenceApiV1.users.getCurrentUser();
const confluenceApiV2 = new ConfluenceApiV2({ fetch, baseUrl });
const spaces = await confluenceApiV2.space.getSpaces({ keys: [payload.spaceKey] });
return { currentUser, space: spaces.results[0] };
}
Impersonalization
When using API on the server side, you can impersonalize the API client. This is useful when you need to access API resources on behalf of a different user or app.
atlassian-connect-express
By default, atlassian-connect-express
makes requests on behalf of the app.
To impersonalize the API client, you need to provide the userAccountId
to the API client:
// ...
app.get('/current-user', async () => {
const confluenceApiV1 = new ConfluenceApiV1({
ace,
clientKey: req.context.clientKey,
userAccountId: req.context.userAccountId
});
const currentUser = await confluenceApiV1.users.getCurrentUser();
res.status(200).send(currentUser);
});
// ...
This can also be achieved by calling asUser
method on the API client:
const confluenceApiV1 = new ConfluenceApiV1({
ace,
clientKey: req.context.clientKey
});
const currentUser = await confluenceApiV1.asUser(req.context.userAccountId).users.getCurrentUser();
@forge/api
By default, @forge/api
makes requests on behalf of the current user.
To perform requests on behalf of the app, you need to provide the asApp
to the API client:
// ...
export const handler = async ({ payload }) => {
const confluenceApiV2 = new ConfluenceApiV2({ forgeApi, asApp: true });
const spaces = await confluenceApiV2.space.getSpaces({ keys: [payload.spaceKey] });
return spaces.results[0];
};
This can also be achieved by calling asApp
method on the API client:
const confluenceApiV2 = new ConfluenceApiV2({ forgeApi });
const spaces = await confluenceApiV2.asApp().space.getSpaces({ keys: ["SPACE"] });
Error handling
All API methods return a promise that resolves to the response data or rejects with an ApiError
instance.
ApiError class:
export class ApiError extends Error {
readonly message: string;
readonly name: "ApiError";
readonly url: URL;
readonly request: CommonHttpClientFetchRequest | undefined;
readonly response: CommonHttpClientFetchResponse | undefined;
readonly options: CommonHttpClientOptions | undefined;
}
Checking response status example:
try {
const spaces = await confluenceApiV2.space.getSpaces({ keys: ["SPACE"] });
console.log("Space:", spaces.results[0]);
} catch (error) {
if (error instanceof ApiError && error.response?.status === 404) {
console.log("Space not found.");
} else {
console.error(error);
}
}
API Documentation
References
License
This repository is licensed under the MIT License.
9 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago