From 799e81a97795b070260817b35e2ab6f44a2591d9 Mon Sep 17 00:00:00 2001 From: h3rby7 Date: Wed, 22 Jun 2022 14:31:19 +0200 Subject: [PATCH 1/4] first steps to post metadata on chat.postMessage --- chat.go | 19 +++++++++++++++++++ messages.go | 3 +++ metadata.go | 7 +++++++ 3 files changed, 29 insertions(+) create mode 100644 metadata.go diff --git a/chat.go b/chat.go index 34848d151..1c498b2af 100644 --- a/chat.go +++ b/chat.go @@ -64,6 +64,9 @@ type PostMessageParameters struct { // chat.postEphemeral support Channel string `json:"channel"` User string `json:"user"` + + // chat metadata support + MetaData SlackMetadata `json:"metadata"` } // NewPostMessageParameters provides an instance of PostMessageParameters with all the sane default values set @@ -285,6 +288,7 @@ type sendConfig struct { endpoint string values url.Values attachments []Attachment + metadata SlackMetadata blocks Blocks responseType string replaceOriginal bool @@ -306,6 +310,7 @@ func (t sendConfig) BuildRequestContext(ctx context.Context, token, channelID st endpoint: t.endpoint, values: t.values, attachments: t.attachments, + metadata: t.metadata, blocks: t.blocks, responseType: t.responseType, replaceOriginal: t.replaceOriginal, @@ -336,6 +341,7 @@ type responseURLSender struct { endpoint string values url.Values attachments []Attachment + metadata SlackMetadata blocks Blocks responseType string replaceOriginal bool @@ -352,6 +358,7 @@ func (t responseURLSender) BuildRequestContext(ctx context.Context) (*http.Reque Timestamp: t.values.Get("ts"), Attachments: t.attachments, Blocks: t.blocks, + Metadata: t.metadata, ResponseType: t.responseType, ReplaceOriginal: t.replaceOriginal, DeleteOriginal: t.deleteOriginal, @@ -662,6 +669,18 @@ func MsgOptionIconEmoji(iconEmoji string) MsgOption { } } +// MsgOptionIconEmoji sets an icon emoji +func MsgOptionMetadata(metadata SlackMetadata) MsgOption { + return func(config *sendConfig) error { + config.metadata = metadata + meta, err := json.Marshal(metadata) + if err == nil { + config.values.Set("metadata", string(meta)) + } + return err + } +} + // UnsafeMsgOptionEndpoint deliver the message to the specified endpoint. // NOTE: USE AT YOUR OWN RISK: No issues relating to the use of this Option // will be supported by the library, it is subject to change without notice that diff --git a/messages.go b/messages.go index 1a3110e44..828fa6026 100644 --- a/messages.go +++ b/messages.go @@ -129,6 +129,9 @@ type Msg struct { ReplaceOriginal bool `json:"replace_original"` DeleteOriginal bool `json:"delete_original"` + // Block type Message + Metadata SlackMetadata `json:"metadata,omitempty"` + // Block type Message Blocks Blocks `json:"blocks,omitempty"` // permalink diff --git a/metadata.go b/metadata.go new file mode 100644 index 000000000..260471236 --- /dev/null +++ b/metadata.go @@ -0,0 +1,7 @@ +package slack + +// SlackMetadata https://api.slack.com/reference/metadata +type SlackMetadata struct { + EventType string `json:"event_type"` + EventPayload interface{} `json:"event_payload"` +} From 2a8832bf35614920fca9d22bb7bc4ed63119ec09 Mon Sep 17 00:00:00 2001 From: h3rby7 Date: Thu, 23 Jun 2022 14:53:36 +0200 Subject: [PATCH 2/4] add test for metadata sending, switch 'event_payload' from interface{} to map[string]interface{} to support proper JSON (un)marshalling --- chat.go | 2 +- chat_test.go | 18 +++++++++ metadata.go | 4 +- slackevents/inner_events.go | 73 ++++++++++++++++++++++--------------- 4 files changed, 65 insertions(+), 32 deletions(-) diff --git a/chat.go b/chat.go index 1c498b2af..4448e9f40 100644 --- a/chat.go +++ b/chat.go @@ -669,7 +669,7 @@ func MsgOptionIconEmoji(iconEmoji string) MsgOption { } } -// MsgOptionIconEmoji sets an icon emoji +// MsgOptionMetadata sets message metadata func MsgOptionMetadata(metadata SlackMetadata) MsgOption { return func(config *sendConfig) error { config.metadata = metadata diff --git a/chat_test.go b/chat_test.go index 40cea908b..524439520 100644 --- a/chat_test.go +++ b/chat_test.go @@ -109,6 +109,24 @@ func TestPostMessage(t *testing.T) { "token": []string{"testing-token"}, }, }, + "Metadata": { + endpoint: "/chat.postMessage", + opt: []MsgOption{ + MsgOptionMetadata( + SlackMetadata{ + EventType: "testing-event", + EventPayload: map[string]interface{}{ + "id": 13, + "name": "testing-name", + }, + }), + }, + expected: url.Values{ + "metadata": []string{`{"event_type":"testing-event","event_payload":{"id":13,"name":"testing-name"}}`}, + "channel": []string{"CXXX"}, + "token": []string{"testing-token"}, + }, + }, "Unfurl": { endpoint: "/chat.unfurl", opt: []MsgOption{ diff --git a/metadata.go b/metadata.go index 260471236..a8c065046 100644 --- a/metadata.go +++ b/metadata.go @@ -2,6 +2,6 @@ package slack // SlackMetadata https://api.slack.com/reference/metadata type SlackMetadata struct { - EventType string `json:"event_type"` - EventPayload interface{} `json:"event_payload"` + EventType string `json:"event_type"` + EventPayload map[string]interface{} `json:"event_payload"` } diff --git a/slackevents/inner_events.go b/slackevents/inner_events.go index 02767eb8f..f0118c5a3 100644 --- a/slackevents/inner_events.go +++ b/slackevents/inner_events.go @@ -234,6 +234,12 @@ type MessageEvent struct { Root *MessageEvent `json:"root"` } +type MessageMetadataEvent struct { + // TODO: not sure about the actual fields we get here! + Type string `json:"type"` + EventTimestamp string `json:"event_ts"` +} + // MemberJoinedChannelEvent A member joined a public or private channel type MemberJoinedChannelEvent struct { Type string `json:"type"` @@ -487,6 +493,12 @@ const ( MemberJoinedChannel = EventsAPIType("member_joined_channel") // Member Left Channel MemberLeftChannel = EventsAPIType("member_left_channel") + // Message metadata was deleted + MessageMetadataDeleted = EventsAPIType("message_metadata_deleted") + // Message metadata was posted + MessageMetadataPosted = EventsAPIType("message_metadata_posted") + // Message metadata was updated + MessageMetadataUpdated = EventsAPIType("message_metadata_updated") // PinAdded An item was pinned to a channel PinAdded = EventsAPIType("pin_added") // PinRemoved An item was unpinned from a channel @@ -509,33 +521,36 @@ const ( // implementations. The structs should be instances of the unmarshalling // target for the matching event type. var EventsAPIInnerEventMapping = map[EventsAPIType]interface{}{ - AppMention: AppMentionEvent{}, - AppHomeOpened: AppHomeOpenedEvent{}, - AppUninstalled: AppUninstalledEvent{}, - ChannelCreated: ChannelCreatedEvent{}, - ChannelDeleted: ChannelDeletedEvent{}, - ChannelArchive: ChannelArchiveEvent{}, - ChannelUnarchive: ChannelUnarchiveEvent{}, - ChannelLeft: ChannelLeftEvent{}, - ChannelRename: ChannelRenameEvent{}, - ChannelIDChanged: ChannelIDChangedEvent{}, - GroupDeleted: GroupDeletedEvent{}, - GroupArchive: GroupArchiveEvent{}, - GroupUnarchive: GroupUnarchiveEvent{}, - GroupLeft: GroupLeftEvent{}, - GroupRename: GroupRenameEvent{}, - GridMigrationFinished: GridMigrationFinishedEvent{}, - GridMigrationStarted: GridMigrationStartedEvent{}, - LinkShared: LinkSharedEvent{}, - Message: MessageEvent{}, - MemberJoinedChannel: MemberJoinedChannelEvent{}, - MemberLeftChannel: MemberLeftChannelEvent{}, - PinAdded: PinAddedEvent{}, - PinRemoved: PinRemovedEvent{}, - ReactionAdded: ReactionAddedEvent{}, - ReactionRemoved: ReactionRemovedEvent{}, - TeamJoin: TeamJoinEvent{}, - TokensRevoked: TokensRevokedEvent{}, - EmojiChanged: EmojiChangedEvent{}, - WorkflowStepExecute: WorkflowStepExecuteEvent{}, + AppMention: AppMentionEvent{}, + AppHomeOpened: AppHomeOpenedEvent{}, + AppUninstalled: AppUninstalledEvent{}, + ChannelCreated: ChannelCreatedEvent{}, + ChannelDeleted: ChannelDeletedEvent{}, + ChannelArchive: ChannelArchiveEvent{}, + ChannelUnarchive: ChannelUnarchiveEvent{}, + ChannelLeft: ChannelLeftEvent{}, + ChannelRename: ChannelRenameEvent{}, + ChannelIDChanged: ChannelIDChangedEvent{}, + GroupDeleted: GroupDeletedEvent{}, + GroupArchive: GroupArchiveEvent{}, + GroupUnarchive: GroupUnarchiveEvent{}, + GroupLeft: GroupLeftEvent{}, + GroupRename: GroupRenameEvent{}, + GridMigrationFinished: GridMigrationFinishedEvent{}, + GridMigrationStarted: GridMigrationStartedEvent{}, + LinkShared: LinkSharedEvent{}, + Message: MessageEvent{}, + MessageMetadataDeleted: MessageMetadataEvent{}, + MessageMetadataPosted: MessageMetadataEvent{}, + MessageMetadataUpdated: MessageMetadataEvent{}, + MemberJoinedChannel: MemberJoinedChannelEvent{}, + MemberLeftChannel: MemberLeftChannelEvent{}, + PinAdded: PinAddedEvent{}, + PinRemoved: PinRemovedEvent{}, + ReactionAdded: ReactionAddedEvent{}, + ReactionRemoved: ReactionRemovedEvent{}, + TeamJoin: TeamJoinEvent{}, + TokensRevoked: TokensRevokedEvent{}, + EmojiChanged: EmojiChangedEvent{}, + WorkflowStepExecute: WorkflowStepExecuteEvent{}, } From 33c3a9e70ae26e184c8da94dad0928b107589371 Mon Sep 17 00:00:00 2001 From: h3rby7 Date: Thu, 23 Jun 2022 14:56:18 +0200 Subject: [PATCH 3/4] RM 'metadata' events sections --- slackevents/inner_events.go | 73 +++++++++++++++---------------------- 1 file changed, 29 insertions(+), 44 deletions(-) diff --git a/slackevents/inner_events.go b/slackevents/inner_events.go index f0118c5a3..02767eb8f 100644 --- a/slackevents/inner_events.go +++ b/slackevents/inner_events.go @@ -234,12 +234,6 @@ type MessageEvent struct { Root *MessageEvent `json:"root"` } -type MessageMetadataEvent struct { - // TODO: not sure about the actual fields we get here! - Type string `json:"type"` - EventTimestamp string `json:"event_ts"` -} - // MemberJoinedChannelEvent A member joined a public or private channel type MemberJoinedChannelEvent struct { Type string `json:"type"` @@ -493,12 +487,6 @@ const ( MemberJoinedChannel = EventsAPIType("member_joined_channel") // Member Left Channel MemberLeftChannel = EventsAPIType("member_left_channel") - // Message metadata was deleted - MessageMetadataDeleted = EventsAPIType("message_metadata_deleted") - // Message metadata was posted - MessageMetadataPosted = EventsAPIType("message_metadata_posted") - // Message metadata was updated - MessageMetadataUpdated = EventsAPIType("message_metadata_updated") // PinAdded An item was pinned to a channel PinAdded = EventsAPIType("pin_added") // PinRemoved An item was unpinned from a channel @@ -521,36 +509,33 @@ const ( // implementations. The structs should be instances of the unmarshalling // target for the matching event type. var EventsAPIInnerEventMapping = map[EventsAPIType]interface{}{ - AppMention: AppMentionEvent{}, - AppHomeOpened: AppHomeOpenedEvent{}, - AppUninstalled: AppUninstalledEvent{}, - ChannelCreated: ChannelCreatedEvent{}, - ChannelDeleted: ChannelDeletedEvent{}, - ChannelArchive: ChannelArchiveEvent{}, - ChannelUnarchive: ChannelUnarchiveEvent{}, - ChannelLeft: ChannelLeftEvent{}, - ChannelRename: ChannelRenameEvent{}, - ChannelIDChanged: ChannelIDChangedEvent{}, - GroupDeleted: GroupDeletedEvent{}, - GroupArchive: GroupArchiveEvent{}, - GroupUnarchive: GroupUnarchiveEvent{}, - GroupLeft: GroupLeftEvent{}, - GroupRename: GroupRenameEvent{}, - GridMigrationFinished: GridMigrationFinishedEvent{}, - GridMigrationStarted: GridMigrationStartedEvent{}, - LinkShared: LinkSharedEvent{}, - Message: MessageEvent{}, - MessageMetadataDeleted: MessageMetadataEvent{}, - MessageMetadataPosted: MessageMetadataEvent{}, - MessageMetadataUpdated: MessageMetadataEvent{}, - MemberJoinedChannel: MemberJoinedChannelEvent{}, - MemberLeftChannel: MemberLeftChannelEvent{}, - PinAdded: PinAddedEvent{}, - PinRemoved: PinRemovedEvent{}, - ReactionAdded: ReactionAddedEvent{}, - ReactionRemoved: ReactionRemovedEvent{}, - TeamJoin: TeamJoinEvent{}, - TokensRevoked: TokensRevokedEvent{}, - EmojiChanged: EmojiChangedEvent{}, - WorkflowStepExecute: WorkflowStepExecuteEvent{}, + AppMention: AppMentionEvent{}, + AppHomeOpened: AppHomeOpenedEvent{}, + AppUninstalled: AppUninstalledEvent{}, + ChannelCreated: ChannelCreatedEvent{}, + ChannelDeleted: ChannelDeletedEvent{}, + ChannelArchive: ChannelArchiveEvent{}, + ChannelUnarchive: ChannelUnarchiveEvent{}, + ChannelLeft: ChannelLeftEvent{}, + ChannelRename: ChannelRenameEvent{}, + ChannelIDChanged: ChannelIDChangedEvent{}, + GroupDeleted: GroupDeletedEvent{}, + GroupArchive: GroupArchiveEvent{}, + GroupUnarchive: GroupUnarchiveEvent{}, + GroupLeft: GroupLeftEvent{}, + GroupRename: GroupRenameEvent{}, + GridMigrationFinished: GridMigrationFinishedEvent{}, + GridMigrationStarted: GridMigrationStartedEvent{}, + LinkShared: LinkSharedEvent{}, + Message: MessageEvent{}, + MemberJoinedChannel: MemberJoinedChannelEvent{}, + MemberLeftChannel: MemberLeftChannelEvent{}, + PinAdded: PinAddedEvent{}, + PinRemoved: PinRemovedEvent{}, + ReactionAdded: ReactionAddedEvent{}, + ReactionRemoved: ReactionRemovedEvent{}, + TeamJoin: TeamJoinEvent{}, + TokensRevoked: TokensRevokedEvent{}, + EmojiChanged: EmojiChangedEvent{}, + WorkflowStepExecute: WorkflowStepExecuteEvent{}, } From b31335c7f2c1a28556093363ec72240c365dd48c Mon Sep 17 00:00:00 2001 From: h3rby7 Date: Wed, 29 Jun 2022 14:36:15 +0200 Subject: [PATCH 4/4] add testcase for basic properties only in chat_go.test, add includeAllMetadata flag to conversationHistory --- chat_test.go | 8 ++++++++ conversation.go | 18 ++++++++++++------ messages.go | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/chat_test.go b/chat_test.go index 524439520..7a549fa90 100644 --- a/chat_test.go +++ b/chat_test.go @@ -82,6 +82,14 @@ func TestPostMessage(t *testing.T) { blockStr := `[{"type":"context","block_id":"context","elements":[{"type":"plain_text","text":"hello"}]}]` tests := map[string]messageTest{ + "OnlyBasicProperties": { + endpoint: "/chat.postMessage", + opt: []MsgOption{}, + expected: url.Values{ + "channel": []string{"CXXX"}, + "token": []string{"testing-token"}, + }, + }, "Blocks": { endpoint: "/chat.postMessage", opt: []MsgOption{ diff --git a/conversation.go b/conversation.go index 299362601..e523716cc 100644 --- a/conversation.go +++ b/conversation.go @@ -571,12 +571,13 @@ func (api *Client) JoinConversationContext(ctx context.Context, channelID string } type GetConversationHistoryParameters struct { - ChannelID string - Cursor string - Inclusive bool - Latest string - Limit int - Oldest string + ChannelID string + Cursor string + Inclusive bool + Latest string + Limit int + Oldest string + IncludeAllMetadata bool } type GetConversationHistoryResponse struct { @@ -615,6 +616,11 @@ func (api *Client) GetConversationHistoryContext(ctx context.Context, params *Ge if params.Oldest != "" { values.Add("oldest", params.Oldest) } + if params.IncludeAllMetadata { + values.Add("include_all_metadata", "1") + } else { + values.Add("include_all_metadata", "0") + } response := GetConversationHistoryResponse{} diff --git a/messages.go b/messages.go index 828fa6026..333404563 100644 --- a/messages.go +++ b/messages.go @@ -129,7 +129,7 @@ type Msg struct { ReplaceOriginal bool `json:"replace_original"` DeleteOriginal bool `json:"delete_original"` - // Block type Message + // metadata Metadata SlackMetadata `json:"metadata,omitempty"` // Block type Message