Introduction to Directus Flows
Hi, Brian here, from Directus. Welcome back to yet another lesson in our onboarding series. Today we're talking about automation with Directus Flows. Automation is one of my favorite things to talk about, and I think this is one of the coolest features inside Directus. It's like having your own personal Zapier inside your Directus instance.
So, Flows just enables you to create custom event-driven data processing and task automations directly inside your headless CMS, right where you need it most. Who needs 35 systems? You've got Directus. So let's log in and take a look.
So we're inside our Directus sample project and we are going to go to the settings and over here on the left we'll find Flows. So if you've loaded our sample project you should have a couple flows, and we'll take a look at these things. Let's just take a look at Post Approval, for example. This is a good example of a pretty common thing that happens for every developer. We add some feature, we want to send an email notification, and you have to write tons of boilerplate for each different event inside your app. With Flows, you no longer have to do this.
So let's break this down. Each flow consists of a trigger—so what is the action or, you know, what kicks off this particular flow—and then it's made up of one or more operations. And there are many different operations and many different types of triggers. Now, Flows also has flow control in that if any of these operations fail, you can route a flow a different way. In this case, there's a condition setup that's checking for the status of a particular item, and if that condition passes, it is sending an email to a particular person.
Creating Your First Flow & Trigger
So let's break down creating our own simple flow, and then we'll create a more advanced flow using our Run Script operation, which allows you to run arbitrary JavaScript right here. So we'll go in and let's just recreate that flow of something happens, we want to send an email. So we'll go in and give this flow a name. Let's call it New Flow for Onboarding. Perfect. Okay.
So we'll move on to the trigger setup, but like most of Directus, we can add icons and colors to keep things visually organized. Big favorite of mine. We'll go in and choose our different triggers. So we can trigger on events that happen inside Directus, an incoming web request from a different service, we can trigger based on regular intervals and time (a cron trigger), we could trigger based on another flow, or we can trigger a flow manually within certain collections. So for this purpose, let's just choose Event Hook. And I've got two types here. So I can do a blocking, like we're going to filter this particular trigger out, or I could do an action. So this would happen after an action occurs. That way we're not blocking the main thread. So we'll go in and let's trigger on whenever an item is created.
We've got other ones here like if a user logs in or the server starts or the server stops, but in this case I'm going to do items.create. And I can go in and see all the different triggers that are the different collections that we can trigger based on, sorry. So if we go in, let's say if we start a, if a new Directus user is created, we want to send an email to that specific user. So anytime a new user is created. Now let's go in and actually add some operations to this.
Adding an "Send Email" Operation
So we'll go in and take our first node here and create an operation. Just like triggers, you've got many different types of operations where you can add conditions to check and route flows based on different logic. We've got the Run Script where you can run arbitrary JavaScript code. You can create data, delete data, update data. I can send emails and notifications inside the system. I can make web requests to third-party APIs or other URLs, other services that we're using. And you can also trigger other flows. So in this case, we'll just do something simple where we want to send an email.
Now, what data are we going to fill in here? As this flow runs, it builds a data object. So we have the data from the trigger, which we can access using a special key which I'll show you in just a moment. But I'm going to go ahead and give this a name, Send Initial Email, and you can see as I name this Directus will generate a key. So the data that is generated from this operation will be stored inside the flow under this key.
Now in this case if I wanted to populate the user email address dynamically, I'm going to want to grab that from the trigger. But for now, what I'm going to do, I'm going to save this and I'm just going to detach it so that we're not sending an email out. And I'm just going to go in and create a new user so we can check our logs section to see what comes out the other side. So I'll go into our user directory, I'm going to create a new user, and I'm going to just say [email protected] and give them a title, Lead Developer. Alright, so now we've created a new user. Let's hop back into the flows.
Using Trigger Data to Send a Dynamic Email
Where is it? New Flow for Onboarding. We've got our logs. If we open this up, we can see the payload coming from the trigger. And there we go. So we've got our first name, we've got the last name, we've got the email address. So let's work on sending a personalized email to this specific user.
What I'll do, I'll come in and now we can reconnect this just to make sure that once that trigger happens, we're going to perform this operation. And here I'm going to go in and we're going to use the Mustache syntax. I'm going to do $trigger. The trigger is the only key that has the dollar sign in front of it and that's just to avoid namespace collisions. We'll go in and we'll say trigger.payload.email is where we're going to send this, and I'm going to hit Enter so that it saves. So don't forget that part. Anytime you're using this email address field, make sure you press Enter to save it.
And we'll say, "Welcome to Directus." If I could spell. My wife likes to make fun of me for the sausage fingers. So we'll go in and now let's personalize the body a little bit. You could choose between Markdown or a WYSIWYG editor. I'm just going to use Markdown here. And we'll go in and do the same thing. We want the trigger.payload.first_name. So we're just going to use their first name.
"Welcome aboard. Super great to have you as our new," and we can again personalize this a bit using the payload.title. Get my Mustache syntax going. Great. So now that we've got this set up, let's save it. We'll save the actual flow in addition to the operation and let's test this thing out.
Testing the Email Automation Flow
Alright, so we're going to go in and create another new user. Let me call this one Mr. Matt Miner. I'm going to use one of my throwaway test emails and give a title of Director of Demand Gen. Like to pick on Matt sometimes in these videos.
Alright, so we're going to save this and our flow should have run. We could go back into the logs just to check that flow as well. New Flow for Onboarding. We can see there's our payload, and there's the email that was sent. So we'll just hop over to Gmail and boom. There's our email with all of the variables that we had populated. So this is really nice.
Now, let's build something a little more complicated since we've got the email thing out of the way. One of our next videos is going to be on building dashboards. So one of the things that I want to do is let's use the run script operation and just Flows to build some sample data to populate for our dashboards.
Creating a Manually Triggered Flow
So we're going to do a new flow. We'll call it Generate Seed Event Data. Alright, you might choose an icon, fancy stuff, and then we'll manually trigger this flow. And we'll pick the collection that we want to manually trigger from. And there's two locations that you can trigger from. I'm going to select the Events collection. First, I can trigger a flow from an item page or a collection page. So in this case, I'm going to trigger based on the collection page only, and we're going to say the collection page does not require a selection. So we're not going to run on existing items. We are going to run, we're just going to run this flow on the collection itself. Do we want to require confirmation? Yes, we do. And, "Are you sure?" And we'll hit finish setup. So the next thing that we're going to do here...
Using the "Run Script" Operation
we will create a new operation, and I'm just going to call this Create Events, very simple. We'll go in and click the Run Script operation. So again, this just allows you to write arbitrary JavaScript here and run that code wherever. So I've got a little bit of code that I wrote for this, just a quick little script that will generate some random events and some random numbers and return a list of items to save inside Directus. So I'm just going to paste that in here. We can take a look at what it's doing. We've got some events, we've got a random number generator, we've got a random date generator, we've got a random UUID generator, and we're putting all that together into a function that just loops and creates 10 items. So we'll go ahead and save this.
And the next step in this process is going to be actually creating those events. So we're going to say, Save Events. And we'll go into the Create Data operation. We're going to choose the Events collection and here for the payload, what we're going to input is create_events. So let's see where that gets us. We're going to save and we'll go to our Events collection. Where are you, Events?
We've got no events. We're going to open our flow and we see we've got one that says Generate Seed Event Data. I'm going to click on this. We're going to run the flow. And uh oh, something has happened. It is not actually generating the data that we want. That's not good. This is a blank event. How do we fix this?
Troubleshooting and Fixing the Flow
So we're going to go back into our flow, we're going to do some troubleshooting and take a look at what happened. Not the new flow for onboarding, we got the seed event data. So here we go. We see our payload there. We've got our options. Looks like we're generating the events just fine. But what's Happening Here? It looks like the payload is incorrect. So we'll go in and adjust this. And wait a minute, that does not look quite right. Let's edit this raw value and see what we're doing wrong.
So are you able to spot where we've gone wrong here? We forgot to include our double mustache brackets to populate the data. So don't forget those mustaches, those curlies. And now we'll save this and let's try again. So we'll go back, we'll run our flow, we'll hit Generate Seed Data, and hey, that's nice. Now we've got some seed data to work with for our dashboards video. But let's take this one step further and make this even more nice, nicer, whatever that word is.
So we'll go in, we'll go back to this, and now let's change this so that we have some input from our user. So we'll go here and down at the bottom we've got our confirmation input fields. Maybe we want to let the user pick the service. So we'll say Service as the key, Services the field name in capitals, and "What service did this event happen in?" Okay. Instead of just app, maybe we want to let them populate something else. So we'll say required. And then maybe we even want to choose the number of items. So we'll say the number of items that we want to generate. Number of items to generate. Very nice. We're going to choose the integer type. We'll do like a half width and this requires a value. Great. Forgot to pick an interface, don't forget to do that. Great.
So now we'll save. We'll save again. And let's just change our script a little bit to pull in those values. So we're going to go back and here we go. So I've got a piece of the script where it says number of items here. You can see that the data for the flow is being passed to this run script so we're going to do data.$trigger.body_or_what's_it_going_to_be... Actually, let's try body and then number_of_items. And then where we have service... let's say the service oh there it is... const service = data.trigger.body.service. Let's see how that works for us.
Final Test and Conclusion
So we'll go back, we'll go back to our Events collection and now when we hit Flows, we can see we've got a service. So this is our test service. We're going to generate five items. Let's see. Alright, can we count them? One, two, three, four, five. Perfect.
So that is a great example of how you can manually trigger flows with input data. This is a super handy feature. Lots of users requested this and man, I'm glad our engineering team came through on this. So that is all I've got for you on flows. Stay tuned for the next lesson. You're going to enjoy it. I'll see you.