Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions integrations/feature-base/definitions/boards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { z } from '@botpress/sdk'
const boardModel = {
id: z.string().title('id').describe('The unique identifier of the board.'),
category: z.string().title('Category').describe('The name of the board/category. Example: "Feature Requests"'),
private: z.boolean().title('Private').optional().describe('Flag indicating whether this board is private.'),
segmentIds: z.array(z.string()).title('Segment Ids').describe('An array of segment IDs associated with this board.'),
roles: z.array(z.string()).title('Roles').describe('An array of roles that have access to this board.'),
hiddenFromRoles: z
.array(z.string())
.title('Hidden From Roles')
.describe('An array of roles that cannot see this board.'),
disablePostCreation: z
.boolean()
.title('Disable Post Creation')
.optional()
.describe('Flag indicating whether post creation is disabled for this board.'),
disableFollowUpQuestions: z
.boolean()
.title('Disable Follow Up Questions')
.optional()
.describe('Flag indicating whether follow-up questions are disabled for this board.'),
customInputFields: z
.array(z.string())
.title('Custom Input Fields')
.describe('An array of custom input fields ids that apply to this board.'),
defaultAuthorOnly: z
.boolean()
.title('Default Author Only')
.optional()
.describe('Flag indicating whether posts in this board are visible to the author only by default.'),
defaultCompanyOnly: z
.boolean()
.title('Default Company Only')
.optional()
.describe('Flag indicating whether posts in this board are visible to the company only by default.'),
}

export const listBoards = {
title: 'List boards',
description: 'List all boards',
input: {
schema: z.object({}),
},
output: {
schema: z.object({
results: z.array(z.object(boardModel)).title('Results').describe('An array of boards.'),
}),
},
}

export const getBoard = {
title: 'Get a board',
description: 'Get a board by ID',
input: {
schema: z.object({
id: z.string().optional().title('ID').describe('The unique identifier of the board to retrieve.'),
}),
},
output: {
schema: z.object(boardModel).title('Board').describe('A single board'),
},
}
158 changes: 158 additions & 0 deletions integrations/feature-base/definitions/posts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import { z } from '@botpress/sdk'

export const createPost = {
title: 'Create a post',
description: 'Create a post on feature base',
input: {
schema: z.object({
title: z.string().title('Title').describe('The title of the submission. It must be at least 2 characters long.'),
category: z.string().title('Category').describe('The board (a.k.a category) of the submission.'),
content: z
.string()
.title('Content')
.optional()
.describe('The content of the submission. Can be an empty string.'),
email: z
.string()
.title('Email')
.optional()
.describe(
'The email of the user submitting the post. Will create a new user if the email is not associated with an existing user.'
),
authorName: z
.string()
.title('Author Name')
.optional()
.describe(
'Used when you provide an email. If the email is not associated with an existing user, a new user will be created with this name.'
),
tags: z
.array(z.string())
.title('Tags')
.optional()
.describe('The tags associated with the submission. Needs to be an array of tag names.'),
commentsAllowed: z
.boolean()
.title('Comments Allowed')
.optional()
.describe('Flag indicating whether comments are allowed on the submission.'),
status: z.string().title('Status').optional().describe('The status of the submission.'),
date: z.date().title('Date').optional().describe('Set the post creation date.'),
}),
},
output: {
schema: z.object({
submission: z
.object({
id: z.string(),
})
.title('Submission')
.describe('Represent the created post.'),
}),
},
}

export const listPosts = {
title: 'List posts',
description: 'List all posts',
input: {
schema: z.object({
id: z.string().title('ID').optional().describe("Find submission by it's id."),
q: z.string().title('Query').optional().describe('Search for posts by title or content.'),
category: z
.array(z.string())
.title('Category')
.optional()
.describe('Filter posts by providing an array of category(board) names.'),
status: z.array(z.string()).title('Status').optional().describe('Filter posts by status ids.'),
sortBy: z.string().title('Sort By').optional().describe('Sort posts by a specific attribute.'),
startDate: z.date().title('Start Date').optional().describe('Get posts created after a specific date.'),
endDate: z.date().title('End Date').optional().describe('Get posts created before a specific date.'),
limit: z.number().title('Limit').optional().describe('Number of results per page'),
page: z.number().title('Page').optional().describe('Page number. Starts at 1'),
nextToken: z.string().title('Next Token').optional().describe('Page number. Starts at 1'),
}),
},
output: {
schema: z.object({
nextToken: z.string().title('Next Token').optional().describe('Use the token to fetch the next page of posts.'),
results: z
.array(
z.object({
title: z.string(),
content: z.string(),
author: z.string(),
authorId: z.string(),
organization: z.string(),
postCategory: z.object({
category: z.string(),
}),
id: z.string(),
})
)
.title('Results')
.describe('An array of posts.'),
}),
},
}

