💖 Hello everyone welcome back to Webzone Tech Tips blogspot, today I will share with you my experience how to create a customize Chatbot integration with Facebook Messenger, Ollama NestJS and Prisma for free, after you understand the step you can easy cho switch Ollama with ChatGPT, the purpose I dont use ChatGPT here because ChatGPT need a subscribe and Ollama is free now, you can download it on your local and try,
If you don't know how to run Ollama, you can check this tutorial for know Ollama work first. it very easy to learn.
Let's started now
First, set up your project structure and install dependencies:
npm install -g @nestjs/cli nest new facebook-chatbot cd facebook-chatbot npm install @prisma/client prisma axios
Create Prisma schema (prisma/schema.prisma):
generator client { provider = "prisma-client-js" } datasource db { provider = "mysql" url = env("DATABASE_URL") } model ChatMessage { id Int @id @default(autoincrement()) senderId String message String response String timestamp DateTime @default(now()) pageId String }
Set up environment variables (.env):
DATABASE_URL="mysql://USER:PASSWORD@HOST:PORT/DATABASE" FACEBOOK_PAGE_ACCESS_TOKEN=your_page_access_token FACEBOOK_VERIFY_TOKEN=your_verify_token OLLAMA_BASE_URL=http://localhost:11434 OLLAMA_MODEL=llama2
Create the main chatbot service (src/chat/chat.service.ts):
import { Injectable } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; import axios from 'axios'; @Injectable() export class ChatService { constructor(private prisma: PrismaService) {} async handleMessage(senderId: string, message: string, pageId: string) { // Get response from Ollama const response = await this.getOllamaResponse(message); // Store message in database await this.prisma.chatMessage.create({ data: { senderId, message, response, pageId, }, }); // Send response back to Facebook await this.sendFacebookMessage(senderId, response); } private async getOllamaResponse(prompt: string): Promise<string> { try { const response = await axios.post( `${process.env.OLLAMA_BASE_URL}/api/generate`, { model: process.env.OLLAMA_MODEL, prompt, stream: false, }, ); return response.data.response; } catch (error) { console.error('Error getting response from Ollama:', error); return "I'm having trouble connecting to my AI service. Please try again later."; } } private async sendFacebookMessage(recipientId: string, message: string) { try { await axios.post( `https://graph.facebook.com/v19.0/me/messages?access_token=${process.env.FACEBOOK_PAGE_ACCESS_TOKEN}`, { recipient: { id: recipientId }, message: { text: message }, }, ); } catch (error) { console.error('Error sending message to Facebook:', error); } } }
Create webhook controller (src/webhook/webhook.controller.ts):
import { Controller, Get, Post, Body, Query } from '@nestjs/common'; import { ChatService } from '../chat/chat.service'; @Controller('webhook') export class WebhookController { constructor(private readonly chatService: ChatService) {} @Get() verifyWebhook( @Query('hub.mode') mode: string, @Query('hub.verify_token') token: string, @Query('hub.challenge') challenge: string, ) { if (mode === 'subscribe' && token === process.env.FACEBOOK_VERIFY_TOKEN) { return challenge; } return 'Verification failed'; } @Post() async handleWebhook(@Body() body: any) { const entry = body.entry[0]; const messaging = entry.messaging[0]; if (messaging.message) { await this.chatService.handleMessage( messaging.sender.id, messaging.message.text, entry.id, ); } return 'EVENT_RECEIVED'; } }
Set up Prisma module (src/prisma/prisma.module.ts):
import { Module } from '@nestjs/common'; import { PrismaService } from './prisma.service'; @Module({ providers: [PrismaService], exports: [PrismaService], }) export class PrismaModule {}
Create Prisma service (src/prisma/prisma.service.ts):
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common'; import { PrismaClient } from '@prisma/client'; @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy { async onModuleInit() { await this.$connect(); } async onModuleDestroy() { await this.$disconnect(); } }
Update app module (src/app.module.ts):
import { Module } from '@nestjs/common'; import { WebhookController } from './webhook/webhook.controller'; import { ChatService } from './chat/chat.service'; import { PrismaModule } from './prisma/prisma.module'; @Module({ imports: [PrismaModule], controllers: [WebhookController], providers: [ChatService], }) export class AppModule {}
Update main.ts to enable appropriate settings:
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.enableCors(); await app.listen(3000); } bootstrap();
To use this system:
Set up your Facebook App and Page:
Create a Facebook Developer account and app https://developers.facebook.com/apps/
Add Messenger functionality (Notes: need submit to appreview before publish the app, but need the business type account)
Generate Page Access Token
Set up webhook URL (https://your-domain.com/webhook)
Run Ollama:
ollama pull llama2 ollama serve
Set up your database and run migrations:
npx prisma migrate dev --name init
Start your NestJS application:
npm run start
Important considerations:
Add proper error handling and validation
Implement security measures (rate limiting, authentication)
Handle different message types (images, attachments)
Add message queuing for better performance
Implement proper logging
Add unit tests
Follow Facebook's Messenger Platform policies
Remember to:
Replace environment variables with your actual values
Set up proper SSL certificate for your webhook URL
Configure your Facebook webhook to subscribe to appropriate events
Handle Facebook's message delivery and read receipts
Implement additional features like typing indicators if needed
This provides a basic structure for your chatbot. You'll need to expand it based on your specific requirements and error handling needs.
If you have any unclear above, leave your comment below on this article, I will support you
💖 Thanks for reading 💖
I am Zidane