From c76f66fb4690c01a8d6192d11277be06ff94e1b8 Mon Sep 17 00:00:00 2001 From: Rob Holt Date: Sat, 13 Sep 2025 16:45:38 -0400 Subject: [PATCH 1/2] Add conversations.member support --- src/Web/Slack/Conversation.hs | 39 ++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/Web/Slack/Conversation.hs b/src/Web/Slack/Conversation.hs index d9982c1..a9cacf8 100644 --- a/src/Web/Slack/Conversation.hs +++ b/src/Web/Slack/Conversation.hs @@ -44,6 +44,10 @@ module Web.Slack.Conversation ( JoinRsp (..), conversationsJoin, conversationsJoin_, + MembersReq (..), + MembersRsp (..), + conversationsMembers, + conversationsMembers_, ) where import Data.Aeson @@ -475,6 +479,23 @@ data InfoRsp = InfoRsp $(deriveJSON (jsonOpts "infoRsp") ''InfoRsp) +data MembersReq = MembersReq + { membersReqChannel :: ConversationId + } + deriving stock (Eq, Show, Generic) + +$(deriveFromJSON (jsonOpts "membersReq") ''MembersReq) + +instance ToForm MembersReq where + toForm = genericToForm (formOpts "membersReq") + +data MembersRsp = MembersRsp + { membersRspMembers :: [UserId] + } + deriving stock (Eq, Show, Generic) + +$(deriveFromJSON (jsonOpts "membersRsp") ''MembersRsp) + -- | FIXME(jadel): move the rest of the Conversations API into here since the old "shoving all the API in one spot" is soft deprecated. -- @since 2.2.0.0 type Api = @@ -486,6 +507,10 @@ type Api = :> AuthProtect "token" :> ReqBody '[FormUrlEncoded] JoinReq :> Post '[JSON] (ResponseJSON JoinRsp) + :<|> "conversations.members" + :> AuthProtect "token" + :> ReqBody '[FormUrlEncoded] MembersReq + :> Post '[JSON] (ResponseJSON MembersRsp) -- | Joins a conversation. -- @@ -552,12 +577,15 @@ $(deriveFromJSON (jsonOpts "joinRsp") ''JoinRsp) -- | @since 2.2.0.0 conversationsJoin_ :: AuthenticatedRequest (AuthProtect "token") -> JoinReq -> ClientM (ResponseJSON JoinRsp) +-- | @since 2.2.1.0 +conversationsMembers_ :: AuthenticatedRequest (AuthProtect "token") -> MembersReq -> ClientM (ResponseJSON MembersRsp) + -- | @since 2.2.0.0 conversationsInfo_ :: AuthenticatedRequest (AuthProtect "token") -> InfoReq -> ClientM (ResponseJSON InfoRsp) -conversationsInfo_ :<|> conversationsJoin_ = client (Proxy @Api) +conversationsInfo_ :<|> conversationsJoin_ :<|> conversationsMembers_ = client (Proxy @Api) -- | Retrieve a conversation's metadata. -- @@ -584,3 +612,12 @@ conversationsJoin :: conversationsJoin slackConfig req = do let authR = mkSlackAuthenticateReq slackConfig run (conversationsJoin_ authR req) . slackConfigManager $ slackConfig + +-- | @since 2.2.1.0 +conversationsMembers :: + SlackConfig -> + MembersReq -> + IO (Response MembersRsp) +conversationsMembers slackConfig req = do + let authR = mkSlackAuthenticateReq slackConfig + run (conversationsMembers_ authR req) . slackConfigManager $ slackConfig From d5f5ab9bb38426eccc1d8eb72d226ceb2d650f4a Mon Sep 17 00:00:00 2001 From: Rob Holt Date: Sat, 13 Sep 2025 17:03:19 -0400 Subject: [PATCH 2/2] Add tests --- CHANGELOG.md | 4 ++++ slack-web.cabal | 2 +- src/Web/Slack/Conversation.hs | 10 ++++++++++ tests/Web/Slack/ConversationSpec.hs | 1 + tests/golden/MembersRsp/test.golden | 11 +++++++++++ tests/golden/MembersRsp/test.json | 11 +++++++++++ 6 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/golden/MembersRsp/test.golden create mode 100644 tests/golden/MembersRsp/test.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a04cc9..339be5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.2.1.0 (2025-09-15) +* [#151](https://github.com/MercuryTechnologies/slack-web/151) + Implement `conversations.member` API method. + # 2.2.0.0 (2025-03-21) * [#145](https://github.com/MercuryTechnologies/slack-web/pull/145) Implement `conversations.info` API method. diff --git a/slack-web.cabal b/slack-web.cabal index c86bedc..cad602e 100644 --- a/slack-web.cabal +++ b/slack-web.cabal @@ -1,6 +1,6 @@ cabal-version: 3.0 name: slack-web -version: 2.2.0.0 +version: 2.2.1.0 build-type: Simple diff --git a/src/Web/Slack/Conversation.hs b/src/Web/Slack/Conversation.hs index a9cacf8..fd2a6c9 100644 --- a/src/Web/Slack/Conversation.hs +++ b/src/Web/Slack/Conversation.hs @@ -479,6 +479,11 @@ data InfoRsp = InfoRsp $(deriveJSON (jsonOpts "infoRsp") ''InfoRsp) +-- | @conversations.members@ request: retrieve a conversation's members. +-- +-- +-- +-- @since 2.2.1.0 data MembersReq = MembersReq { membersReqChannel :: ConversationId } @@ -489,6 +494,11 @@ $(deriveFromJSON (jsonOpts "membersReq") ''MembersReq) instance ToForm MembersReq where toForm = genericToForm (formOpts "membersReq") +-- | @conversation.members@ response +-- +-- +-- +-- @since 2.2.1.0 data MembersRsp = MembersRsp { membersRspMembers :: [UserId] } diff --git a/tests/Web/Slack/ConversationSpec.hs b/tests/Web/Slack/ConversationSpec.hs index 442c516..6cb4820 100644 --- a/tests/Web/Slack/ConversationSpec.hs +++ b/tests/Web/Slack/ConversationSpec.hs @@ -116,6 +116,7 @@ spec = describe "ToJSON and FromJSON for Conversation" $ do mapM_ (oneGoldenTestDecode @Conversation) ["shared_channel"] mapM_ (oneGoldenTestDecode @InfoRsp) ["general"] mapM_ (oneGoldenTestDecode @JoinRsp) ["test"] + mapM_ (oneGoldenTestDecode @MembersRsp) ["test"] it "errors accurately if no variant matches" $ do let badData = diff --git a/tests/golden/MembersRsp/test.golden b/tests/golden/MembersRsp/test.golden new file mode 100644 index 0000000..c2278b6 --- /dev/null +++ b/tests/golden/MembersRsp/test.golden @@ -0,0 +1,11 @@ +MembersRsp + { membersRspMembers = + [ UserId + { unUserId = "U023BECGF" } + , UserId + { unUserId = "U061F7AUR" } + , UserId + { unUserId = "W012A3CDE" } + ] + } + diff --git a/tests/golden/MembersRsp/test.json b/tests/golden/MembersRsp/test.json new file mode 100644 index 0000000..3707344 --- /dev/null +++ b/tests/golden/MembersRsp/test.json @@ -0,0 +1,11 @@ +{ + "ok": true, + "members": [ + "U023BECGF", + "U061F7AUR", + "W012A3CDE" + ], + "response_metadata": { + "next_cursor": "e3VzZXJfaWQ6IFcxMjM0NTY3fQ==" + } +} \ No newline at end of file