From f413cf16dd316ff6aa4956e5eb57b5bfd60f250a Mon Sep 17 00:00:00 2001 From: Gildas Cherruel Date: Fri, 22 Apr 2022 19:04:33 +0900 Subject: [PATCH 1/3] SendInboundAttachment should receive an OpenMessagingAttachment --- openmessaging_attachment.go | 41 +++++++++++++++++++++++++++++++++++- openmessaging_integration.go | 41 ++++-------------------------------- 2 files changed, 44 insertions(+), 38 deletions(-) diff --git a/openmessaging_attachment.go b/openmessaging_attachment.go index 580c57d..31e3e42 100644 --- a/openmessaging_attachment.go +++ b/openmessaging_attachment.go @@ -2,14 +2,19 @@ package gcloudcx import ( "encoding/json" + "mime" "net/url" + "path" + "strings" "github.com/gildas/go-core" "github.com/gildas/go-errors" + "github.com/gildas/go-request" + nanoid "github.com/matoous/go-nanoid/v2" ) type OpenMessageAttachment struct { - ID string `json:"id"` + ID string `json:"id,omitempty"` Type string `json:"mediaType"` URL *url.URL `json:"-"` Mime string `json:"mime,omitempty"` @@ -18,6 +23,40 @@ type OpenMessageAttachment struct { Hash string `json:"sha256,omitempty"` } +func (attachment OpenMessageAttachment) WithContent(content *request.Content) *OpenMessageAttachment { + var attachmentType string + switch { + case len(content.Type) == 0: + attachmentType = "Link" + case strings.HasPrefix(content.Type, "audio"): + attachmentType = "Audio" + case strings.HasPrefix(content.Type, "image"): + attachmentType = "Image" + case strings.HasPrefix(content.Type, "video"): + attachmentType = "Video" + default: + attachmentType = "File" + } + + attachment.Type = attachmentType + attachment.Mime = content.Type + attachment.Filename = content.Name + attachment.URL = content.URL + + if attachmentType != "Link" && len(content.Name) == 0 { + fileExtension := path.Ext(content.URL.Path) + if content.Type == "audio/mpeg" { + fileExtension = ".mp3" + } else if fileExtensions, err := mime.ExtensionsByType(content.Type); err == nil && len(fileExtensions) > 0 { + fileExtension = fileExtensions[0] + } + fileID, _ := nanoid.New() + attachment.Filename = strings.ToLower(attachmentType) + "-" + fileID + fileExtension + } + + return &attachment +} + // MarshalJSON marshals this into JSON func (attachment OpenMessageAttachment) MarshalJSON() ([]byte, error) { type surrogate OpenMessageAttachment diff --git a/openmessaging_integration.go b/openmessaging_integration.go index b41a1f0..4b45343 100644 --- a/openmessaging_integration.go +++ b/openmessaging_integration.go @@ -3,9 +3,7 @@ package gcloudcx import ( "context" "encoding/json" - "mime" "net/url" - "path" "strings" "time" @@ -13,7 +11,6 @@ import ( "github.com/gildas/go-errors" "github.com/gildas/go-logger" "github.com/google/uuid" - nanoid "github.com/matoous/go-nanoid/v2" ) // OpenMessagingIntegration describes an GCloud OpenMessaging Integration @@ -255,41 +252,17 @@ func (integration *OpenMessagingIntegration) SendInboundMessage(context context. // // See https://developer.genesys.cloud/api/digital/openmessaging/inboundMessages#inbound-message-with-attached-photo // See https://developer.genesys.cloud/api/rest/v2/conversations/#post-api-v2-conversations-messages-inbound-open -func (integration *OpenMessagingIntegration) SendInboundMessageWithAttachment(context context.Context, from *OpenMessageFrom, messageID, text string, attachmentURL *url.URL, attachmentMimeType, attachmentID string, attributes map[string]string, metadata map[string]string) (id string, err error) { +func (integration *OpenMessagingIntegration) SendInboundMessageWithAttachment(context context.Context, from *OpenMessageFrom, messageID, text string, attachment *OpenMessageAttachment, attributes map[string]string, metadata map[string]string) (id string, err error) { if integration.ID == uuid.Nil { return "", errors.ArgumentMissing.With("ID") } if len(messageID) == 0 { return "", errors.ArgumentMissing.With("messageID") } - if attachmentURL == nil { + if attachment.URL == nil { return "", errors.ArgumentMissing.With("url") } - var attachmentType string - switch { - case len(attachmentMimeType) == 0: - attachmentType = "Link" - case strings.HasPrefix(attachmentMimeType, "audio"): - attachmentType = "Audio" - case strings.HasPrefix(attachmentMimeType, "image"): - attachmentType = "Image" - case strings.HasPrefix(attachmentMimeType, "video"): - attachmentType = "Video" - default: - attachmentType = "File" - } - - var attachmentFilename string - if attachmentType != "Link" { - fileExtension := path.Ext(attachmentURL.Path) - if fileExtensions, err := mime.ExtensionsByType(attachmentMimeType); err == nil && len(fileExtensions) > 0 { - fileExtension = fileExtensions[0] - } - fileID, _ := nanoid.New() - attachmentFilename = strings.ToLower(attachmentType) + "-" + fileID + fileExtension - } - result := OpenMessageText{} err = integration.client.Post( integration.logger.ToContext(context), @@ -304,14 +277,8 @@ func (integration *OpenMessagingIntegration) SendInboundMessageWithAttachment(co Text: text, Content: []*OpenMessageContent{ { - Type: "Attachment", - Attachment: &OpenMessageAttachment{ - Type: attachmentType, - ID: attachmentID, - Mime: attachmentMimeType, - URL: attachmentURL, - Filename: attachmentFilename, - }, + Type: "Attachment", + Attachment: attachment, }, }, Metadata: metadata, From f0ec2a2e32eb487dbca6b3e9ed9dcc13db4cf81b Mon Sep 17 00:00:00 2001 From: Gildas Cherruel Date: Thu, 28 Apr 2022 16:41:48 +0900 Subject: [PATCH 2/3] message details struct fixes --- conversation.go | 23 ++++++++++++++++++++++ conversation_message.go | 42 +++++++++-------------------------------- message.go | 28 +++++++++++++++++++++++++++ participant.go | 8 ++++++++ 4 files changed, 68 insertions(+), 33 deletions(-) create mode 100644 message.go diff --git a/conversation.go b/conversation.go index 67a9fea..440df51 100644 --- a/conversation.go +++ b/conversation.go @@ -14,6 +14,7 @@ type Conversation struct { ID uuid.UUID `json:"id"` SelfURI URI `json:"selfUri,omitempty"` Name string `json:"name"` + ExternalTag string `json:"externalTag,omitempty"` StartTime time.Time `json:"startTime"` EndTime time.Time `json:"endTime"` Address string `json:"address"` @@ -118,6 +119,28 @@ func (conversation Conversation) String() string { return conversation.ID.String() } +// Disconnect disconnect an Identifiable from this +// implements Disconnecter +func (conversation Conversation) Disconnect(context context.Context, identifiable Identifiable) error { + return conversation.client.Patch( + conversation.logger.ToContext(context), + NewURI("/conversations/%s/participants/%s", conversation.ID, identifiable.GetID()), + MediaParticipantRequest{State: "disconnected"}, + nil, + ) +} + +// UpdateState update the state of an identifiable in this +// implements StateUpdater +func (conversation Conversation) UpdateState(context context.Context, identifiable Identifiable, state string) error { + return conversation.client.Patch( + conversation.logger.ToContext(context), + NewURI("/conversations/%s/participants/%s", conversation.ID, identifiable.GetID()), + MediaParticipantRequest{State: state}, + nil, + ) +} + /* func (conversation *Conversation) GetParticipants(context context.Context) []*Participant { log := conversation.logger.Child(nil, "participants") diff --git a/conversation_message.go b/conversation_message.go index 839fbca..255f527 100644 --- a/conversation_message.go +++ b/conversation_message.go @@ -9,19 +9,18 @@ import ( // ConversationMessage describes a Message (like belonging to Participant) type ConversationMessage struct { ID uuid.UUID `json:"id"` + Type string `json:"type"` Direction string `json:"direction"` // inbound,outbound State string `json:"state"` // alerting,dialing,contacting,offering,connected,disconnected,terminated,converting,uploading,transmitting,scheduled,none Held bool `json:"held"` - RecordingID string `json:"recordingId"` + RecordingID string `json:"recordingId,omitempty"` Segments []Segment `json:"segments"` Provider string `json:"provider"` - ScriptID string `json:"scriptId"` - PeerID string `json:"peerId"` - Type string `json:"type"` - RecipientCountry string `json:"recipientCountry"` - RecipientType string `json:"recipientType"` + ScriptID string `json:"scriptId,omitempty"` + PeerID uuid.UUID `json:"peerId"` + RecipientCountry string `json:"recipientCountry,omitempty"` ToAddress Address `json:"toAddress"` FromAddress Address `json:"fromAddress"` @@ -30,34 +29,11 @@ type ConversationMessage struct { StartAlertingTime time.Time `json:"startAlertingTime"` StartHoldTime time.Time `json:"startHoldTime"` - Messages []MessageDetail `json:"messages"` + Messages []MessageDetails `json:"messages"` DisconnectType string `json:"disconnectType"` // endpoint,client,system,transfer,timeout,transfer.conference,transfer.consult,transfer.forward,transfer.noanswer,transfer.notavailable,transport.failure,error,peer,other,spam,uncallable ErrorInfo ErrorBody `json:"errorInfo"` -} - -// MessageDetail describes details about a Message -type MessageDetail struct { - ID string `json:"messageId"` - MessageURI string `json:"messageURI"` - Status string `json:"messageStatus"` - SegmentCount string `json:"messageSegmentCount"` - Time time.Time `json:"messageTime"` - Media MessageMedia `json:"media"` - Stickers []MessageSticker `json:"stickers"` -} - -// MessageMedia describes the Media of a Message -type MessageMedia struct { - ID string `json:"id"` - Name string `json:"name"` - URL string `json:"url"` - MediaType string `json:"mediaType"` - ContentLength string `json:"contentLengthBytes"` -} - -// MessageSticker describes a Message Sticker -type MessageSticker struct { - ID string `json:"id"` - URL string `json:"url"` + // Screenshares []ScreenShare `json:"screenshares"` + // SocialExpressions []SocialExpression `json:"socialExpressions"` + // Videos []Video `json:"videos"` } diff --git a/message.go b/message.go new file mode 100644 index 0000000..0326ab7 --- /dev/null +++ b/message.go @@ -0,0 +1,28 @@ +package gcloudcx + +import "time" + +// MessageDetails describes details of a Message in a Message Conversation +type MessageDetails struct { + ID string `json:"messageId"` + Status string `json:"messageStatus"` + SegmentCount int `json:"messageSegmentCount"` + Time time.Time `json:"messageTime"` + Media []MessageMedia `json:"media"` + Stickers []MessageSticker `json:"stickers"` +} + +// MessageMedia describes the Media of a Message +type MessageMedia struct { + ID string `json:"id"` + Name string `json:"name"` + URL string `json:"url"` + MediaType string `json:"mediaType"` + ContentLength int64 `json:"contentLengthBytes"` +} + +// MessageSticker describes a Message Sticker +type MessageSticker struct { + ID string `json:"id"` + URL string `json:"url"` +} diff --git a/participant.go b/participant.go index be8aa01..52ead97 100644 --- a/participant.go +++ b/participant.go @@ -37,6 +37,7 @@ type Participant struct { Queue *Queue `json:"queue,omitempty"` QueueID string `json:"queueId,omitempty"` GroupID string `json:"groupId,omitempty"` + TeamID string `json:"teamId,omitempty"` QueueName string `json:"queueName,omitempty"` ConsultParticipantID string `json:"consultParticipantId,omitempty"` MonitoredParticipantID string `json:"monitoredParticipantId,omitempty"` @@ -167,6 +168,11 @@ func (participant Participant) String() string { return participant.ID.String() } +// Disconnect disconnects the Participant from the target +func (participant *Participant) Disconnect(context context.Context, target Disconnecter) error { + return target.Disconnect(context, participant) +} + // UpdateState updates the state of the Participant in target func (participant *Participant) UpdateState(context context.Context, target StateUpdater, state string) error { return target.UpdateState(context, participant, state) @@ -202,6 +208,8 @@ func (participant *Participant) UnmarshalJSON(payload []byte) (err error) { type surrogate Participant var inner struct { surrogate + QueueID uuid.UUID `json:"queueId"` + QueueName string `json:"queueName"` UserID uuid.UUID `json:"userId"` UserURI URI `json:"userUri"` AlertingTimeoutMs int64 `json:"alertingTimeoutMs"` From a247a380b0855fd7e049398b132e0aac5a5fa151 Mon Sep 17 00:00:00 2001 From: Gildas Cherruel Date: Fri, 29 Apr 2022 00:46:36 +0900 Subject: [PATCH 3/3] Bumped to version 0.7.12 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index b6109ac..3978937 100644 --- a/version.go +++ b/version.go @@ -4,7 +4,7 @@ package gcloudcx var commit string // VERSION is the version of this application -var VERSION = "0.7.11" + commit +var VERSION = "0.7.12" + commit // APP is the name of the application const APP string = "GCloudCX Client"