syntax = "proto3"; option go_package = ".;main"; import "google/protobuf/timestamp.proto"; // Support provides an interactive chat service, for customers to interact with // the bank's support agents. A single stream, for either of the two methods, is // a stateful connection to a single "chat session". Streams are initially disconnected // (not part of any session). A stream must be disconnected from a session (via customer // hang up or via agent leaving a session) before it can be connected to a new one. service Support { // ChatCustomer is used by a customer-facing app to send the customer's messages // to a chat session. The customer is how initiates and terminates (via "hangup") // a chat session. Only customers may invoke this method (e.g. requests must // include customer auth credentials). rpc ChatCustomer(stream ChatCustomerRequest) returns (stream ChatCustomerResponse); // ChatAgent is used by an agent-facing app to allow an agent to reply to a // customer's messages in a chat session. The agent may accept a chat session, // which defaults to the session awaiting an agent for the longest period of time // (FIFO queue). rpc ChatAgent(stream ChatAgentRequest) returns (stream ChatAgentResponse); } enum Void { VOID = 0; } message ChatCustomerRequest { oneof req { // init is used when a chat stream is not part of a // chat session. This is a stream's initial state, as well as // the state after a "hang_up" request is sent. This creates // a new state session or resumes an existing one. InitiateChat init = 1; // msg is used to send the customer's messages to support // agents. string msg = 2; // hang_up is used to terminate a chat session. If a stream // is broken, but the session was not terminated, the client // may initiate a new stream and use init to resume that // session. Sessions are not terminated unless done so // explicitly via sending this kind of request on the stream. Void hang_up = 3; } } message InitiateChat { string resume_session_id = 1; } message AgentMessage { string agent_name = 1; string msg = 2; } message ChatCustomerResponse { oneof resp { // session is sent from the server when the stream is connected // to a chat session. This happens after an init request is sent // and the stream is connected to either a new or resumed session. Session session = 1; // msg is sent from the server to convey agents' messages to the // customer. AgentMessage msg = 2; } } message ChatAgentRequest { oneof req { // accept is used when an agent wants to join a customer chat // session. It can be used to connect to a specific session (by // ID), or to just accept the session for which the customer has // been waiting the longest (e.g. poll a FIFO queue of sessions // awaiting a support agent). It is possible for multiple agents // to be connected to the same chat session. AcceptChat accept = 1; // msg is used to send a message to the customer. It will also be // delivered to any other connected support agents. string msg = 2; // leave_session allows an agent to exit a chat session. They can // always re-enter later by sending an accept message for that // session ID. Void leave_session = 3; } } message AcceptChat { string session_id = 1; } message ChatEntry { google.protobuf.Timestamp date = 1; oneof entry { string customer_msg = 2; AgentMessage agent_msg = 3; } } message ChatAgentResponse { oneof resp { // accepted_session provides the detail of a chat session. The server // sends this message after the agent has accepted a chat session. Session accepted_session = 1; // msg is sent by the server when the customer, or another support // agent, sends a message in stream's current session. ChatEntry msg = 2; // session_ended notifies the support agent that their currently // connected chat session has been terminated by the customer. Void session_ended = 3; } } message Session { string session_id = 1; string customer_name = 2; repeated ChatEntry history = 3; }