Skip to content
CCPEDIAby Unity Nodes
VideosLesson 2: Writing and Running Daml Triggers

Lesson 2: Writing and Running Daml Triggers

Nothing is loaded from YouTube until you press play, and then without tracking cookies.

About this video

For a better learning experience, sign up and enroll in this free course at: daml.talentlms.com/plus/catalog/courses/154

Transcript

2,536 words

Captions as YouTube publishes them, usually machine-generated, so names such as Daml and Canton can be misheard.

  1. 0:00

    a daml trigger is an optional component of a daml solution that can provide off lger Automation in this lesson we will learn how to implement a daml trigger in a simple chat application then run the trigger and see its effect first let's take a look at the templates we need in our chat application the template named user profile represents a user account in the application users can follow each other any two users who follow each other can exchange messages the user

  2. 0:33

    profile contract has the owner party as the signatory and the list of parties the user follows as observers the owner party is also defined as the contract key the user profile template has two choices one adds a new party to the list of parties the user follows the other allows a sender party to send a message to the user that is create a message contract with the receiver field set to the owner party of this user profile

  3. 1:05

    contract the message template defines the sender and the receiver parties the content field for the text of the message and the received at field to store the time the message contract was created the ensure Clause prevents the creation of a message where sender and receiver are the same party in other words it prevents us from sending a message to ourselves this is a protection against a potential endless loop where a message sent might trigger

  4. 1:35

    the auto reply which in turn would trigger the auto reply again and so on the template includes the delete message Choice which allows the receiver party to Archive the contract the automation that we want to add for this application is to create an automated response to a message sent to a user to demonstrate the use of trigger State let's make a trigger that that responds to every other message more specifically let's create a bot that reacts to a message sent to the user

  5. 2:07

    named Alice and that alternates between two replies the first will be please tell me more when the trigger runs and the second will delete the message sent to Alice when the trigger runs again repeating the cycle for as long as the user Alice receives messages the bot needs an algorithm or rules for what it should and shouldn't do for example we don't want it to respond to messages sent by Alice only to messages received by her since the only source of data for a damel trigger

  6. 2:41

    is The Ledger before implementing the trigger in code we should formalize the rules for our trigger in terms of contracts on The Ledger in the logic of the trigger we're going to use the internal state of the trigger containing a Boolean variable which will be toggled from True to false or from false to True every time the trigger runs let's use the following formalization for the trigger rule when the latest message contract visible to Alice's party has

  7. 3:10

    Alice's party as the value of the receiver field if the bully variable in the internal state of the trigger is true the trigger finds the user profile contract where the owner field value is set to the party from the center field of the message contract and then the trigger exercises the send message choice on this user profile contract and if the Boolean variable in the internal state of the trigger is false the trigger exercises the delete message choice on the message

  8. 3:42

    contract now we're ready to implement the trigger in code for the state of our trigger we only need a single Boolean variable so we could declare the trigger State type as bull but to demonstrate that the trigger State could be a complex data structure supporting much more more sophisticated logic than the one that a single Boolean variable could support let's introduce a daml record to represent the trigger State let's call This Record auto reply State and let's

  9. 4:13

    put the Boolean variable named reply to message that we need for the logic in our trigger inside this daml record we will name our trigger auto reply since the type of the trigger state in the daml record is named auto reply State the type Declaration of the trigger variable is t. trigger with auto reply State the initialized function sets the initial state of the trigger to an instance of auto reply state record with the reply to message field value set to

  10. 4:44

    true the update State function will be set to a Lambda that discards its argument and calls the modify function from the dl. trigger module which allows us to modify the state of the trigger the modify function takes an argument of another function that Maps the state of the trigger before the trigger is run to the state of the trigger after the trigger rule is executed in our trigger the Lambda function toggles the value of the Boolean reply to message field in

  11. 5:15

    the daml record representing the trigger State the effect is that every time the trigger runs the value of the reply to message field in the trigger State changes from True to false or from false to true in the rule function we again use a Lambda the argument of the Lambda is the party running the trigger this is the party whose credentials will be needed to run the trigger and under whose authority the trigger will send commands to The Ledger in our example we

  12. 5:46

    will run the trigger under the authority of Alice's party the first thing we do in the rules function is query The Ledger for message contracts visible to Alice's party the query function from the dam d.t trigger module takes an explicit type application for the template and Returns the list of contracts created from this template that are visible to the party running the trigger for each contract the query function returns a tuple with the contract ID and the contract payload we

  13. 6:18

    bind the result of the query to the variable named message uncore contracts from this list we take the latest message using the maximum on function from d a a. list. tootal module which searches the list of tupes with message contract IDs and payloads and returns an optional with either sum with the tupple containing the highest value of received at field in the message contract payload or none if the list in the message uncore contracts variable is

  14. 6:50

    empty if the value of the last message variable is none we want to do nothing if the value is sum then we want to to check whether the value of the receiver field in the message payload is the same as the party running the trigger using the get function from the dl. trigger module we bind the current value of the trigger state to the variable named s if the value of the reply to message field in the current state of the trigger is true then we want to reply to the

  15. 7:22

    message to do this we query The Ledger for all user profile contracts visible to the party running the trigger where the value of the owner field is the same as the value of the sender field in the message contract the query filter function returns a list we take the head of the list and bind it to the variable named reply 2 which will be of the type optional with a tuple of user profile contract ID and the payload finally if the value of the

  16. 7:53

    reply to variable is sum then we take the contract ID of the user profile contract bind it to the variable named sender profile C ID using pattern matching and then use the DD exercise function from the dl. trigger module to send the exercise command to The Ledger this will exercise the send message choice on the user profile contract that creates a message contract with the party running the trigger as the sender and the content set to the text value

  17. 8:26

    please tell me more and if the value of the reply to message in the trigger status is false then we use the DD exercise function to exercise the delete message choice on the message contract delete message is a consuming Choice which results in the message contract being archived it's also possible to update the state of the trigger in the body of the rules function instead of utilizing the update State function in many cases this may actually be preferable because

  18. 8:59

    this way of updating the trigger State can take into account the state of the active contract set as well as the logic of the trigger implementation in fact in our example it would be better to update the trigger State inside the rules function in our current naive implementation the state of the trigger is toggled every time the trigger is run the running of the trigger may be caused by various events including the creation or archival of any user profile or message contracts

  19. 9:30

    visible to Alice not only by the creation of a new message sent to Alice in other words our naive implementation doesn't actually satisfy the requirement of autor replying to every other message sent to Alice in fact some messages sent to Alice will receive an autor reply and others will get deleted seemingly at random to satisfy the requirement we would indeed need to update the state of the trigger inside the rules function after exercising either the send message

  20. 10:03

    or delete message Choice one last thing to mention about trigger States is that the update State function is run before the rule function so the state of the trigger available inside the rules function is the updated state that is the state that results from executing the update State function given that this is only an example and not a production application we could have used the all and dar value for the registered templates field in the trigger however if we follow best

  21. 10:34

    practices we should set registered templates as the only two templates this trigger requires which would be message and user profile since this trigger doesn't need to run on a schedule the value of the heartbeat field is set to none to test the application we also need a setup script to initialize The Ledger which we're not going to go over in this lesson suffice it to say that the script allocates three test parties Alice Bob and Charlie and creates an off Ledger

  22. 11:07

    user identity corresponding to each of these parties that we can use to login into the application UI similarly we're not going to go over the code for the application frontend as frontend development is out of scope for this training course now let's run the application and see the trigger in action we're going to use a daml project template named GSG triggers which is installed with the daml SDK and contains the templates and the trigger used in this lesson if you're going to check out

  23. 11:41

    this project template on your machine note that the code shown in this lesson is similar but not identical to the code in the gsgt triggers project template first in a new terminal if you're using Linux or Mac OS or in a command prompt if you're using Windows we're going to use the daml new command to create a new daml project in a folder named chat app based on the project template GSG trigger then we CD into the project folder and run the backend using the

  24. 12:14

    daml start command which builds the project by compiling the daml code into a Dar file launches an instance of the daml sandbox as an in-memory Canton Ledger with one participant node and uploads the dark file to the Canton participant node in the daml sandbox the daml start command also launches an instance of the HTTP Json service which is used by the application frontend then in a separate terminal we navigate into the UI folder within our

  25. 12:47

    project folder the front end in the project template we used is a node application to install the required node modules we need to run the npm I command once the required npm packages are installed we can run npm start to launch the web server for the front end this will also open a browser to the login page for the application frontend let's log in as Bob then we will log out and log in again as Alice

  26. 13:19

    and make Alice follow Bob now let's log out as Alice and log in again as Bob we'll make Bob follow Alice in our application Alice must follow Bob and Bob must follow Alice in order for them to be able to exchange messages now let's launch our trigger in a separate terminal window to do this we use the daml trigger command this command takes as a parameter the path to the DAR file that our trigger code was compiled into it also takes the name of

  27. 13:53

    the trigger which consists of the name of the module with the trigger code and the name of the the daml record for the trigger separated by a colon then the daml trigger command takes The Ledger host name or address and the port number to connect to The Ledger finally we pass the name of the user whose credentials we want to use to run the trigger and want to send commands to The Ledger from the trigger to the daml trigger command a trigger can also be run under an on

  28. 14:24

    lger identity a party in which case we would use The Ledger party parameter we can also run the command under an off lger identity of a user mapped to one or more parties with can act as and can read as privileges in which case we would use The Ledger user parameter as in this example once the trigger is running we can come back to the application front end we're logged in as Bob so let's make Bob send a message to Alice as you can see the message automatically received

  29. 14:58

    the response please tell me more this response was generated by our trigger let's send another message this time the message Bob sent doesn't receive a response instead Bob's message disappears it was archived by the trigger let's send another message this one again receives an automatic response generated by the trigger as we intended every first message sent from Bob to Alice receives an automatic response and every second message is deleted to

  30. 15:31

    summarize we've looked at the implementation of a trigger in a chat application a trigger runs under the authority of a party a trigger can utilize an internal state in its Logic the implementation of the trigger in the example application we used in this lesson involves querying the ACs filtering the results of the query checking the internal state of the trigger and sending a command to The Ledger to exercise a choice on a

  31. 16:20

    contract