Chatbot / src /app /chatbot /chatbot.component.ts
SharanB's picture
Upload 20 files
08eaca3 verified
import { Component, OnInit, AfterViewChecked, ElementRef, ViewChild } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { CouchdbService } from '../couchdb.service'; // Import the service
import emailjs, { EmailJSResponseStatus } from 'emailjs-com';
interface Answer {
text: string;
next: string;
}
interface Node {
type: string;
text: string;
answers?: Answer[];
next?: string;
}
interface DecisionTree {
startNode: string;
nodes: { [key: string]: Node };
}
@Component({
selector: 'app-chatbot',
templateUrl: './chatbot.component.html',
styleUrls: ['./chatbot.component.css']
})
export class ChatbotComponent implements OnInit, AfterViewChecked {
decisionTree: DecisionTree = { startNode: '', nodes: {} };
currentNode: Node = { type: '', text: '' };
conversation: { speaker: string; text: string }[] = [];
userInput = '';
errorMessage = '';
isMinimized = true;
leaveDetails: any = {};
leaveBalance = 0;
@ViewChild('chatContent') private chatContent!: ElementRef;
constructor(private couchdbService: CouchdbService, private http: HttpClient) {} // Inject the service
ngOnInit(): void {
this.couchdbService.getDecisionTree().subscribe(data => {
this.decisionTree = data.data;
this.currentNode = this.decisionTree.nodes[this.decisionTree.startNode];
this.addMessage('bot', this.currentNode.text);
});
}
ngAfterViewChecked() {
this.scrollToBottom();
}
addMessage(speaker: string, text: string): void {
this.conversation.push({ speaker, text });
this.scrollToBottom();
}
selectAnswer(answer: Answer): void {
this.addMessage('user', answer.text);
// Check for redirection conditions
if (this.currentNode.text === "Welcome to our Ticket service!") {
if (answer.text === 'Raise Ticket' || answer.text === 'Ticket Status') {
window.open('https://e.chain.portal.url', '_blank');
}
} else if (this.currentNode.text === "Welcome to our Technical service!") {
if (answer.text === 'Raise Support') {
window.open('https://appTrack.portal.url', '_blank');
}
}
if (this.currentNode.text === "Are you sure you want to submit the form?") {
if (answer.text === 'Yes, submit') {
this.sendLeaveApplicationEmail();
this.userInput = ''; // Clear user input
return;
} else {
// Handle other options if needed
}
}
// Move to the next node based on the selected answer
this.currentNode = this.decisionTree.nodes[answer.next];
this.processNode();
}
submitInput(): void {
if (!this.userInput.trim()) {
this.displayErrorMessage('Please enter a value');
return;
}
// Validate email ID
if (this.currentNode.text === "Enter your Email ID" || this.currentNode.text === "Enter manager Email ID") {
if (!this.validateEmail(this.userInput)) {
this.displayErrorMessage('Please enter a valid email ID');
return;
}
}
// Validate dates
if (this.currentNode.text === "Please provide the start date for your leave. (Format: YYYY-MM-DD)" || this.currentNode.text === "Please provide the end date for your leave. (Format: YYYY-MM-DD)") {
if (!this.validateDate(this.userInput)) {
this.displayErrorMessage('Please enter a valid date in the format YYYY-MM-DD');
return;
}
if (new Date(this.userInput) <= new Date()) {
this.displayErrorMessage('Please enter a date greater than today\'s date');
return;
}
}
this.addMessage('user', this.userInput);
this.errorMessage = '';
this.leaveDetails[this.currentNode.text] = this.userInput; // Store user input in leaveDetails
if (this.currentNode.text === "Please provide your employee ID") {
this.checkEmployeeEligibility(this.userInput);
} else {
this.currentNode = this.decisionTree.nodes[this.currentNode.next || ''];
this.processNode();
}
this.userInput = '';
}
validateEmail(email: string): boolean {
const emailPattern = /^[a-zA-Z]+\.[a-zA-Z]+@chainsys\.com$/;
return emailPattern.test(email);
}
validateDate(date: string): boolean {
const datePattern = /^\d{4}-\d{2}-\d{2}$/;
return datePattern.test(date);
}
checkEmployeeEligibility(employeeId: string): void {
const url = `https://192.168.57.185:5984/employee-db/${employeeId}`;
const headers = new HttpHeaders({
'Authorization': 'Basic ' + btoa('d_couchdb:Welcome#2')
});
this.http.get<any>(url, { headers }).subscribe(
data => {
data.leaveBalance = data.leaveBalance || 0; // Ensure leaveBalance is initialized if null
this.leaveBalance = data.leaveBalance;
this.leaveDetails['leaveBalance'] = this.leaveBalance;
if (this.leaveBalance > 0) {
this.currentNode = this.decisionTree.nodes['nodeEligibilityResult'];
} else {
this.addMessage('bot', 'You are not eligible to apply for leave.');
this.currentNode = this.decisionTree.nodes[this.decisionTree.startNode];
}
this.processNode();
},
error => {
this.addMessage('bot', 'No record found.');
this.currentNode = this.decisionTree.nodes[this.decisionTree.startNode];
this.processNode();
}
);
}
processNode(): void {
if (!this.currentNode) {
console.error('Invalid node configuration');
return;
}
if (this.currentNode.type === 'question' && this.currentNode.text === 'No. of days') {
// Adjust leave options based on leave balance
const maxDays = Math.min(this.leaveBalance, 5); // Maximum of 5 days or leave balance, whichever is smaller
this.currentNode.answers = this.currentNode.answers?.filter(answer => parseInt(answer.text, 10) <= maxDays);
}
const botMessage = this.replaceVariables(this.currentNode.text);
this.addMessage('bot', botMessage);
}
replaceVariables(text: string): string {
return text.replace(/\[\w+\]/g, match => this.leaveDetails[match.slice(1, -1)] || match);
}
toggleMinimize(event?: Event): void {
if (event) {
event.stopPropagation();
}
this.isMinimized = !this.isMinimized;
}
closeChat(event?: Event): void {
const confirmClose = confirm("Are you sure you want to close the chat?");
if (event) {
event.stopPropagation();
}
this.isMinimized = !this.isMinimized;
}
private scrollToBottom(): void {
try {
this.chatContent.nativeElement.scrollTop = this.chatContent.nativeElement.scrollHeight;
} catch (err) {
console.error('Scroll to bottom failed:', err);
}
}
displayErrorMessage(message: string): void {
this.errorMessage = message;
setTimeout(() => {
this.errorMessage = '';
}, 2000);
}
sendLeaveApplicationEmail(): void {
const templateParams = {
employee_email: this.leaveDetails['Enter your Email ID'],
manager_email: this.leaveDetails['Enter manager Email ID'],
employee_id: this.leaveDetails['Please provide your employee ID'],
leave_type: this.leaveDetails['Type of leave'],
leave_reason: this.leaveDetails['Reason for the leave'],
leave_days: this.leaveDetails['No. of days'],
start_date: this.leaveDetails['Please provide the start date for your leave. (Format: YYYY-MM-DD)'],
end_date: this.leaveDetails['Please provide the end date for your leave. (Format: YYYY-MM-DD)']
};
emailjs.send('service_g7y50fu', 'template_20nsgam', templateParams, '8pjnXdcFSoOVX9B6c')
.then((response: EmailJSResponseStatus) => {
console.log('SUCCESS!', response.status, response.text);
this.currentNode = this.decisionTree.nodes['node13'];
this.processNode();
}, (error) => {
console.error('FAILED...', error);
});
}
}