Cách thiết lập kết nối WebSocket?

TA

Tami

Cập nhật lần cuối ngày 17 thg 4, 2023

WebSocket thiết lập kết nối liên tục giữa client và server, cho phép giao tiếp hai chiều. SquareHub sử dụng kết nối này để cung cấp cập nhật theo thời gian thực về các sự kiện trên nền tảng. Để kết nối với WebSocket của SquareHub, chỉ cần cung cấp token và làm theo hướng dẫn thiết lập được trình bày trong bài viết này.

Lưu ý: Tính năng này đang ở giai đoạn thử nghiệm và tài liệu có thể thay đổi theo từng phiên bản. Ngoài ra, khả năng tương thích ngược không được đảm bảo, vì vậy hãy đảm bảo bạn đang sử dụng phiên bản mới nhất của triển khai.

Tại sao nên dùng kết nối WebSocket?

Kết nối WebSocket cho phép cập nhật dữ liệu theo thời gian thực, lý tưởng cho các client như SDK Android hoặc iOS dành cho SquareHub. Điều này giúp cập nhật bảng điều khiển mà không cần tải lại trang, từ đó nâng cao trải nghiệm người dùng và cải thiện năng suất của nhân viên hỗ trợ.

Cách thiết lập kết nối WebSocket với SquareHub?

Để thiết lập kết nối WebSocket với SquareHub, bạn cần khởi tạo kết nối bằng token xác thực PubSub do SquareHub cung cấp. URL kết nối là wss://<your-installation-url>/cable. Nếu bạn đang dùng SquareHub Cloud, có thể sử dụng wss://app.squarehub.com/cable làm URL.

PubSub token là token dùng để xác thực client khi kết nối với dịch vụ PubSub (publish-subscribe). Client phải trình token này cho dịch vụ để thiết lập kết nối và bắt đầu gửi hoặc nhận tin nhắn.

Có hai loại PubSub token trong SquareHub, được liệt kê dưới đây.

  1. User PubSub Token: Token này có quyền của nhân viên hỗ trợ/quản trị viên và sẽ nhận tất cả các sự kiện được liệt kê ở phần sau. Bạn có thể lấy PubSub token bằng cách gọi Profile API.

  2. Contact PubSub Token: SquareHub tạo một PubSub token duy nhất cho mỗi phiên của liên hệ. Token này có thể dùng để kết nối WebSocket và nhận cập nhật thời gian thực cho phiên đó. Khi một liên hệ được tạo qua các public API, pubsub_token sẽ được đưa vào payload phản hồi. Token này chỉ cấp quyền truy cập vào các sự kiện liên quan đến phiên hiện tại, chẳng hạn như conversation.created,  conversation.status_changedmessage.createdmessage.updatedconversation_typing_onconversation_typing_off và presence.update.

Vui lòng tham khảo Client APIs để xây dựng tích hợp hướng đến khách hàng theo thời gian thực với SquareHub.

Lưu ý: Token này có thể được xoay vòng định kỳ tùy theo loại cài đặt của bạn. Hãy đảm bảo bạn luôn sử dụng token mới nhất.

Cách kết nối với WebSocket của SquareHub?

Để kết nối với WebSocket của SquareHub, sử dụng lệnh subscribe và đưa pubSubToken, accountIduserId (nếu dùng user token) vào yêu cầu kết nối. Dưới đây là ví dụ về cách kết nối với SquareHub.

// Add a helper method to convert JSON to a string
const stringify = (payload = {}) => JSON.stringify(payload);

const pubSubToken = "<contact/user-pub-sub-token>";
const accountId = "<your-account-id-in-integer>";
const userId = "<user-id-in-integer-if-using-user-token>";
const connection = new WebSocket(
  "wss://app.squarehub.com/cable"
);

connection.send(
  stringify({
    command: "subscribe",
    identifier: stringify({
      channel: "RoomChannel",
      pubsub_token: pubSubToken,
      account_id: accountId,
      user_id: userId,
    }),
  })
);

