diff --git a/examples/src/document_loaders/confluence.ts b/examples/src/document_loaders/confluence.ts index e95612f3c08c..e9d6e265f16c 100644 --- a/examples/src/document_loaders/confluence.ts +++ b/examples/src/document_loaders/confluence.ts @@ -2,6 +2,7 @@ import { ConfluencePagesLoader } from "langchain/document_loaders/web/confluence const username = process.env.CONFLUENCE_USERNAME; const accessToken = process.env.CONFLUENCE_ACCESS_TOKEN; +const personalAccessToken = process.env.CONFLUENCE_PAT; if (username && accessToken) { const loader = new ConfluencePagesLoader({ @@ -11,10 +12,18 @@ if (username && accessToken) { accessToken, }); + const documents = await loader.load(); + console.log(documents); +} else if (personalAccessToken) { + const loader = new ConfluencePagesLoader({ + baseUrl: "https://example.atlassian.net/wiki", + spaceKey: "~EXAMPLE362906de5d343d49dcdbae5dEXAMPLE", + personalAccessToken, + }); const documents = await loader.load(); console.log(documents); } else { console.log( - "You must provide a username and access token to run this example." + "You need either a username and access token, or a personal access token (PAT), to use this example." ); } diff --git a/langchain/.env.example b/langchain/.env.example index d6ad749624c8..8a773e50a44c 100644 --- a/langchain/.env.example +++ b/langchain/.env.example @@ -88,3 +88,6 @@ NEO4J_USERNAME=ADD_YOURS_HERE NEO4J_PASSWORD=ADD_YOURS_HERE CLOSEVECTOR_API_KEY=ADD_YOURS_HERE CLOSEVECTOR_API_SECRET=ADD_YOURS_HERE +CONFLUENCE_USERNAME=ADD_YOURS_HERE +CONFLUENCE_PASSWORD=ADD_YOURS_HERE +CONFLUENCE_PATH=ADD_YOURS_HERE diff --git a/langchain/src/document_loaders/web/confluence.ts b/langchain/src/document_loaders/web/confluence.ts index d94e4d2e9b5f..5e2144b2aab0 100644 --- a/langchain/src/document_loaders/web/confluence.ts +++ b/langchain/src/document_loaders/web/confluence.ts @@ -9,8 +9,9 @@ import { BaseDocumentLoader } from "../base.js"; export interface ConfluencePagesLoaderParams { baseUrl: string; spaceKey: string; - username: string; - accessToken: string; + username?: string; + accessToken?: string; + personalAccessToken?: string; limit?: number; } @@ -54,18 +55,21 @@ export class ConfluencePagesLoader extends BaseDocumentLoader { public readonly spaceKey: string; - public readonly username: string; + public readonly username?: string; - public readonly accessToken: string; + public readonly accessToken?: string; public readonly limit: number; + public readonly personalAccessToken?: string; + constructor({ baseUrl, spaceKey, username, accessToken, limit = 25, + personalAccessToken, }: ConfluencePagesLoaderParams) { super(); this.baseUrl = baseUrl; @@ -73,6 +77,24 @@ export class ConfluencePagesLoader extends BaseDocumentLoader { this.username = username; this.accessToken = accessToken; this.limit = limit; + this.personalAccessToken = personalAccessToken; + } + + /** + * Returns the authorization header for the request. + * @returns The authorization header as a string, or undefined if no credentials were provided. + */ + private get authorizationHeader(): string | undefined { + if (this.personalAccessToken) { + return `Bearer ${this.personalAccessToken}`; + } else if (this.username && this.accessToken) { + const authToken = Buffer.from( + `${this.username}:${this.accessToken}` + ).toString("base64"); + return `Basic ${authToken}`; + } + + return undefined; } /** @@ -99,16 +121,18 @@ export class ConfluencePagesLoader extends BaseDocumentLoader { url: string ): Promise { try { - const authToken = Buffer.from( - `${this.username}:${this.accessToken}` - ).toString("base64"); + const initialHeaders: HeadersInit = { + "Content-Type": "application/json", + Accept: "application/json", + }; + + const authHeader = this.authorizationHeader; + if (authHeader) { + initialHeaders.Authorization = authHeader; + } const response = await fetch(url, { - headers: { - Authorization: `Basic ${authToken}`, - "Content-Type": "application/json", - Accept: "application/json", - }, + headers: initialHeaders, }); if (!response.ok) {