-
Notifications
You must be signed in to change notification settings - Fork 178
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #77 from Pash10g/mongo-feed
MongoFeed project
- Loading branch information
Showing
117 changed files
with
9,081 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
node_modules | ||
.env | ||
.env.local | ||
package-lock.json | ||
.next |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
# MongoFeed | ||
|
||
MongoFeed is a comprehensive platform for product feedback analysis and sentiment tracking. It leverages MongoDB for data storage and Amazon Bedrock for AI-powered sentiment analysis, providing valuable insights into customer feedback and product reviews. | ||
|
||
> ♥️ Inpired by a customer success story : [Syncly](https://www.mongodb.com/customers/syncly) | ||
## Hosted Version | ||
|
||
https://mongo-feed.vercel.app | ||
|
||
## Features | ||
|
||
- File upload for product feedback analysis (JSON, HTML, images) | ||
- Chat paste functionality for direct input of customer interactions | ||
- Sentiment analysis using Amazon Bedrock AI | ||
- Real-time processing queue for feedback analysis | ||
- Interactive charts and visualizations: | ||
- Feedback trends over time | ||
- Sentiment distribution | ||
- Top issues identification | ||
- Agent performance tracking and sentiment analysis | ||
|
||
## Prerequisites | ||
|
||
Before you begin, ensure you have the following installed: | ||
- Node.js (v14 or later) | ||
- npm (v6 or later) | ||
- MongoDB (6.0+) | ||
- An AWS account with access to Amazon Bedrock and Claude 3.5 V2 model | ||
|
||
## Installation | ||
|
||
1. **Clone the repository:** | ||
```bash | ||
git clone <repository-url> | ||
cd mongo-feed | ||
``` | ||
|
||
2. **Install dependencies:** | ||
```bash | ||
npm install | ||
``` | ||
|
||
3. **Configure environment variables:** | ||
- Create a `.env.local` file in the root directory. | ||
- Add your MongoDB connection string and AWS Bedrock credentials. | ||
```env | ||
MONGODB_URI=your_mongodb_connection_string | ||
AWS_REGION=your_aws_region | ||
AWS_ACCESS_KEY_ID=your_aws_access_key_id | ||
AWS_SECRET_ACCESS_KEY=your_aws_secret_access_key | ||
``` | ||
**Note:** Ensure you have the necessary permissions for Amazon Bedrock and MongoDB. | ||
## Development | ||
1. **Run the development server:** | ||
```bash | ||
npm run dev | ||
``` | ||
Open [http://localhost:3000](http://localhost:3000) in your browser to view the application. | ||
|
||
## Building for Production | ||
|
||
1. **Build the application:** | ||
```bash | ||
npm run build | ||
``` | ||
|
||
2. **Start the production server:** | ||
```bash | ||
npm run start | ||
``` | ||
|
||
## Usage | ||
|
||
To use MongoFeed: | ||
|
||
1. **Access the application** in your browser at [http://localhost:3000](http://localhost:3000) after running the development or production server. | ||
2. **Upload Feedback Files or Paste Chat Interactions:** | ||
- Navigate to the feedback input section. | ||
- Choose to upload files (JSON, HTML, images) or paste text from chat interactions. | ||
- Follow the on-screen instructions to input your feedback data. | ||
3. **View Sentiment Analysis Results and Visualizations:** | ||
- Once the feedback is processed, navigate to the dashboard. | ||
- Explore interactive charts and visualizations to understand: | ||
- Feedback trends over time | ||
- Sentiment distribution across feedback | ||
- Top issues identified from the feedback | ||
4. **Navigate the Dashboard:** | ||
- Use the dashboard to access different features, such as: | ||
- Real-time processing queue monitoring. | ||
- Agent performance tracking and sentiment analysis (if applicable). | ||
- Detailed views of individual feedback entries and their sentiment analysis. | ||
|
||
## Configuration | ||
|
||
- **Environment Variables:** | ||
- `MONGODB_URI`: MongoDB connection string for your MongoDB database. | ||
- `AWS_REGION`: AWS region where your Bedrock service is configured. | ||
- `AWS_ACCESS_KEY_ID`: AWS access key ID for authentication. | ||
- `AWS_SECRET_ACCESS_KEY`: AWS secret access key for authentication. | ||
|
||
- **Other configurations:** | ||
- The application may have additional configurations that can be set in the `.env.local` file or through the application's settings panel. Refer to the application documentation for advanced configuration options. | ||
|
||
## Contributing | ||
|
||
If you'd like to contribute to MongoFeed, please follow these guidelines: | ||
1. Fork the repository. | ||
2. Create a branch for your feature or bug fix. | ||
3. Ensure your code adheres to the project's coding standards. | ||
4. Submit a pull request with a clear description of your changes. | ||
|
||
## License | ||
|
||
[Specify the project license, e.g., MIT License] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { NextResponse } from "next/server" | ||
import clientPromise from "@/lib/mongodb" | ||
|
||
export const dynamic = "force-dynamic" | ||
export const revalidate = 0 | ||
|
||
export async function GET() { | ||
try { | ||
const client = await clientPromise | ||
const db = client.db("mongofeed") | ||
|
||
const agentAnalysis = await db | ||
.collection("chat_analyses") | ||
.aggregate([ | ||
{ $unwind: "$messages" }, | ||
{ $match: { "messages.role": "Agent" } }, | ||
{ | ||
$group: { | ||
_id: "$messages.agentName", | ||
positiveSentiment: { $sum: { $cond: [{ $eq: ["$messages.sentiment", "positive"] }, 1, 0] } }, | ||
neutralSentiment: { $sum: { $cond: [{ $eq: ["$messages.sentiment", "neutral"] }, 1, 0] } }, | ||
negativeSentiment: { $sum: { $cond: [{ $eq: ["$messages.sentiment", "negative"] }, 1, 0] } }, | ||
totalInteractions: { $sum: 1 }, | ||
}, | ||
}, | ||
{ | ||
$project: { | ||
agentName: "$_id", | ||
positiveSentiment: 1, | ||
neutralSentiment: 1, | ||
negativeSentiment: 1, | ||
totalInteractions: 1, | ||
_id: 0, | ||
}, | ||
}, | ||
{ $sort: { totalInteractions: -1 } }, | ||
]) | ||
.toArray() | ||
|
||
return NextResponse.json(agentAnalysis) | ||
} catch (error) { | ||
console.error("Error fetching agent analysis:", error) | ||
return NextResponse.json({ error: "An error occurred while fetching agent analysis." }, { status: 500 }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { NextResponse } from "next/server" | ||
import clientPromise from "@/lib/mongodb" | ||
|
||
export const dynamic = "force-dynamic" | ||
export const revalidate = 0 | ||
|
||
export async function GET() { | ||
try { | ||
const client = await clientPromise | ||
const db = client.db("mongofeed") | ||
|
||
// First get all agents with their sentiment data | ||
const agentData = await db | ||
.collection("agent_sentiment") | ||
.aggregate([ | ||
{ | ||
$lookup: { | ||
from: "chat_analyses", | ||
let: { agentName: "$agentName" }, | ||
pipeline: [ | ||
{ | ||
$match: { | ||
$expr: { $eq: ["$analysis.agentName", "$$agentName"] }, | ||
}, | ||
}, | ||
{ $sort: { createdAt: -1 } }, | ||
{ $limit: 5 }, | ||
{ | ||
$project: { | ||
id: { $toString: "$_id" }, | ||
date: "$createdAt", | ||
summary: "$analysis.summary", | ||
sentiment: "$analysis.overallSentiment", | ||
issues: "$analysis.mainTopics", | ||
}, | ||
}, | ||
], | ||
as: "recentChats", | ||
}, | ||
}, | ||
{ $sort: { totalInteractions: -1 } }, | ||
]) | ||
.toArray() | ||
|
||
return NextResponse.json(agentData) | ||
} catch (error) { | ||
console.error("Error fetching agent sentiment:", error) | ||
return NextResponse.json({ error: "An error occurred while fetching agent sentiment." }, { status: 500 }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { type NextRequest, NextResponse } from "next/server" | ||
import { analyzeAgentFeedback, analyzeProductReview } from "@/lib/analyze-content" | ||
import clientPromise from "@/lib/mongodb" | ||
|
||
export const dynamic = "force-dynamic" | ||
export const runtime = "nodejs" | ||
|
||
export async function POST(req: NextRequest) { | ||
try { | ||
const formData = await req.formData() | ||
const file = formData.get("file") as File | ||
const type = formData.get("type") as string | ||
|
||
if (!file) { | ||
return NextResponse.json({ error: "No file uploaded" }, { status: 400 }) | ||
} | ||
|
||
const contentType = file.type | ||
const fileName = file.name | ||
|
||
let content: string | ArrayBuffer | ||
if (contentType.startsWith("image/")) { | ||
content = await file.arrayBuffer() | ||
} else { | ||
const buffer = await file.arrayBuffer() | ||
content = new TextDecoder().decode(buffer) | ||
} | ||
|
||
let analysisResult | ||
|
||
if (type === "agent") { | ||
analysisResult = await analyzeAgentFeedback(content as string) | ||
} else if (type === "product") { | ||
analysisResult = await analyzeProductReview(content, contentType, fileName) | ||
} else { | ||
return NextResponse.json({ error: "Invalid analysis type" }, { status: 400 }) | ||
} | ||
|
||
// Store the analysis result in MongoDB | ||
const client = await clientPromise | ||
const db = client.db("mongofeed") | ||
await db.collection("chat_analyses").insertOne({ | ||
type, | ||
contentType, | ||
fileName, | ||
analysis: analysisResult, | ||
createdAt: new Date(), | ||
}) | ||
|
||
return NextResponse.json({ sentiments: analysisResult }) | ||
} catch (error) { | ||
console.error("Error analyzing feedback:", error) | ||
return NextResponse.json({ error: "An error occurred while analyzing feedback." }, { status: 500 }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { NextRequest, NextResponse } from 'next/server'; | ||
import { bedrock } from '@/lib/bedrock'; | ||
import { generateText } from 'ai'; | ||
|
||
export async function POST(req: NextRequest) { | ||
try { | ||
const data = await req.json(); | ||
const documents = data.documents; | ||
|
||
if (!Array.isArray(documents)) { | ||
return NextResponse.json({ error: 'Invalid input. Expected an array of documents.' }, { status: 400 }); | ||
} | ||
|
||
const sentiments = await Promise.all( | ||
documents.map(async (doc) => { | ||
try { | ||
const { text } = await generateText({ | ||
model: bedrock('aanthropic.claude-3-5-sonnet-20241022-v2:0'), | ||
prompt: `Analyze the sentiment of the following text and respond with only one word: "positive", "negative", or "neutral". Text: "${doc}"`, | ||
}); | ||
return text.trim().toLowerCase(); | ||
} catch (error) { | ||
console.error('Error analyzing individual document:', error); | ||
return 'error'; | ||
} | ||
}) | ||
); | ||
|
||
return NextResponse.json({ sentiments }); | ||
} catch (error) { | ||
console.error('Error analyzing sentiment:', error); | ||
return NextResponse.json({ error: 'An error occurred while analyzing sentiment.' }, { status: 500 }); | ||
} | ||
} |
Oops, something went wrong.