// The expected string in connection.send is of the format:
// {"command":"subscribe","identifier":"{\\"channel\\":\\"RoomChannel\\",\\"pubsub_token\\":\\"your-pubsub-token\\",\\"account_id\\": account_id_integer,\\"user_id\\":user_id_integer }"}

Gửi cập nhật trạng thái hiện diện lên server WebSocket

Để duy trì trạng thái trực tuyến cho người dùng trong SquareHub, bạn có thể gửi sự kiện cập nhật trạng thái hiện diện lên SquareHub mỗi 30 giây. Hành động này sẽ giữ trạng thái trực tuyến cho nhân viên hỗ trợ/liên hệ.

Cách cập nhật trạng thái hiện diện của nhân viên hỗ trợ/quản trị viên?

Để cập nhật trạng thái hiện diện của nhân viên hỗ trợ hoặc quản trị viên, gửi payload sau lên server:

const userPayload = stringify({
  command: "message",
  identifier: stringify({
    channel: "RoomChannel",
    pubsub_token: "<user-pubsub-token>",
    account_id: accountId,
    user_id: userId,
  }),
  data: stringify({ action: "update_presence" }),
});

connection.send(userPayload);
// The expected string in connection.send is of the format:
// {"command":"message","identifier":"{\\"channel\\":\\"RoomChannel\\",\\"pubsub_token\\":\\"your-pubsub-token\\",\\"account_id\\": account_id_integer,\\"user_id\\":user_id_integer ","data":"{\\"action\\":\\"update_presence\\"}"}

Cách cập nhật trạng thái hiện diện của liên hệ?

Để cập nhật trạng thái hiện diện của liên hệ, gửi payload sau lên server:

const agentPayload = stringify({
  command: "message",
  identifier: stringify({
    channel: "RoomChannel",
    pubsub_token: "<user-pubsub-token>",
  }),
  data: stringify({ action: "update_presence" }),
});

connection.send(agentPayload);
// The expected string in connection.send is of the format:
// {"command":"message","identifier":"{\\"channel\\":\\"RoomChannel\\",\\"pubsub_token\\":\\"your-pubsub-token\\","data":"{\\"action\\":\\"update_presence\\"}"}

Payload WebSocket

Các đối tượng

Một sự kiện có thể chứa bất kỳ đối tượng nào sau đây trong payload. Các loại đối tượng được SquareHub hỗ trợ như sau.

Conversation

Payload sau sẽ được trả về cho một cuộc hội thoại.

{
  "additional_attributes": {
    "browser": {
      "device_name": "string",
      "browser_name": "string",
      "platform_name": "string",
      "browser_version": "string",
      "platform_version": "string"
    },
    "referer": "string",
    "initiated_at": {
      "timestamp": "iso-datetime"
    }
  },
  "can_reply": "boolean",
  "channel": "string",
  "id": "integer",
  "inbox_id": "integer",
  "contact_inbox": {
    "id": "integer",
    "contact_id": "integer",
    "inbox_id": "integer",
    "source_id": "string",
    "created_at": "datetime",
    "updated_at": "datetime",
    "hmac_verified": "boolean"
  },
  "messages": ["Array of message objects"],
  "meta": {
    "sender": {
      // Contact Object
    },
    "assignee": {
      // User Object
    }
  },
  "status": "string",
  "unread_count": "integer",
  "agent_last_seen_at": "unix-timestamp",
  "contact_last_seen_at": "unix-timestamp",
  "timestamp": "unix-timestamp",
  "account_id": "integer"
}

Contact

Payload sau sẽ được trả về cho một liên hệ.

{
  "additional_attributes": "object",
  "custom_attributes": "object",
  "email": "string",
  "id": "integer",
  "identifier": "string or null",
  "name": "string",
  "phone_number": "string or null",
  "thumbnail": "string"
}

User

Payload sau sẽ được trả về cho một nhân viên hỗ trợ/quản trị viên.

