Skip to content

Commit

Permalink
command building should in itself be an effect
Browse files Browse the repository at this point in the history
  • Loading branch information
barryoneill committed May 26, 2022
1 parent 1e23fcf commit 317844f
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 43 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,12 @@ SlashCommandBotBuilder[IO](secret)
`CommandMapper[F]` is a type alias for:

```scala
SlashCommandPayload => Command[F]
SlashCommandPayload => F[Command[F]]
```

Your implementation of this function defines your business logic. The input is the slash command request from Slack. The output defines how to respond to that request.
Your implementation of this effect defines your business logic. The input is the slash command request from Slack. The output defines how to respond to that request.

Slack4s will only invoke this function if the incoming request's slack signature has been validated against your signing secret.
Slack4s will only evaluate this effect if the incoming request's slack signature has been validated against your signing secret.

### `SlashCommandPayload`

Expand Down
20 changes: 11 additions & 9 deletions src/main/scala/io/laserdisc/slack4s/slashcmd/CommandMapper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ object CommandMapper {
// $COVERAGE-OFF$
def default[F[_]: Sync]: CommandMapper[F] =
(payload: SlashCommandPayload) =>
Command(
handler = getLogger
.warn(
s"Responding with default message; To configure your own processor, see $ProjectRepo"
)
.as(helloFromSlack4s(payload)),
responseType = Immediate,
logId = "GETTING-STARTED"
)
Sync[F].delay {
Command(
handler = getLogger
.warn(
s"Responding with default message; To configure your own processor, see $ProjectRepo"
)
.as(helloFromSlack4s(payload)),
responseType = Immediate,
logId = "GETTING-STARTED"
)
}
// $COVERAGE-ON$

}
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ class CommandRunnerImpl[F[_]: Async](
override def processRequest(ar: AuthedRequest[F, SlackUser]): F[Response[F]] =
ar.req.decode[SlashCommandPayload] { payload =>
for {
_ <- logger.info(s"PARSE-CMD cmdId=${payload.requestId} payload:'$payload'")
cmd = mapper(payload)
_ <- logger.info(s"PARSE-CMD cmdId=${payload.requestId} payload:'$payload'")
cmd <- mapper(payload)
_ <- logger.info(
s"COMMAND-SELECT cmdId:${cmd.logId} reqId=${payload.requestId} user:${payload.getUserName}(${payload.getUserId}) text:'${payload.getText}' responseType:${cmd.responseType}"
)
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/io/laserdisc/slack4s/slashcmd/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ package object slashcmd {
object BindPort extends RefinedTypeOps[BindPort, Int]
object BindAddress extends RefinedTypeOps[BindAddress, String]

type CommandMapper[F[_]] = SlashCommandPayload => Command[F]
type CommandMapper[F[_]] = SlashCommandPayload => F[Command[F]]

}
36 changes: 20 additions & 16 deletions src/test/scala/examples/SpaceNewsExample.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,28 @@ object SpaceNewsExample extends IOApp.Simple {
def mapper: CommandMapper[IO] = { (payload: SlashCommandPayload) =>
payload.getText.trim match {
case "" =>
Command(
handler = IO.pure(slackMessage(headerSection("Please provide a search term!"))),
responseType = Immediate
IO(
Command(
handler = IO.pure(slackMessage(headerSection("Please provide a search term!"))),
responseType = Immediate
)
)
case searchTerm =>
Command(
handler = querySpaceNews(searchTerm).map {
case Seq() =>
slackMessage(
headerSection(s"No results for: $searchTerm")
)
case articles =>
slackMessage(
headerSection(s"Space news results for: $searchTerm")
+: articles.flatMap(formatNewsArticle)
)
},
responseType = Delayed
IO(
Command(
handler = querySpaceNews(searchTerm).map {
case Seq() =>
slackMessage(
headerSection(s"No results for: $searchTerm")
)
case articles =>
slackMessage(
headerSection(s"Space news results for: $searchTerm")
+: articles.flatMap(formatNewsArticle)
)
},
responseType = Delayed
)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ class CommandRunnerTest extends SlashCommandSuite {

val (response, callbacks) = testSlashCmdService(
payload =>
Command(
handler = IO.pure(slackMessage(textSection(s"hello ${payload.getText}"))),
responseType = Immediate
IO(
Command(
handler = IO.pure(slackMessage(textSection(s"hello ${payload.getText}"))),
responseType = Immediate
)
),
signedSlashCmdRequest(text = "lenny"),
waitForCallbacks
Expand All @@ -41,9 +43,11 @@ class CommandRunnerTest extends SlashCommandSuite {

val (response, callbacks) = testSlashCmdService(
payload =>
Command(
handler = IO.pure(slackMessage(headerSection(s"--- ${payload.getText} ---"))),
responseType = Delayed
IO(
Command(
handler = IO.pure(slackMessage(headerSection(s"--- ${payload.getText} ---"))),
responseType = Delayed
)
),
signedSlashCmdRequest(text = "foo bar", responseURL = CallbackURL),
waitForCallbacks
Expand All @@ -68,9 +72,11 @@ class CommandRunnerTest extends SlashCommandSuite {

val (response, callbacks) = testSlashCmdService(
payload =>
Command(
handler = IO.pure(slackMessage(markdownSection(s"you sent: ${payload.getText}"))),
responseType = DelayedWithMsg(DelayMessage)
IO(
Command(
handler = IO.pure(slackMessage(markdownSection(s"you sent: ${payload.getText}"))),
responseType = DelayedWithMsg(DelayMessage)
)
),
signedSlashCmdRequest(text = "woof", responseURL = CallbackURL),
waitForCallbacks
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,10 @@ class SignatureValidatorTest extends SlashCommandSuite {
}

lazy val defaultMapper: CommandMapper[IO] = payload =>
Command(
handler = IO.pure(slackMessage(textSection(s"hello ${payload.getText}"))),
responseType = Immediate
IO(
Command(
handler = IO.pure(slackMessage(textSection(s"hello ${payload.getText}"))),
responseType = Immediate
)
)
}

0 comments on commit 317844f

Please sign in to comment.