2
0

Introducing The Forge (#1072)

The Forge allows anyone to easily create their own Typebot Block.

Closes #380
This commit is contained in:
Baptiste Arnaud
2023-12-13 10:22:02 +01:00
committed by GitHub
parent c373108b55
commit 5e019bbb22
184 changed files with 42659 additions and 37411 deletions

View File

@ -0,0 +1,63 @@
import { createAction, option } from '@typebot.io/forge'
import { isDefined, isEmpty } from '@typebot.io/lib'
import { got } from 'got'
import { apiBaseUrl } from '../constants'
import { auth } from '../auth'
import { ChatNodeResponse } from '../types'
export const sendMessage = createAction({
auth,
name: 'Send Message',
options: option.object({
botId: option.string.layout({
label: 'Bot ID',
placeholder: '68c052c5c3680f63',
moreInfoTooltip:
'The bot_id you want to ask question to. You can find it at the end of your ChatBot URl in your dashboard',
}),
threadId: option.string.layout({
label: 'Thread ID',
moreInfoTooltip:
'Used to remember the conversation with the user. If empty, a new thread is created.',
}),
message: option.string.layout({
label: 'Message',
placeholder: 'Hi, what can I do with ChatNode',
input: 'textarea',
}),
responseMapping: option.saveResponseArray(['Message', 'Thread ID']).layout({
accordion: 'Save response',
}),
}),
getSetVariableIds: ({ responseMapping }) =>
responseMapping?.map((r) => r.variableId).filter(isDefined) ?? [],
run: {
server: async ({
credentials: { apiKey },
options: { botId, message, responseMapping, threadId },
variables,
}) => {
const res: ChatNodeResponse = await got
.post(apiBaseUrl + botId, {
headers: {
Authorization: `Bearer ${apiKey}`,
},
json: {
message,
chat_session_id: isEmpty(threadId) ? undefined : threadId,
},
})
.json()
responseMapping?.forEach((mapping) => {
if (!mapping.variableId || !mapping.item) return
if (mapping.item === 'Message')
variables.set(mapping.variableId, res.message)
if (mapping.item === 'Thread ID')
variables.set(mapping.variableId, res.chat_session_id)
})
},
},
})

View File

@ -0,0 +1,15 @@
import { option, AuthDefinition } from '@typebot.io/forge'
export const auth = {
type: 'encryptedCredentials',
name: 'ChatNode account',
schema: option.object({
apiKey: option.string.layout({
label: 'API key',
isRequired: true,
helperText:
'You can generate an API key [here](https://www.chatnode.ai/account/settings).',
input: 'password',
}),
}),
} satisfies AuthDefinition

View File

@ -0,0 +1 @@
export const apiBaseUrl = 'https://api.public.chatnode.ai/v1/'

View File

@ -0,0 +1,13 @@
import { createBlock } from '@typebot.io/forge'
import { ChatNodeLogo } from './logo'
import { auth } from './auth'
import { sendMessage } from './actions/sendMessage'
export const chatNode = createBlock({
id: 'chat-node',
name: 'ChatNode',
tags: ['ai', 'openai', 'document', 'url'],
LightLogo: ChatNodeLogo,
auth,
actions: [sendMessage],
})

View File

@ -0,0 +1,10 @@
import React from 'react'
export const ChatNodeLogo = (props: React.SVGProps<SVGSVGElement>) => (
<svg viewBox="0 0 25 25" xmlns="http://www.w3.org/2000/svg" {...props}>
<path
d="M17.5659 9.95206C17.5659 10.6394 17.0087 11.1966 16.3214 11.1966H15.9065C15.2192 11.1966 14.6619 10.6394 14.6619 9.95206L14.6619 2.36802C14.6619 2.03123 14.459 1.726 14.1432 1.60895C12.3471 0.943268 10.4043 0.57959 8.37666 0.57959H2.00814C1.43534 0.57959 0.970996 1.04394 0.970996 1.61674C0.970996 3.63734 0.93996 5.66077 0.964561 7.68162C0.968691 8.02086 1.2456 8.29263 1.58487 8.29263L7.60934 8.29263C8.2967 8.29263 8.85392 8.84985 8.85392 9.53721V9.95206C8.85392 10.6394 8.2967 11.1966 7.60934 11.1966L2.03766 11.1966C1.64592 11.1966 1.35104 11.5545 1.44396 11.9351C1.82599 13.4998 2.42987 14.9774 3.22037 16.333C3.46819 16.7579 3.93069 17.0047 4.42262 17.0047H16.3214C17.0087 17.0047 17.5659 17.5619 17.5659 18.2492V18.6641C17.5659 19.3514 17.0087 19.9087 16.3214 19.9087H7.04882C6.67598 19.9087 6.4984 20.3561 6.78168 20.5985C9.68205 23.0805 13.4486 24.5796 17.5653 24.5796H24.971V17.1739C24.971 11.6855 22.3066 6.81948 18.2007 3.79866C17.9338 3.60233 17.5659 3.7977 17.5659 4.12899L17.5659 9.95206Z"
fill="#818CF8"
></path>
</svg>
)

View File

@ -0,0 +1,16 @@
{
"name": "@typebot.io/chat-node-block",
"version": "1.0.0",
"description": "",
"main": "index.ts",
"keywords": [],
"license": "ISC",
"devDependencies": {
"@typebot.io/forge": "workspace:*",
"@typebot.io/lib": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"@types/react": "18.2.15",
"typescript": "5.3.2",
"got": "12.6.0"
}
}

View File

@ -0,0 +1,10 @@
{
"extends": "@typebot.io/tsconfig/base.json",
"include": ["**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"],
"compilerOptions": {
"lib": ["ESNext", "DOM"],
"noEmit": true,
"jsx": "react"
}
}

View File

@ -0,0 +1,4 @@
export type ChatNodeResponse = {
message: string
chat_session_id: string
}