{
  "id": "integer",
  "name": "string",
  "available_name": "string",
  "avatar_url": "string",
  "availability_status": "string",
  "thumbnail": "string"
}

Message

Payload sau sẽ được trả về cho một tin nhắn.

{
  "id": "integer",
  "content": "string",
  "account_id": "integer",
  "inbox_id": "integer",
  "message_type": "integer",
  "created_at": "unix-timestamp",
  "updated_at": "datetime",
  "private": "boolean",
  "status": "string",
  "source_id": "string / null",
  "content_type": "string",
  "content_attributes": "object",
  "sender_type": "string",
  "sender_id": "integer",
  "external_source_ids": "object",
  "sender": {
    "type": "string - contact/user"
    // User or Contact Object
  }
}

Notification

Payload sau sẽ được trả về cho một thông báo.

{
  "id": "integer",
  "notification_type": "string",
  "primary_actor_type": "string",
  "primary_actor_id": "integer",
  "primary_actor": {
    "can_reply": "boolean",
    "channel": "string",
    "id": "integer",
    "inbox_id": "integer",
    "meta": {
      "assignee": {
        "id": "integer",
        "name": "string",
        "available_name": "string",
        "avatar_url": "string",
        "type": "user",
        "availability_status": "string",
        "thumbnail": "string"
      },
      "hmac_verified": "boolean"
    },
    "agent_last_seen_at": "unix-timestamp",
    "contact_last_seen_at": "unix-timestamp",
    "timestamp": "unix-timestamp",
  },
  "read_at": "unix-timestamp",
  "secondary_actor": "object/null",
  "created_at":"unix-timestamp",
  "account_id": "integer",
  "push_message_title": "string"
}

Identifier

Mỗi sự kiện sẽ có thuộc tính identifier theo định dạng sau.

{
  "identifier": "{\\"channel\\":\\"RoomChannel\\",\\"pubsub_token\\":\\"token\\",\\"account_id\\":id,\\"user_id\\":user_id}"
}

Message

Mỗi sự kiện sẽ bao gồm thuộc tính message chứa tên sự kiện và dữ liệu liên quan. Để xem danh sách các sự kiện, hãy tham khảo tài liệu bên dưới.

Các loại sự kiện

conversation.created

Sự kiện này được kích hoạt khi một cuộc hội thoại mới được khởi tạo. Nếu đăng ký theo PubSub token của liên hệ, sự kiện này chỉ bao gồm dữ liệu liên quan đến phiên cụ thể được liên kết với PubSub token đó.

Dành cho: nhân viên hỗ trợ/quản trị viên, liên hệ

{
  "message": {
    "event": "conversation.created",
    "data": {
      // Conversation object will be available here
    }
  }
}

conversation.read

Sự kiện này được kích hoạt và gửi đến các nhân viên hỗ trợ/quản trị viên có quyền truy cập inbox khi một liên hệ đã đọc tin nhắn.

Dành cho: nhân viên hỗ trợ/quản trị viên

{
  "message": {
    "event": "conversation.read",
    "data": {
      // Conversation object will be available here
    }
  }
}

message.created

Sự kiện này được kích hoạt và gửi đến các nhân viên hỗ trợ, quản trị viên, liên hệ khi một tin nhắn mới được tạo trong cuộc hội thoại mà họ có quyền truy cập.

Dành cho: nhân viên hỗ trợ/quản trị viên, liên hệ

{
  "message": {
    "event": "message.created",
    "data": {
      // Message object will be available here
    }
  }
}

message.updated

Sự kiện này được kích hoạt và gửi đến các nhân viên hỗ trợ, quản trị viên, liên hệ khi một tin nhắn được cập nhật trong cuộc hội thoại mà họ có quyền truy cập.

Dành cho: nhân viên hỗ trợ/quản trị viên, liên hệ

{
  "message": {
    "event": "message.updated",
    "data": {
      // Message object will be available here
    }
  }
}

conversation.status_changed

Sự kiện này được gửi đến các nhân viên hỗ trợ, quản trị viên, liên hệ khi trạng thái cuộc hội thoại được cập nhật.

