0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

チャネルトークをNuxt3のECサイトへ導入した話

Last updated at Posted at 2023-12-19

はじめに

チャネルトークとは 

Customer satisfaction on G2で4.8点の評価を受けた
All in oneチャットソリューション
実店舗のような接客体験を売りにしているチャットサービス
とのこと

導入方法

今回はSDKを使用して導入
導入ガイド: https://channel.io/ja/guides

Plugin Keyの取得
下記のガイドの自社制作サイトに従ってPlugin Keyを取得

実装

下記の開発者向けドキュメントを参照して実装
https://developers.channel.io/docs/web-quickstart

1.型ファイルの作成

Service for TypeScriptを参照に型ファイルを作成

types/channel_talk.ts
export interface IChannelIO {
  c?: (...args: any) => void
  q?: [methodName: string, ...args: any[]][]
  (...args: any): void
}

export interface Profile {
  [key: string]: string | number | boolean | null | undefined
}

export interface CallbackUser {
  alert: number
  avatarUrl: string
  id: string
  language: string
  memberId: string
  name?: string
  profile?: Profile | null
  tags?: string[] | null
  unsubscribeEmail: boolean
  unsubscribeTexting: boolean
}

export interface BootOption {
  appearance?: string
  customLauncherSelector?: string
  hideChannelButtonOnBoot?: boolean
  hidePopup?: boolean
  language?: string
  memberHash?: string
  memberId?: string
  pluginKey: string
  profile?: Profile
  trackDefaultEvent?: boolean
  trackUtmSource?: boolean
  unsubscribe?: boolean
  unsubscribeEmail?: boolean
  unsubscribeTexting?: boolean
  zIndex?: number
}

export interface Callback {
  (error: Error | null, user: CallbackUser | null): void
}

export interface UpdateUserInfo {
  language?: string
  profile?: Profile | null
  profileOnce?: Profile
  tags?: string[] | null
  unsubscribeEmail?: boolean
  unsubscribeTexting?: boolean
}

export interface FollowUpProfile {
  name?: string | null
  mobileNumber?: string | null
  email?: string | null
}

export interface EventProperty {
  [key: string]: string | number | boolean | null | undefined
}

export type Appearance = "light" | "dark" | "system" | null

2.windowに型を追加

IChannelIOは先ほどの型ファイルから読み込みます

types/window.ts
import { IChannelIO } from "~/types/channel_talk"
export declare global {
  interface Window {
    ChannelIO?: IChannelIO
  }
}

3.処理部分を作成

layout/default.vue
import {
  IChannelIO,
  BootOption,
  UpdateUserInfo,
  Callback,
  EventProperty,
  FollowUpProfile,
  Appearance,
} from "~/types/channel_talk"

export class ChannelService {
  constructor() {
    this.loadScript()
  }

  loadScript() {
    ;(function () {
      const w = window
      if (w.ChannelIO) return
      const ch: IChannelIO = function () {
        ch.c?.(arguments)
      }
      ch.q = []
      ch.c = function (args) {
        ch.q?.push(args)
      }
      w.ChannelIO = ch
      function l() {
        w.ChannelIOInitialized = true
        const s = document.createElement("script")
        s.type = "text/javascript"
        s.async = true
        s.src = "https://cdn.channel.io/plugin/ch-plugin-web.js"
        const x = document.getElementsByTagName("script")[0]
        if (x.parentNode) {
          x.parentNode.insertBefore(s, x)
        }
      }
      if (document.readyState === "complete") {
        l()
      } else {
        w.addEventListener("DOMContentLoaded", l)
        w.addEventListener("load", l)
      }
    })()
  }

  boot(option: BootOption, callback?: Callback) {
    window.ChannelIO?.("boot", option, callback)
  }

  shutdown() {
    window.ChannelIO?.("shutdown")
  }

  showMessenger() {
    window.ChannelIO?.("showMessenger")
  }

  hideMessenger() {
    window.ChannelIO?.("hideMessenger")
  }

  openChat(chatId?: string | number, message?: string) {
    window.ChannelIO?.("openChat", chatId, message)
  }

  track(eventName: string, eventProperty?: EventProperty) {
    window.ChannelIO?.("track", eventName, eventProperty)
  }

  onShowMessenger(callback: () => void) {
    window.ChannelIO?.("onShowMessenger", callback)
  }

  onHideMessenger(callback: () => void) {
    window.ChannelIO?.("onHideMessenger", callback)
  }

  onBadgeChanged(callback: (unread: number, alert: number) => void) {
    window.ChannelIO?.("onBadgeChanged", callback)
  }

  onChatCreated(callback: () => void) {
    window.ChannelIO?.("onChatCreated", callback)
  }

  onFollowUpChanged(callback: (profile: FollowUpProfile) => void) {
    window.ChannelIO?.("onFollowUpChanged", callback)
  }

  onUrlClicked(callback: (url: string) => void) {
    window.ChannelIO?.("onUrlClicked", callback)
  }

  clearCallbacks() {
    window.ChannelIO?.("clearCallbacks")
  }

  updateUser(userInfo: UpdateUserInfo, callback?: Callback) {
    window.ChannelIO?.("updateUser", userInfo, callback)
  }

  addTags(tags: string[], callback?: Callback) {
    window.ChannelIO?.("addTags", tags, callback)
  }

  removeTags(tags: string[], callback?: Callback) {
    window.ChannelIO?.("removeTags", tags, callback)
  }

  setPage(page: string) {
    window.ChannelIO?.("setPage", page)
  }

  resetPage() {
    window.ChannelIO?.("resetPage")
  }

  showChannelButton() {
    window.ChannelIO?.("showChannelButton")
  }

  hideChannelButton() {
    window.ChannelIO?.("hideChannelButton")
  }

  setAppearance(appearance: Appearance) {
    window.ChannelIO?.("setAppearance", appearance)
  }
}


4.C側に表示

layout/default.vue
import { ChannelService, ignoreChannelTalkPath } from "~/utils/channel_talk"

const channelTalkViewEvent = () => {
  const channel = new ChannelService()
  const pluginKey = プラグインキー
  if (window.ChannelIOInitialized) {
    channel.boot({
      pluginKey,
    })
  }
}

ボタンが配置されていたら実装完了!
スクリーンショット 2023-12-14 13.19.58.png

まとめ

ガイドやドキュメントがシンプルで理解しやすく導入の難易度は低め

機能も充実しており、URLのブラックリストを作成して一部ページでは非表示にすることも可能などカスタマイズも幅広く行える

無料で扱える部分も多いので皆様是非使用してみてください

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?