Skip to main content

Angular Integration with Periscope Web SDK

Integrating the Periscope Web SDK into an Angular application involves loading the SDK, creating a dedicated component for the chatbot, and then using that component within your application.

1. Load the SDK in index.html​

Make the SDK globally available by adding the script tag to your src/index.html file. Place it preferably at the end of the <body> tag:

<!-- src/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>YourAngularApp</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
<app-root></app-root>
<script
async
src="https://media.periscopechat.com/sdk/chatbot-sdk.umd.js"
></script>
</body>
</html>

2. Create a Dedicated Angular Component​

Encapsulating the chatbot in its own component is a good practice for modularity and reusability.

a. Generate the component using Angular CLI:

Open your terminal and run:

ng generate component chatbot

This command creates the necessary files for your component (e.g., src/app/chatbot/chatbot.component.ts, .html, .css) and declares it in your app.module.ts (or the closest module).

b. Define the component's template (src/app/chatbot/chatbot.component.html):

This HTML file will contain the div where the chatbot widget is rendered.

<div [id]="containerId">
<chatbotSDK></chatbotSDK>
</div>

Using [id]="containerId" allows the ID to be dynamically set via an @Input property in your component.

c. Implement the component's logic (src/app/chatbot/chatbot.component.ts):

import {
Component,
AfterViewInit,
Input,
OnChanges,
SimpleChanges,
} from "@angular/core";

// Declare ChatbotSDK to inform TypeScript it's a global variable
// This is crucial because the SDK is loaded via a script tag, not as an ES module.
declare var ChatbotSDK: any;

@Component({
selector: "app-chatbot", // This is how you'll use it in other templates
templateUrl: "./chatbot.component.html",
styleUrls: ["./chatbot.component.css"],
})
export class ChatbotComponent implements AfterViewInit, OnChanges {
// --- Required SDK Configuration ---
@Input() socketUrl!: string; // Mark as definitely assigned if it's always provided
@Input() title: string = "Chat Support";
@Input() headerBgColor: string = "#007bff"; // Default blue
@Input() containerId: string = "periscope-chatbot-container"; // Unique ID for the chatbot instance

// --- Optional SDK Configuration (Refer to SDK documentation for all options) ---
@Input() iconUrl?: string;
@Input() initMessage?: string;
@Input() questionPills?: string[];
@Input() buttonText?: string;
@Input() buttonBgColor?: string;
// @Input() iconComponent?: any; // For advanced use with ReactNode, if applicable

private isSdkInitialized = false;
private sdkLoadAttempts = 0;
private readonly maxSdkLoadAttempts = 10; // e.g., 5 seconds if polling every 500ms
private sdkLoadInterval: any;

constructor() {}

ngAfterViewInit(): void {
this.attemptSdkInitialization();
}

private attemptSdkInitialization(): void {
if (typeof ChatbotSDK !== "undefined" && ChatbotSDK.init) {
this.initializeChatbot();
if (this.sdkLoadInterval) {
clearInterval(this.sdkLoadInterval);
}
} else {
this.sdkLoadAttempts++;
if (this.sdkLoadAttempts <= this.maxSdkLoadAttempts) {
if (!this.sdkLoadInterval) {
// Start interval only if not already running
this.sdkLoadInterval = setInterval(() => {
this.attemptSdkInitialization();
}, 500);
}
} else {
console.error(
"ChatbotSDK could not be loaded after multiple attempts."
);
if (this.sdkLoadInterval) {
clearInterval(this.sdkLoadInterval);
}
}
}
}

ngOnChanges(changes: SimpleChanges): void {
// If critical inputs like socketUrl change, and SDK is initialized, consider re-initialization
// This is a basic example; you might need more sophisticated handling based on which inputs change.
if (
this.isSdkInitialized &&
(changes["socketUrl"] || changes["containerId"])
) {
// console.warn('Chatbot re-initialization due to input changes might be needed.');
// this.initializeChatbot(); // Be cautious with re-initialization logic
}
}

private initializeChatbot(): void {
if (!this.socketUrl) {
console.error("ChatbotSDK: socketUrl is required for initialization.");
return;
}
if (!this.containerId) {
console.error("ChatbotSDK: containerId is required for initialization.");
return;
}

ChatbotSDK.init({
socketUrl: this.socketUrl,
title: this.title,
headerBgColor: this.headerBgColor,
containerId: this.containerId,
iconUrl: this.iconUrl,
initMessage: this.initMessage,
questionPills: this.questionPills,
buttonText: this.buttonText,
buttonBgColor: this.buttonBgColor,
// iconComponent: this.iconComponent, // Uncomment if using
});
this.isSdkInitialized = true;
}

// --- Wrapper methods for SDK functionalities ---
// These methods provide a clean interface to the SDK from your Angular component

identifyUser(name: string, customer_uuid: string): void {
if (this.isSdkInitialized && ChatbotSDK && ChatbotSDK.identify) {
ChatbotSDK.identify(name, customer_uuid);
} else {
console.warn(
"ChatbotSDK not ready for identifyUser call or identify method unavailable."
);
}
}

addCustomMetadata(metadata: object): void {
if (this.isSdkInitialized && ChatbotSDK && ChatbotSDK.addMetadata) {
ChatbotSDK.addMetadata(metadata);
} else {
console.warn(
"ChatbotSDK not ready for addCustomMetadata call or addMetadata method unavailable."
);
}
}

showChat(): void {
if (this.isSdkInitialized && ChatbotSDK && ChatbotSDK.show) {
ChatbotSDK.show();
} else {
console.warn(
"ChatbotSDK not ready for showChat call or show method unavailable."
);
}
}

hideChat(): void {
if (this.isSdkInitialized && ChatbotSDK && ChatbotSDK.hide) {
ChatbotSDK.hide();
} else {
console.warn(
"ChatbotSDK not ready for hideChat call or hide method unavailable."
);
}
}
}