Dành cho: nhân viên hỗ trợ/quản trị viên, liên hệ

{
  "message": {
    "event": "conversation.status_changed",
    "data": {
      // Conversation object will be available here
    }
  }
}

conversation.typing_on

Sự kiện này được gửi đến các nhân viên hỗ trợ, quản trị viên, liên hệ khi một liên hệ hoặc nhân viên hỗ trợ bắt đầu nhập phản hồi.

Dành cho: nhân viên hỗ trợ/quản trị viên, liên hệ

{
  "message": {
    "event": "conversation.typing_on",
    "data": {
      "conversation": {
        // Conversation object will be available here
      },
      "user": {
        // Contact / Agent,Admin User object will be available here.
      },
      "is_private": "boolean", // Shows whether the agent is typing a private note or not.
      "account_id": "integer"
    }
  }
}

conversation.typing_off

Sự kiện này được gửi đến các nhân viên hỗ trợ, quản trị viên, liên hệ khi một liên hệ hoặc nhân viên hỗ trợ dừng nhập phản hồi.

Dành cho: nhân viên hỗ trợ/quản trị viên, liên hệ

{
  "message": {
    "event": "conversation.typing_off",
    "data": {
      "conversation": {
        // Conversation object will be available here
      },
      "user": {
        // Contact / User object will be available here.
      },
      "account_id": "integer"
    }
  }
}

assignee.changed

Sự kiện này được gửi đến các nhân viên hỗ trợ/quản trị viên có quyền truy cập inbox khi nhân viên hỗ trợ được phân công thay đổi.

Dành cho: nhân viên hỗ trợ/quản trị viên

{
  "message": {
    "event": "assignee.changed",
    "data": {
      // Conversation object will be available here
    }
  }
}

team.changed

Sự kiện này được gửi đến các nhân viên hỗ trợ/quản trị viên có quyền truy cập inbox khi nhóm được phân công thay đổi.

Dành cho: nhân viên hỗ trợ/quản trị viên

{
  "message": {
    "event": "team.changed",
    "data": {
      // Conversation object will be available here
    }
  }
}

conversation.contact_changed

Sự kiện này được gửi đến các nhân viên hỗ trợ/quản trị viên khi hai liên hệ được hợp nhất và toàn bộ cuộc hội thoại của họ được gộp về một liên hệ duy nhất.

Dành cho: nhân viên hỗ trợ/quản trị viên

{
  "message": {
    "event": "conversation.contact_changed",
    "data": {
      // Conversation object will be available here
    }
  }
}

contact.created

Sự kiện này được gửi đến các nhân viên hỗ trợ/quản trị viên khi một liên hệ được tạo.

Dành cho: nhân viên hỗ trợ/quản trị viên

{
  "message": {
    "event": "contact.created",
    "data": {
      // Contact object will be available here
    }
  }
}

contact.updated

Sự kiện này được gửi đến các nhân viên hỗ trợ/quản trị viên khi một liên hệ được cập nhật.

Dành cho: nhân viên hỗ trợ/quản trị viên

{
  "message": {
    "event": "contact.updated",
    "data": {
      // Contact object will be available here
    }
  }
}

presence.update

Có sẵn cho cả nhân viên hỗ trợ và liên hệ, sự kiện này cung cấp cập nhật theo thời gian thực về trạng thái hoạt động của người dùng trong hệ thống. Sự kiện gửi đến liên hệ sẽ không bao gồm thông tin về trạng thái hoạt động của các liên hệ khác.

Dành cho: nhân viên hỗ trợ/quản trị viên

{
  "message": {
    "event": "presence.update",
    "data": {
      "account_id": "integer",
      "users": {
        "user-id": "string"
      },
      "contacts": {
        "contact-id": "string"
      }
    }
  }
}

notification_created

Sự kiện này được gửi đến các nhân viên hỗ trợ/quản trị viên khi một thông báo được tạo.

Dành cho: nhân viên hỗ trợ/quản trị viên