This commit is contained in:
Leifer Mendez
2024-04-24 18:59:05 +02:00
commit c5f48307c2
15 changed files with 3504 additions and 0 deletions

7
.dockerignore Normal file
View File

@@ -0,0 +1,7 @@
dist/*
node_modules
.env
*_sessions
*tokens
.wwebjs*

2
.env.example Normal file
View File

@@ -0,0 +1,2 @@
ASSISTANT_ID=
OPENAI_API_KEY=

26
.eslintrc.json Normal file
View File

@@ -0,0 +1,26 @@
{
"env": {
"browser": true,
"node": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:builderbot/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["@typescript-eslint", "builderbot"],
"rules": {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/ban-types": "off",
"no-unsafe-optional-chaining": "off"
}
}

12
.gitignore vendored Normal file
View File

@@ -0,0 +1,12 @@
dist/*
node_modules
.env
tmp/*
!tmp/.gitkeep
*_sessions
*tokens
.wwebjs*
*.log
*qr.png

40
Dockerfile Normal file
View File

@@ -0,0 +1,40 @@
# Image size ~ 400MB
FROM node:21-alpine3.18 as builder
WORKDIR /app
RUN corepack enable && corepack prepare pnpm@latest --activate
ENV PNPM_HOME=/usr/local/bin
COPY . .
COPY package*.json *-lock.yaml ./
RUN apk add --no-cache --virtual .gyp \
python3 \
make \
g++ \
&& apk add --no-cache git \
&& pnpm install && pnpm run build \
&& apk del .gyp
FROM node:21-alpine3.18 as deploy
WORKDIR /app
ARG PORT
ENV PORT $PORT
EXPOSE $PORT
COPY --from=builder /app/assets ./assets
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/*.json /app/*-lock.yaml ./
RUN corepack enable && corepack prepare pnpm@latest --activate
ENV PNPM_HOME=/usr/local/bin
RUN npm cache clean --force && pnpm install --production --ignore-scripts \
&& addgroup -g 1001 -S nodejs && adduser -S -u 1001 nodejs \
&& rm -rf $PNPM_HOME/.npm $PNPM_HOME/.node-gyp
CMD ["npm", "start"]

44
README.md Normal file
View File

@@ -0,0 +1,44 @@
<p align="center">
<a href="https://builderbot.vercel.app/">
<picture>
<img src="https://builderbot.vercel.app/assets/thumbnail-vector.png" height="80">
</picture>
<h2 align="center">BuilderBot</h2>
</a>
</p>
<p align="center">
<a aria-label="NPM version" href="https://www.npmjs.com/package/@builderbot/bot">
<img alt="" src="https://img.shields.io/npm/v/@builderbot/bot?color=%2300c200&label=%40bot-whatsapp">
</a>
<a aria-label="Join the community on GitHub" href="https://link.codigoencasa.com/DISCORD">
<img alt="" src="https://img.shields.io/discord/915193197645402142?logo=discord">
</a>
</p>
## Getting Started
With this library, you can build automated conversation flows agnostic to the WhatsApp provider, set up automated responses for frequently asked questions, receive and respond to messages automatically, and track interactions with customers. Additionally, you can easily set up triggers to expand functionalities limitlessly.
```
npm create builderbot@latest
```
## Documentation
Visit [builderbot](https://builderbot.vercel.app/) to view the full documentation.
## Official Course
If you want to discover all the functions and features offered by the library you can take the course.
[View Course](https://app.codigoencasa.com/courses/builderbot?refCode=LEIFER)
## Contact Us
- [💻 Discord](https://link.codigoencasa.com/DISCORD)
- [👌 𝕏 (Twitter)](https://twitter.com/leifermendez)

BIN
assets/sample.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

12
nodemon.json Normal file
View File

@@ -0,0 +1,12 @@
{
"watch": ["src"],
"ext": "ts",
"ignore": [
"**/*.test.ts",
"**/*.spec.ts"
],
"delay": "3",
"execMap": {
"ts": "tsx"
}
}

35
package.json Normal file
View File

