In the realm of customer support and interaction, chatbots have emerged as a key tool for providing efficient and instant assistance. With advancements in AI, creating a bespoke chatbot that leverages powerful models like OpenAI’s has become more accessible than ever. In this article, I’ll guide you through creating your own chatbot using OpenAI’s API, with an Angular-based UI and a Spring Boot backend. Notably, building your own system means you aren’t reliant on third-party platforms, offering a more tailored and direct way to support your users.

Why Build Your Own Chatbot?

Before diving into the technicalities, let’s consider why you might choose to develop a chatbot in-house:

Customization: Tailor the experience to fit your brand and specific user needs.Independence: Avoid dependencies on external services and platforms.Cost Efficiency: Control your costs by optimizing your chatbot’s design and deployment.Privacy and Security: Manage sensitive data in-house, adhering to your security standards.

Given the constraints of this platform, I’ll guide you through the structure and key code snippets needed to create the frontend application in an Nx monorepo setup, and outline the backend implementation with Spring Boot, focusing on a single controller with two endpoints. This sample implementation will include necessary TypeScript (TS) and HTML code for the Angular frontend, and Java code for the Spring Boot backend with Swagger annotations for API documentation.

Setting Up Your Angular Frontend

The first step is to create a user-friendly chat interface using Angular. This frontend will handle user inputs and display responses from your chatbot.

Nx Monorepo Setup for Angular Frontend

Create an Nx Workspace:

Install Nx CLI globally with npm: npm install -g nx.Create a new Nx workspace: npx create-nx-workspace@latest yourWorkspace –preset=empty.Navigate into your workspace: cd yourWorkspace.

Add Angular Plugin and Application:

Add Angular capabilities: nx add @nrwl/angular.Generate a new Angular application: nx g @nrwl/angular:app chat-ui.

Implement Chat UI: Inside the apps/chat-ui/src/app/, create or modify the existing components to include:

app.component.html

<div class=“chat-container“>
<div class=“messages“>
<div *ngFor=“let message of messages“>
<p>{{message.sender}}: {{message.content}}</p>
</div>
</div>
<input [(ngModel)]=“newMessage“ placeholder=“Type a message…“ (keyup.enter)=“sendMessage()“>
<button (click)=“sendMessage()“>Send</button>
</div>

app.component.ts

import { Component } from ‚@angular/core‘;
import { HttpClient } from ‚@angular/common/http‘;

interface ChatMessage {
sender: string;
content: string;
}

@Component({
selector: ‚your-app-root‘,
templateUrl: ‚./app.component.html‘,
styleUrls: [‚./app.component.scss‘],
})
export class AppComponent {
messages: ChatMessage[] = [];
newMessage: string = “;

constructor(private http: HttpClient) {
this.loadChatHistory();
}

loadChatHistory() {
this.http.get<ChatMessage[]>(‚/api/chat‘).subscribe((data) => {
this.messages = data;
});
}

sendMessage() {
if (!this.newMessage.trim()) return;
this.http.post<ChatMessage>(‚/api/chat‘, { content: this.newMessage }).subscribe((data) => {
this.messages.push(data);
this.newMessage = “;
});
}
}

Developing the Spring Boot Backend

Your backend acts as the bridge between your Angular frontend and the OpenAI API. It will process requests, interact with the OpenAI API, and return the AI-generated responses to the user.

Spring Boot Setup:

Use Spring Initializr to create a new project with dependencies for Spring Web, Spring Data JPA (if you plan to persist chat history), and OpenAPI (Springdoc).Implement Chat Controller:

ChatController.java

import org.springframework.web.bind.annotation.*;
import org.springframework.http.HttpStatus;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import java.util.List;

