Skip to content

Angular Integration

Angular 애플리케이션에서 MSAP Chat SDK를 사용하는 방법을 안내합니다.

먼저 설치 문서의 TypeScript 타입 안내에 따라 msap-ai-chat.d.tssrc/types/msap-ai-chat.d.ts로 복사합니다.

서비스로 만들기

재사용 가능한 서비스로 만드는 것을 권장합니다.

services/chat.service.ts

typescript
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class ChatService {
  private widget: MSAPChat.Instance | null = null;

  init(applicationKey: string): void {
    if (window.MSAPChat && !this.widget) {
      this.widget = window.MSAPChat.init({
        applicationKey,
      });
    }
  }

  open(): void {
    this.widget?.open();
  }

  close(): void {
    this.widget?.close();
  }

  toggle(): void {
    this.widget?.toggle();
  }

  isOpen(): boolean {
    return this.widget?.isOpen() ?? false;
  }

  destroy(): void {
    this.widget?.destroy();
    this.widget = null;
  }
}

컴포넌트에서 사용

app.component.ts

typescript
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ChatService } from './services/chat.service';
import { environment } from '../environments/environment';

@Component({
  selector: 'app-root',
  template: `
    <div>
      <h1>My App</h1>
      <button (click)="openChat()">고객 지원</button>
    </div>
  `,
})
export class AppComponent implements OnInit, OnDestroy {
  constructor(private chatService: ChatService) {}

  ngOnInit(): void {
    this.chatService.init(environment.chatKey);
  }

  ngOnDestroy(): void {
    this.chatService.destroy();
  }

  openChat(): void {
    this.chatService.open();
  }
}

index.html에 스크립트 추가

html
<!doctype html>
<html lang="ko">
  <head>
    <meta charset="utf-8" />
    <title>My App</title>
    <base href="/" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <!-- MSAP Chat SDK -->
    <script src="https://sdk.turacocloud.com/msap-ai-chat.min.js"></script>
  </head>
  <body>
    <app-root></app-root>
  </body>
</html>

environment 설정

environments/environment.ts

typescript
export const environment = {
  production: false,
  chatKey: 'your-development-key',
};

environments/environment.prod.ts

typescript
export const environment = {
  production: true,
  chatKey: 'your-production-key',
};

전용 컴포넌트 만들기

components/chat-button/chat-button.component.ts

typescript
import { Component } from '@angular/core';
import { ChatService } from '../../services/chat.service';

@Component({
  selector: 'app-chat-button',
  template: `
    <button class="chat-button" (click)="toggleChat()">
      {{ isOpen ? '채팅 닫기' : '채팅 열기' }}
    </button>
  `,
  styles: [
    `
      .chat-button {
        padding: 10px 20px;
        background: #e60012;
        color: white;
        border: none;
        border-radius: 5px;
        cursor: pointer;
      }
      .chat-button:hover {
        background: #cc0010;
      }
    `,
  ],
})
export class ChatButtonComponent {
  constructor(private chatService: ChatService) {}

  get isOpen(): boolean {
    return this.chatService.isOpen();
  }

  toggleChat(): void {
    this.chatService.toggle();
  }
}

APP_INITIALIZER로 초기화

앱 시작 시 자동으로 초기화하려면:

app.module.ts

typescript
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ChatService } from './services/chat.service';
import { environment } from '../environments/environment';

export function initializeChat(chatService: ChatService) {
  return () => {
    chatService.init(environment.chatKey);
  };
}

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: initializeChat,
      deps: [ChatService],
      multi: true,
    },
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

Standalone Components (Angular 14+)

typescript
import { Component, OnInit, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ChatService } from './services/chat.service';
import { environment } from '../environments/environment';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule],
  template: `
    <div>
      <h1>My App</h1>
      <button (click)="openChat()">고객 지원</button>
    </div>
  `,
})
export class AppComponent implements OnInit {
  private chatService = inject(ChatService);

  ngOnInit(): void {
    this.chatService.init(environment.chatKey);
  }

  openChat(): void {
    this.chatService.open();
  }
}

RxJS와 함께 사용

typescript
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class ChatService {
  private widget: MSAPChat.Instance | null = null;
  private isOpenSubject = new BehaviorSubject<boolean>(false);

  public isOpen$: Observable<boolean> = this.isOpenSubject.asObservable();

  init(applicationKey: string): void {
    if (window.MSAPChat && !this.widget) {
      this.widget = window.MSAPChat.init({
        applicationKey,
      });
    }
  }

  open(): void {
    this.widget?.open();
    this.isOpenSubject.next(true);
  }

  close(): void {
    this.widget?.close();
    this.isOpenSubject.next(false);
  }
}

사용:

typescript
@Component({
  selector: 'app-chat-status',
  template: ` <div *ngIf="isOpen$ | async">채팅이 열려있습니다</div> `,
})
export class ChatStatusComponent {
  isOpen$ = this.chatService.isOpen$;

  constructor(private chatService: ChatService) {}
}

다음 단계