What am I doing wrong?
Also, I couldn’t find in the docs what the second argument with [Party]
types is in the testRule
function so I just put in both the allocated parties.
module ChatBot where
import qualified Daml.Trigger as T
import qualified User
import qualified DA.List.Total as List
import DA.Action (when)
import DA.Optional (whenSome)
import Daml.Script
import DA.Map qualified as Maps
import Daml.Trigger.Assert
autoReply : T.Trigger ()
autoReply = T.Trigger
{ initialize = pure ()
, updateState = \_ -> pure ()
, rule = \p -> do
message_contracts <- T.query @User.Message
let messages = map snd message_contracts
debug $ "Messages so far: " <> show (length messages)
let lastMessage = List.maximumOn (.receivedAt) messages
debug $ "Last message: " <> show lastMessage
whenSome lastMessage $ \m ->
when (m.receiver == p) $ do
users <- T.query @User.User
debug $ "users: " <> show users
let isSender = (\user -> user.username == m.sender)
let replyTo = List.head $ filter (\(_, user) -> isSender user) users
whenSome replyTo $ \(sender, _) ->
T.dedupExercise sender (User.SendMessage p "Please, tell me more about that.")
, registeredTemplates = T.AllInDar
, heartbeat = None
}
test : Script ()
test = do
alice <- allocateParty "Alice"
bob <- allocateParty "Bob"
aliceUserCid <- submit alice $ Daml.Script.createCmd User.User with username = alice, following = [bob]
bobUserCid <- submit bob $ Daml.Script.createCmd User.User with username = bob, following = [alice]
bobMsgCid <- submit bob $ Daml.Script.exerciseCmd aliceUserCid User.SendMessage with sender = bob, content = "Hello Alice"
let acsBuilder = toACS aliceUserCid <> toACS bobUserCid <> toACS bobMsgCid
testRule autoReply alice [alice, bob] acsBuilder Maps.empty ()
return ()
The second argument is the parties passed via --ledger-readas
, i.e., parties your trigger can read but not act as.
You’re not doing anything wrong unless you mean the call to your test. testRule
doesn’t modify anything so discarding the result makes it relatively useless, it just gives you back the commands that would be executed.
You can assert on them like this:
((), cmds) <- testRule autoReply alice [alice, bob] acsBuilder Maps.empty ()
assertExerciseCmd (flattenCommands cmds) $ \(cid, choiceArg) -> do
cid === bobUserCid
choiceArg === User.SendMessage with
sender = alice
content = "Please, tell me more about that."
1 Like
For other damlers interested in this topic, this is the trigger and the full test. You can get the original package like this:
daml new --template=gsg-trigger gsg-trigger
module ChatBot where
import qualified Daml.Trigger as T
import qualified User
import qualified DA.List.Total as List
import DA.Action (when)
import DA.Optional (whenSome)
import Daml.Script
import DA.Map qualified as Maps
import Daml.Trigger.Assert
import DA.Assert
autoReply : T.Trigger ()
autoReply = T.Trigger
{ initialize = pure ()
, updateState = \_ -> pure ()
, rule = \p -> do
message_contracts <- T.query @User.Message
let messages = map snd message_contracts
debug $ "Messages so far: " <> show (length messages)
let lastMessage = List.maximumOn (.receivedAt) messages
debug $ "Last message: " <> show lastMessage
whenSome lastMessage $ \m ->
when (m.receiver == p) $ do
users <- T.query @User.User
debug $ "users: " <> show users
let isSender = (\user -> user.username == m.sender)
let replyTo = List.head $ filter (\(_, user) -> isSender user) users
whenSome replyTo $ \(sender, _) ->
T.dedupExercise sender (User.SendMessage p "Please, tell me more about that.")
, registeredTemplates = T.AllInDar
, heartbeat = None
}
test : Script ()
test = do
alice <- allocateParty "Alice"
bob <- allocateParty "Bob"
aliceUserCid <- submit alice $ Daml.Script.createCmd User.User with username = alice, following = [bob]
bobUserCid <- submit bob $ Daml.Script.createCmd User.User with username = bob, following = [alice]
bobMsgCid <- submit bob $ Daml.Script.exerciseCmd aliceUserCid User.SendMessage with sender = bob, content = "Hello Alice"
let acsBuilder = toACS aliceUserCid <> toACS bobUserCid <> toACS bobMsgCid
((), cmds) <- testRule autoReply alice [] acsBuilder Maps.empty ()
assertExerciseCmd (flattenCommands cmds) $ \(cid, choiceArg) -> do
cid === bobUserCid
debug choiceArg
choiceArg === User.SendMessage with
sender = alice
content = "Please, tell me more about that."
2 Likes