@RestController
@RequestMapping(„/api/chat“)
public class ChatController {

// Assuming you have a service to handle chat logic
private final ChatService chatService;

public ChatController(ChatService chatService) {
this.chatService = chatService;
}

@GetMapping
@Operation(summary = „Get chat history“)
@ApiResponse(responseCode = „200“, description = „Success“)
public List<ChatMessage> getChatHistory() {
return chatService.getMessages();
}

@PostMapping
@Operation(summary = „Create a new chat message“)
@ApiResponse(responseCode = „201“, description = „Message created“)
@ResponseStatus(HttpStatus.CREATED)
public ChatMessage createChatMessage(@RequestBody ChatMessage message) {
return chatService.saveMessage(message);
}
}

Integration Notes

Frontend to Backend Communication: Ensure CORS configurations in your Spring Boot application permit requests from your Angular app’s origin.Swagger UI: Access the API documentation generated by Springdoc OpenAPI at http://localhost:8080/swagger-ui.html to test and validate your API endpoints.

Integration with OpenAI’s API

To extend the Spring Boot controller to integrate with OpenAI’s assistance API for the chat, you’ll need to perform a few key steps:

Add OpenAI Java SDK Dependency: Ensure you have the OpenAI Java SDK added to your pom.xml or build.gradle file to make API calls to OpenAI. If there’s no direct SDK available or you prefer a manual integration, you can use a REST client like RestTemplate or WebClient in Spring WebFlux.Configure OpenAI API Key: Securely store your OpenAI API key in your application properties, ensuring it’s not hard-coded or exposed.Extend Chat Controller and Service: Modify your chat service to communicate with OpenAI’s API whenever a new chat message is received. The service will send the user’s message to OpenAI and return the AI’s response as the reply in the chat.

Here’s how you might adjust your ChatController and add a new ChatService method for this integration:

Update application.properties

openai.api.key=your_openai_api_key_here

Extend ChatService to Include OpenAI API Call:

Assuming you’re using RestTemplate for simplicity, but consider WebClient for a non-blocking approach.

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.openai.api.*;

@Service
public class ChatService {

@Value(„${openai.api.key}“)
private String apiKey;

private final RestTemplate restTemplate;

public ChatService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}

public ChatMessage getAIResponse(ChatMessage userMessage) {
// Set up OpenAI request (simplified for demonstration)
OpenAIClient client = new OpenAIClient(apiKey);
String prompt = userMessage.getContent(); // user’s message as prompt
try {
CompletionCreateResponse response = client.completions().create(CompletionCreateRequest.builder()
.model(„text-davinci-003“) // specify the model
.prompt(prompt)
.maxTokens(50) // adjust based on your needs
.build());
String aiResponse = response.getChoices().get(0).getText().trim();
return new ChatMessage(„AI“, aiResponse); // Assuming ChatMessage has a constructor like ChatMessage(String sender, String content)
} catch (Exception e) {
e.printStackTrace();
return new ChatMessage(„AI“, „Sorry, I encountered an error.“);
}
}
}

Modify ChatController to Use AI Responses:

Adjust the createChatMessage method to utilize the ChatService for generating AI responses.

@PostMapping
public ChatMessage createChatMessage(@RequestBody ChatMessage message) {
// Save user message and get AI response
ChatMessage userMessage = chatService.saveMessage(message);
ChatMessage aiResponse = chatService.getAIResponse(message);
chatService.saveMessage(aiResponse); // Optional: save AI response to history
return aiResponse;
}

Notes:

Error Handling: The above code simplifies error handling for brevity. Consider implementing more robust error handling to manage API call failures.Security: Keep your API key secure and never expose

Why This Approach Is Efficient

By developing your chatbot, you gain full control over the customer support experience. You can:

Adapt quickly to changing needs without waiting for third-party updates.Ensure privacy by keeping all interactions within your controlled environment.Reduce costs associated with third-party chatbot services, especially as your usage scales.

Conclusion

Building your chatbot with Angular, Spring Boot, and OpenAI’s API is not just a project; it’s a strategic move towards enhancing your customer support system. It offers a unique blend of customization, efficiency, and independence from third-party platforms. Follow this guide to create a chatbot that not only meets your immediate needs but also scales with your aspirations.

Chatbots Unleashed: OpenAI, Angular, and Spring Boot in Harmony was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.