messageep

package
v1.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 23, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ApproveSendDraftEndpoint

type ApproveSendDraftEndpoint struct{}

Approves a reply draft and sends it to the customer.

The draft becomes the sent message rather than spawning a copy: it takes its place in the case timeline, and the customer sees it as coming from "Customer Service". A draft on the email channel goes out as a reply on the case's email thread; otherwise it appears in the customer's conversation. Sending also moves the case to waiting on the customer.

Only the first approval of a draft sends it — approving one that is no longer open fails, so a concurrent double-approve cannot reach the customer twice. Customer accounts cannot approve drafts.

func (*ApproveSendDraftEndpoint) Materialize

type ApproveSendDraftRequest

type ApproveSendDraftRequest struct {
	// The id of the draft to approve.
	MessageID string `path:"id" validate:"required"`
	// A unique client-generated key for this approval, such as a UUID.
	ClientMessageID string `json:"client_message_id" validate:"required"`
}

Request to approve a customer-reply draft and send it to the customer.

func (*ApproveSendDraftRequest) SchemaExample

func (*ApproveSendDraftRequest) SchemaExample() any

type CancelScheduledEndpoint

type CancelScheduledEndpoint struct{}

Cancels a message that was scheduled for a future send, so it is never delivered.

You can only cancel a message you scheduled yourself, and only while it is still waiting to go out — once it has been delivered or has otherwise left the scheduled state, the request fails. The canceled message is kept as a record and never appears in the conversation.

func (*CancelScheduledEndpoint) Materialize

type CancelScheduledRequest

type CancelScheduledRequest struct {
	// The id of the scheduled message to cancel.
	MessageID string `path:"id" validate:"required"`
}

Request to cancel a pending scheduled message.

type ListMessagesEndpoint

type ListMessagesEndpoint struct{}

Returns the messages in a conversation, newest first.

You must be an active participant. A customer reading their own case receives only the messages meant for them — internal team notes are never included.

type ListMessagesRequest

type ListMessagesRequest struct {
	apiresource.PaginationRequest
	// Conversation ID.
	ConversationID string `path:"id" validate:"required"`
	// Which set of the conversation's messages to return.
	//
	// Left unset, you get the delivered timeline. Pass `draft` for the case's reply drafts awaiting approval, or `scheduled` for the messages you yourself have queued for a future send, soonest first. Those two ignore paging and come back in a single response.
	Status *constants.MessageStatus `query:"status"`
	// Return only messages that come after this position in the timeline.
	//
	// Use it to catch up after a dropped realtime connection: pass the sequence of the last message you already have to fetch everything since.
	AfterSequence *int64 `query:"after_sequence"`
}

Request to list a conversation's messages.

type MessageAttachmentInput

type MessageAttachmentInput struct {
	// What is being attached.
	//
	// - `file`: a document you uploaded to object storage first.
	// - `image`: an uploaded image, rendered inline in the conversation.
	// - `link`: an external web address, with nothing stored on our side.
	// - `resource`: a reference to an in-app record, such as an order.
	Kind constants.MessageAttachmentKind `json:"kind" validate:"required"`
	// The key you uploaded the file to, taken from the upload-url response (file and image).
	//
	// The key must be one minted for this conversation and the file must already be uploaded, otherwise the send is rejected.
	S3Key field.Optional[string] `json:"s3_key,omitzero"`
	// The filename to display for the attachment (file and image).
	Filename field.Optional[string] `json:"filename,omitzero"`
	// The MIME content type of the uploaded file (file and image).
	ContentType field.Optional[string] `json:"content_type,omitzero"`
	// The size of the uploaded file in bytes (file and image).
	SizeBytes field.Optional[int64] `json:"size_bytes,omitzero"`
	// The web address being shared (link).
	URL field.Optional[string] `json:"url,omitzero"`
	// The type of the record being referenced, paired with `resource_id` (resource).
	ResourceType field.Optional[string] `json:"resource_type,omitzero"`
	// The id of the record being referenced, paired with `resource_type` (resource).
	ResourceID field.Optional[string] `json:"resource_id,omitzero"`
}

A single attachment supplied when sending a message.

For an uploaded file or image, supply the `s3_key` you uploaded to; for a link, supply `url`; for a resource reference, supply `resource_type` and `resource_id`.

type MessageSvc

MessageSvc backs the chat message endpoints via the notification-service ChatService gRPC client. A message is the single resource for sent, scheduled, and draft content; the lifecycle endpoints (send, schedule, draft create/update/approve/reject/cancel) all return a Message.

func NewMessageSvc

func NewMessageSvc(config *MessageSvcConfig) MessageSvc

type MessageSvcConfig

type MessageSvcConfig struct {
	// ChatClient (required) is the notification-service ChatService gRPC client.
	ChatClient pb.ChatServiceClient
}

type RejectDraftEndpoint

type RejectDraftEndpoint struct{}

Discards a reply draft without sending it to the customer.

The draft is kept as a rejected record for history and can no longer be edited or approved. Because the customer is still owed an answer, the case moves back to waiting on your team.

func (*RejectDraftEndpoint) Materialize

type RejectDraftRequest

type RejectDraftRequest struct {
	// The id of the draft to reject.
	MessageID string `path:"id" validate:"required"`
}

Request to discard an open customer-reply draft without sending it.

type SendMessageEndpoint

type SendMessageEndpoint struct{}

Posts a message to a conversation.