@@ -0,0 +1,35 @@
{
"name": "base-bailey-json",
"version": "1.0.0",
"description": "",
"main": "dist/app.js",
"type": "module",
"scripts": {
"start": "node ./dist/app.js",
"lint": "eslint . --no-ignore",
"dev": "npm run lint && nodemon ./src/app.ts",
"build": "npx rollup -c"
},
"keywords": [],
"dependencies": {
"@builderbot-plugins/openai-assistants": "^0.0.2",
"@builderbot/bot": "1.1.4-alpha.2",
"@builderbot/provider-baileys": "1.1.4-alpha.2",
"dotenv": "^16.4.5"
},
"devDependencies": {
"@types/multer": "^1.4.11",
"@types/node": "^20.11.30",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.4.0",
"eslint": "^8.52.0",
"eslint-plugin-builderbot": "latest",
"nodemon": "^3.1.0",
"rollup": "^4.10.0",
"rollup-plugin-typescript2": "^0.36.0",
"tsx": "^4.7.1",
"typescript": "^5.4.3"
},
"author": "",
"license": "ISC"
}

3228
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

13
rollup.config.js Normal file
View File

@@ -0,0 +1,13 @@
import typescript from 'rollup-plugin-typescript2'
export default {
input: 'src/app.ts',
output: {
file: 'dist/app.js',
format: 'esm',
},
onwarn: (warning) => {
if (warning.code === 'UNRESOLVED_IMPORT') return
},
plugins: [typescript()],
}

37
src/app.ts Normal file
View File

@@ -0,0 +1,37 @@
import "dotenv/config"
import { createBot, createProvider, createFlow, addKeyword, EVENTS } from '@builderbot/bot'
import { MemoryDB as Database } from '@builderbot/bot'
import { BaileysProvider as Provider } from '@builderbot/provider-baileys'
import { toAsk, httpInject } from "@builderbot-plugins/openai-assistants"
import { typing } from "./utils/presence"
const PORT = process.env?.PORT ?? 3008
const ASSISTANT_ID = process.env?.ASSISTANT_ID ?? ''
const welcomeFlow = addKeyword<Provider, Database>(EVENTS.WELCOME)
.addAction(async (ctx, { flowDynamic, state, provider }) => {
await typing(ctx, provider)
const response = await toAsk(ASSISTANT_ID, ctx.body, state)
const chunks = response.split(/(?<!\d)\.\s+/g);
for (const chunk of chunks) {
await flowDynamic([{ body: chunk.trim() }]);
}
})
const main = async () => {
const adapterFlow = createFlow([welcomeFlow])
const adapterProvider = createProvider(Provider)
const adapterDB = new Database()
const { httpServer } = await createBot({
flow: adapterFlow,
provider: adapterProvider,
database: adapterDB,
})
httpInject(adapterProvider.server)
httpServer(+PORT)
}
main()

14
src/utils/presence.ts Normal file
View File

@@ -0,0 +1,14 @@
const typing = async function (ctx: any, provider: any) {
if (provider && provider?.vendor && provider.vendor?.sendPresenceUpdate) {
const id = ctx.key.remoteJid
await provider.vendor.sendPresenceUpdate('composing', id)
}
}
const recording = async function (ctx: any, provider: any) {
if (provider && provider?.vendor && provider.vendor?.sendPresenceUpdate) {
const id = ctx.key.remoteJid
await provider.vendor.sendPresenceUpdate('recording', id)
}
}
export { typing, recording }

0
tmp/.gitkeep Normal file
View File

34
tsconfig.json Normal file
View File

@@ -0,0 +1,34 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"declaration": false,
"declarationMap": false,
"moduleResolution": "node",
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"sourceMap": false,
"outDir": "./dist",
"baseUrl": "./",
"rootDir": "./",
"incremental": true,
"skipLibCheck": true,
"paths": {
"~/*": ["./src/*"]
}
},
"include": [
"**/*.js",
"**/*.ts"
],
"exclude": [
"node_modules",
"dist",
"**/*.test.ts",
"**/*.spec.ts",
"**e2e**",
"**mock**"
]
}