3. Add the Component to an Angular Module​

Ensure your ChatbotComponent is declared in an Angular module. If you used ng generate component chatbot, this is typically done automatically in src/app/app.module.ts or the nearest parent module.

// src/app/app.module.ts (or your feature module)
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser"; // Or CommonModule for feature modules

import { AppComponent } from "./app.component";
import { ChatbotComponent } from "./chatbot/chatbot.component"; // Ensure path is correct

@NgModule({
declarations: [
AppComponent,
ChatbotComponent, // Your ChatbotComponent
],
imports: [
BrowserModule,
// ... other Angular modules
],
providers: [],
bootstrap: [AppComponent], // If this is the main AppModule
// exports: [ChatbotComponent] // If other modules will import this module to use ChatbotComponent
})
export class AppModule {}

4. Use the Chatbot Component in Your Application​

You can now use your <app-chatbot> component selector in any other component's template where you want the chatbot to appear. Pass the necessary configurations using @Input() properties.

<!-- Example: In your app.component.html or any other component template -->
<h1>Welcome to My Angular App</h1>

<app-chatbot
[socketUrl]="'https://your-tenant-name.periscopechat.com/web'"
title="Customer Assistance"
headerBgColor="#123456"
containerId="my-unique-chatbot"
initMessage="Hi there! How can I help you today?"
[questionPills]="['What are your services?', 'How do I reset my password?']"
buttonText="Chat with us"
></app-chatbot>

<p>Some other content on your page.</p>

Remember to replace 'https://your-tenant-name.periscopechat.com/web' with your actual socketUrl.

Key Angular Considerations:​

  • declare var ChatbotSDK: any;: This is vital for TypeScript to recognize the ChatbotSDK object loaded globally via the <script> tag.
  • ngAfterViewInit: Use this lifecycle hook to ensure the DOM is ready before initializing the SDK. The provided example includes a polling mechanism as the SDK script loads asynchronously.
  • @Input() Properties: These make your ChatbotComponent configurable and reusable.
  • containerId: Ensure the containerId passed to ChatbotSDK.init is unique if you plan to have multiple instances, and it must match the id of the div in your chatbot.component.html.
  • Error Handling: The example includes basic console error messages. You might want to implement more robust error handling.
  • Styling: You can add styles to src/app/chatbot/chatbot.component.css to customize the appearance of the chatbot container or elements around it.