With `mode` = `send` the message is delivered — immediately, or queued when `scheduled_at` is set — and a retry of an immediate send with the same `client_message_id` returns the original message rather than posting it twice. With `mode` = `draft` the message is proposed as a reply to the customer and held for a teammate to approve instead of being sent, and `channel` is required.

Sending requires you to be an active participant allowed to post: view-only participants cannot post, and in a direct message neither side of a block can. On a customer-facing case, replying to the customer moves the case to waiting on the customer, and proposing a draft moves it to awaiting approval.

func (*SendMessageEndpoint) Materialize

type SendMessageRequest

type SendMessageRequest struct {
	// Conversation ID.
	ConversationID string `path:"id" validate:"required"`
	// Message body.
	//
	// Required unless the message carries at least one attachment or a resource link.
	Body string `json:"body" validate:"required_without_all=Attachments LinkResourceID"`
	// Whether to deliver the message now or hold it as a customer-reply draft.
	//
	// - `send`: delivers the message, immediately or at `scheduled_at`.
	// - `draft`: proposes a reply to the customer on a customer-facing case and holds it for a teammate to approve before it goes out. Requires `channel`.
	//
	// A draft is built from `body`, `subject`, `channel`, and `source_thread_message_id` only — attachments, mentions, copied recipients, resource links, replies, and scheduling are not carried onto it.
	Mode field.Optional[constants.MessageSendMode] `json:"mode,omitzero" default:"send"`
	// The channel a draft will be sent over once it is approved (`mode` = `draft`).
	//
	// - `message`: appears in the customer's conversation timeline.
	// - `email`: goes out as an email from the inbox the case is bridged to. Falls back to the conversation timeline if the case has no bridged inbox.
	Channel field.Optional[constants.MessageChannel] `json:"channel,omitzero"`
	// The internal thread message a draft is composed from, when drafting from a thread (`mode` = `draft`).
	SourceThreadMessageID field.Optional[string] `json:"source_thread_message_id,omitzero"`
	// Client-supplied dedupe key.
	//
	// Repeating an immediate send with the same value returns the message created by the first request instead of posting a second one, so a retry after a network failure is safe. Required when sending (`mode` = `send`); ignored for drafts.
	ClientMessageID string `json:"client_message_id,omitzero"`
	// Who the message is addressed to on a customer-facing case.
	//
	// - `customer`: a reply the customer sees, shown to them as coming from "Customer Service" and delivered as email when the case is bridged to an inbox.
	// - `internal`: a team-only note the customer never sees.
	//
	// Messages are team-only unless you ask for `customer`, so an internal note can never leak by omission. Asking for `customer` on a conversation that has no customer is rejected.
	//
	// On a case bridged to an email inbox, a customer reply goes out as mail carrying only the body, subject, and copied recipients — attachments, mentions, resource links, and replies are dropped.
	Audience field.Optional[constants.ConversationAudience] `json:"audience,omitzero" default:"internal"`
	// The subject line for a customer reply sent by email.
	//
	// When omitted, the reply goes out as "Re:" the case title.
	Subject field.Optional[string] `json:"subject,omitzero"`
	// Additional email addresses to copy on a customer reply sent by email.
	Cc []string `json:"cc,omitzero"`
	// When set, hold the message and deliver it at this future time instead of sending it now.
	//
	// Only the body is carried into a scheduled send — attachments, mentions, copied recipients, resource links, replies, and audience are dropped, and it is delivered as an ordinary team-visible message. If you are no longer an active participant when it comes due, it is canceled instead of sent.
	ScheduledAt field.Optional[time.Time] `json:"scheduled_at,omitzero"`
	// The message this one is a reply to.
	ReplyToMessageID field.Optional[string] `json:"reply_to_message_id,omitzero"`
	// Type of a resource to link in the message, paired with `link_resource_id`.
	//
	// Linking a record lets clients render the message as a reference to it. A link counts in place of text, so a message may consist of nothing but the link.
	LinkResourceType field.Optional[constants.ObjectType] `json:"link_resource_type,omitzero"`
	// ID of a resource to link in the message, paired with `link_resource_type`.
	LinkResourceID field.Optional[string] `json:"link_resource_id,omitzero"`
	// Attachments to include with the message.
	Attachments []MessageAttachmentInput `json:"attachments,omitzero"`
	// Account user ids explicitly @mentioned in the message.
	//
	// A mention notifies the person even when they have muted the conversation.
	Mentions []string `json:"mentions,omitzero"`
}

Request to post a message to a conversation.

func (*SendMessageRequest) SchemaExample

func (*SendMessageRequest) SchemaExample() any

type UpdateDraftEndpoint

type UpdateDraftEndpoint struct{}

Revises a reply draft before it is sent to the customer.

Only a draft that is still awaiting approval can be edited; once it has been approved, rejected, or superseded the request fails. Nothing reaches the customer until the draft is approved.

func (*UpdateDraftEndpoint) Materialize

type UpdateDraftRequest

type UpdateDraftRequest struct {
	// The id of the draft to edit.
	MessageID string `path:"id" validate:"required"`
	// The revised reply body, replacing what the draft said before.
	Body string `json:"body" validate:"required"`
	// The revised subject line for a draft that will be sent by email.
	//
	// Leaving it out keeps the draft's current subject.
	Subject field.Optional[string] `json:"subject,omitzero"`
}

Request to edit a still-open customer-reply draft message.

func (*UpdateDraftRequest) SchemaExample

func (*UpdateDraftRequest) SchemaExample() any

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL