Champagne

Customer chats

Let members and staff start conversations on any subject, outside of a reservation.

A customer chat is a conversation between one person of the club (a member or an applicant) and the club team about a subject of their choice. Either side can start it, and a person can keep several chats open at once. Reservation conversations stay attached to their reservation (see Reservations).

Staff need the customer_chats permission in the club; club administrators always have it. Members can only reach their own chats in the club of their session.

Staff inbox

query CustomerChats($clubId: ID!, $archived: Boolean!) {
  customerChats(clubId: $clubId, archived: $archived) {
    id
    personId
    personName
    subject
    createdAt
    archivedAt
    unread
    lastMessage {
      author
      senderName
      body
      createdAt
    }
  }
}
ArgumentTypeDescription
clubIdID!Club whose chats are listed.
archivedBoolean!false (default) lists active chats, true the archived ones.

Every staff member with access sees every chat of the club, sorted by latest message first. unread and archivedAt belong to the caller: a chat is unread while a customer message is newer than the caller's last read, and archiving it never affects another staff member. Any new message, from either side, restores the chat to every staff member's active list.

query CustomerChat($clubId: ID!, $chatId: ID!) {
  customerChat(clubId: $clubId, chatId: $chatId) {
    id
    personId
    personName
    subject
    messages {
      id
      author
      senderName
      body
      createdAt
    }
  }
}

mutation ReadCustomerChat($clubId: ID!, $chatId: ID!) {
  markCustomerChatRead(clubId: $clubId, chatId: $chatId)
}

mutation ArchiveCustomerChat($clubId: ID!, $chatId: ID!) {
  setCustomerChatArchived(clubId: $clubId, chatId: $chatId, archived: true)
}

customerChat returns null for a chat of another club. Messages are ordered oldest first; author is customer or professional. markCustomerChatRead and setCustomerChatArchived return false when the chat does not exist in the club.

Start and answer as staff

mutation StartCustomerChat($clubId: ID!, $personId: ID!, $subject: String!, $body: String!) {
  startCustomerChat(clubId: $clubId, personId: $personId, subject: $subject, body: $body) {
    id
    subject
  }
}

mutation PostCustomerChatMessage($clubId: ID!, $chatId: ID!, $body: String!) {
  postCustomerChatMessage(clubId: $clubId, chatId: $chatId, body: $body) {
    id
    messages {
      id
      body
    }
  }
}

The person must belong to clubId. Messages are signed with the staff member's name, or Club team when it is empty, and are immediately read for the sender. Each staff message sends the member a chat notification in the app and by email (according to their preferences) linking to /account/chats/{chatId}, and emits the chat.message webhook. Starting a chat is recorded as customer_chat.started and later replies as customer_chat.message_posted in the staff activity log.

Member operations

query MyCustomerChats($clubId: ID!) {
  myCustomerChats(clubId: $clubId) {
    id
    subject
    unread
    lastMessage {
      author
      senderName
      body
      createdAt
    }
  }
}

mutation StartMyCustomerChat($clubId: ID!, $subject: String!, $body: String!) {
  startMyCustomerChat(clubId: $clubId, subject: $subject, body: $body) {
    id
  }
}

myCustomerChat(clubId, chatId), postMyCustomerChatMessage(clubId, chatId, body) and markMyCustomerChatRead(clubId, chatId) complete the member API. A member chat is unread while a professional message is newer than the member's last read; the member's own messages count as read. Chats of another member return null (or false for markMyCustomerChatRead). Members of another club and staff accounts receive UNAUTHENTICATED. Customer messages are signed with the member's name and do not notify staff beyond the unread state of their inbox.

Validation

Subjects are trimmed and must contain 1 to 120 characters; message bodies are trimmed and must contain 1 to 4000 characters. Invalid IDs and out-of-range values return BAD_USER_INPUT.

On this page