export const updatePost = {
title: 'Update post',
description: 'Update a post',
input: {
schema: z.object({
id: z.string().title('ID').describe('The id of the submission.'),
title: z.string().title('Title').optional().describe('The title of the post. Example: "Add dark mode support"'),
content: z
.string()
.title('Content')
.optional()
.describe(
'The HTML content of the post. Example: "<p>It would be great to have dark mode support for better viewing at night.</p>"'
),
status: z.string().title('Status').optional().describe('The status of the submission. Example: "In Progress"'),
commentsAllowed: z
.boolean()
.title('Comments Allowed')
.optional()
.describe('Flag indicating whether comments are allowed on the submission. Example: true'),
category: z
.string()
.title('Category')
.optional()
.describe('The category of the submission. Example: "💡 Feature Request"'),
sendStatusUpdateEmail: z
.boolean()
.title('Send Status Update Email')
.optional()
.describe('Flag indicating whether to send a status update email to the upvoters. Default: false'),
tags: z
.array(z.string())
.title('Tags')
.optional()
.describe('The tags of the submission. Example: ["tag1", "tag2"]'),
inReview: z
.boolean()
.title('In Review')
.optional()
.describe('Flag indicating whether the submission is in review. In review posts are not visible to users.'),
date: z.date().title('Date').optional().describe('The post creation date.'),
}),
},
output: {
schema: z.object({}),
},
}

export const deletePost = {
title: 'Delete post',
description: 'Delete a post',
input: {
schema: z.object({
id: z.string().title('ID').describe('The id of the submission.'),
}),
},
output: {
schema: z.object({}),
},
}
11 changes: 11 additions & 0 deletions integrations/feature-base/hub.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Feature Base integration

## Description

This integration allows Botpress bots to interact with Feature Base’s API. By connecting your bot to Feature Base, you can dynamically manage and display content such as posts or boards without leaving the conversation. Whether it’s retrieving live data, adding new entries, or updating existing ones, this integration turns your chatbot into a real-time content manager for Feature Base.

## Getting started

### Configuration

Your API key is needed to configure this integration. How to find your API key is describe in [this documentation](https://docs.featurebase.app/quickstart).
13 changes: 13 additions & 0 deletions integrations/feature-base/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions integrations/feature-base/integration.definition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { z, IntegrationDefinition } from '@botpress/sdk'
import { listBoards, getBoard } from 'definitions/boards'
import { listPosts, createPost, deletePost, updatePost } from 'definitions/posts'

export default new IntegrationDefinition({
name: 'feature-base',
version: '0.1.0',
title: 'Feature Base',
description: 'CRUD operations for Feature Base',
readme: 'hub.md',
icon: 'icon.svg',
configuration: {
schema: z.object({
apiKey: z.string().min(1, 'API Key is required').describe('Your Feature Base API Key').title('API Key'),
}),
},
actions: {
listBoards,
getBoard,
createPost,
listPosts,
deletePost,
updatePost,
},
})
18 changes: 18 additions & 0 deletions integrations/feature-base/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "@botpresshub/feature-base",
"scripts": {
"build": "bp add -y && bp build",
"check:type": "tsc --noEmit",
"check:bplint": "bp lint"
},
"private": true,
"dependencies": {
"@botpress/client": "workspace:*",
"@botpress/sdk": "workspace:*",
"axios": "^1.11.0"
},
"devDependencies": {
"@types/node": "^22.16.4",
"typescript": "^5.6.3"
}
}
Loading
Loading