Right. So one thing I was reading through team's feedback, you know, the last session, sorry, I had a conflict could not join last time. It sounds like you guys discussed, you know, some of the things, you know, around intent design. So that more of the kind of NLP, like free text enabled stuff. Just to be clear, is this is not how we are using the platform because we're working in the regulated environment. So we're not doing a lot of open ended. So just, you know, something, you know, even though it's like interesting for the team, it's not like what we have been doing or have like immediate plans on using. We're doing, you know, more kind of like a scripted logic and multiple choice. So maybe a lot focusing less on that. Guys, you know, team, I'm not seeing anything in the chat, like are you putting your stuff in. Are you having any problem doing that? If you're saying something, we cannot hear your all on mute. Actually, are you able to hear us? I see that you're connected now. Yes, yes. Okay, so I know you connected just a couple of minutes late. One thing I asked people to do. So the survey internal survey about, you know, what you learned, what you'd like to learn more, you know, about. Can you can everyone take the your response to the last question of what topics you want, you know, to learn more about and post your response in the chat to this meeting into the meeting chat. Yes, you're motion. Okay. So it will help Mark and Andrew to make sure that, you know, topics you're interested in are covered. Well, well, people are doing that. Mark and Andrew, it seems like definitely like the modular in a nature of thing that was something that people wanted to understand the more things about. Like working with hooks. Let's see. Okay, so Andrew, do you want to go through hooks and talk about setting up a hook in a flow and how the, and how they would build a custom hook that would then save data to something or would do something. Sure. Yeah, just give me a moment to get something set up here. And guys, you can literally just like copy paste, you know, from your email that you send, you know, in response to Monica's questionnaire. Just copy paste your response to the last question into the chat. Well, this is happening and Andrew is getting set up. Mark, depending on how it goes, you know, we may want to have, you know, maybe one more session. Yeah, that's fine. Okay. Thank you. So look, you know, there is no pressure, no look crushing everything. Okay, I'm just giving another moment here. I was trying to use the idea of, um, shade, new project as my example, but it looks like some changes. Have been made in there, so I'm just trying to get, um, get a simple flow up and running care. Okay. Well, while you're setting that up, Mark, another thing we would like to do for the new project that we're starting to develop project, Wally. We would like to have a walk through that, you know, requirements that design of that and have your teams input and guidance on, like, basically doing it properly, yeah, like proper architecture. Daniel is the product manager, so he's been working on, you know, putting the requirements together, trying to keep things as modular as possible, but, you know, any input. Like, if there is anything can be improved even in, like, how things are defined, but definitely how to then carry that kind of like modular approach to the way things are architected in the solution itself and implemented. Yeah, if, uh, Daniel wants to, um, Daniel, if you, I don't want to talk about you in a third person sensor here, um, if you want to go ahead and just, um, suggest some times we can get together and, um, get Andrew on the call and we can go through your, but you guys are trying to accomplish and talk about best, the best way to achieve that. Sure. Yeah, I currently have a main tree and a few subtrees drafted. Um, I mean, the main tree should show the major. Sort of the logic, right, and the flows. So I don't know if that's enough to look at, or if there should be more content to review first. Well, we can start with that and then go from there. And if we want, we can just get a standing meeting like every Tuesday at this time and then these for the next four weeks or so, we can just do that and then use it for review or answering questions or whatever and then, um, then evaluate at the end of the four weeks, if we still need another series of meetings. Okay, that makes sense. I will, I'll reach out to Andrew to set the time for that. That sounds good. Looking through the questions to see if I can. Andrew, how are we doing getting close? Um, I'm going to switch over to another environment. I'm not sure what's happening. I'm the dear, Devon, but I can't, I can't deploy the dear Jade project. It's giving you not everything that I've never seen before. So I'm just going to pivot here. You is something wrong with our environment. Andrew. Something's wrong with the idea of Jade, the idea of a new example project. For some reason, it just doesn't want to deploy at the moment. So I'm just getting something quickly set up here and in internal environment of ours. Okay, so that's what you guys used for either example last time. Yes, yeah. You Okay. I think this will work. Sure. Okay, can everyone see it? Yep. Okay, so I think the first thing we wanted to cover was sort of a more detailed walkthrough of implementing custom hooks and flow of studios that right? Yes. American, you said to record data. Well, I think that's one example that I think was mentioned last week, but just, you know, how you would create the. So you would look in the custom hooks and how you would set what you would set in the flow and then how the custom hook and then. You pass on to the function to do something. Okay, so we're over here in whatever internal sandboxes and set up a quick example flow for us to use for the purposes of this demo. I'm also going to add a new custom folks tab. So we're over here. So within the module system, there's this sort of one bit of boilerplate that you're always going to be using when trying to sort of tap into the project context in the modules. So we're going to set it right here is just sort of waiting for all of the project module code to be initialized. And then there's usually a dependencies. No, like this where you're just telling, you know, you want to wait until all the particular dependencies of this code in this tab needs. In this case, we're just looking for flow manager module to be ready. And so this you will see this repeated. And unfortunately, there isn't a great way to avoid having to copy and paste that boy or play between tabs, but you'll see that's not pretty much any tabs either for the modules and the self. So are any code utilizing the modules. So let's go ahead. Let's just go with this test for now. Change the name to just say here at Pestible example. Let's go at it. We will just log in message. So then we know that it has launched. So in here. Part of what the project context code here did was established. So it's actually deployed first. So what is this code is executed is going to establish a reference to all the project module code in the in the local context for the flow. So that's why you're seeing this light here project equals flow to get project is getting this entire object here from the flow flow manager. We're just picking out that one particular module that we're interested in. And then we are calling the register hook method on it. And you'll see you can explore the flow context a little bit over in this panel. And you'll see what's available within a particular module what methods it's exposed. But so here we're going to register our custom hook. The first property in this case is the name for the custom hook. This is very important because this is the name you're going to use to invoke that hook. And then the flow studio flow. And then the second parameter is just the handler. And every every handler for a hook is going to take in the message object first. It can take in other additional properties. I'll give you an example of that. And taking that message object and it's going to need to do something with that message object and pass it along. And so here in our case, we are just going to take that message will pass it along. And then we'll pass it along to this next node. And then we're going to have a flow manager module. And we are going to call the handle method. And pretty much without exception, every hook that you are going to create will want to do this. I can't think of the top of my head of sort of a use case where you would want the execution to end within a hook. So this method here is what passes execution back to the back to the flow manager module to sort of continue onward. And then we're going to run to the next step. And this doesn't necessarily need to be in the next tab. If you want to do streamline this, you could call flow manager dot handle. Right within this, this is just sort of an example of, you know, often your your logic gets, you know, sort of more complex for some of these hooks. But you know, you can continue on to sort of a series of node where you are, even where you're defining your health as long as at the end of whatever your logic is. You end up calling flow manager dot handle message. So let's go ahead and save that. Just. Reading that's clear. I'm going to grab our hook name here. And we'll go back into this example flow that I've created. So after our initial say node, I'm going to bring over a custom node. And I'm going to change the name of it to a dear custom example, which is the exact thing that we registered that hook with. Go ahead and save it. And we'll relaunch the chat by here. And I've set the glad to dear example flow to be the launch flow for this experience. And I did that by editing our settings content. Over here. And setting that launch ID, setting that flow ID here to flow dot watch dot ID. That's sort of a standard convention in the base modules to smooth over, you know, you know, you're not up and to write any code around that. Quick way to have your experience pipe directly into some particular flow to start. Okay. So now I've relished the chatbot page. I'm going to launch again. We'll see we're still in our idea of example flow. We will see a few extra log entries here. We'll see that the end year. Love this debug entry that the idea of custom example hook has been called. That was our logging statement from here. So we can see that it has executed successfully. So I guess next step. Go back in here. There's another convention with these hook names. And there you can then after the hook name at a colon. And specify some parameter values. And these are going to be pipe delimited. So actually let's just go with. Actually, let's do something like true. One. Some strength. So I've just specified some random parameter values. True one, some string. Pipe delimited. So I'm going to save that. I'm going to come over here. So in our handler for this hook, I'm then going to say, 1, 2, 3. We will spit those out as well. In our long just to see what's coming through. We'll do a little chatbot again. So now we can see here we're back in our flow. Our custom hook is still executing. And here are those parameters that we spat out that came from that convention there. One thing worth noting here is that they are always going to come through initially as strings. So if you are interpreting one that you know is going to be a Boolean value like param two, you know, you would do something like whether or not param two is strictly equal to the string true. For things you know are going to be numbers, you would probably want an extra piece of code here to parse the integer out from it. So that is one. An important limitation here with this system. But it is a vast improvement over what you might be familiar with. Sort of earlier suggestions that we would have given where you just have a switch statement that is, you know, essentially copy and paste the control ID over here. And then he's just get very ugly very quickly. So yeah. That is yeah, that's essentially all the basics of invoking one of these custom registered hooks from low studio. If you did want to create a record as a result of it, it there's really nothing that changes in terms of the hook invocation. You would just go on to then use a dynamic native data node. This is your standard node for writing records. So in here, you know, you could establish a message to fill in that data. And this would be whatever data you want to record for that record. You choose the model that you are creating a record for. Let's say an appointment for this sake of this example. You would choose your action. Let's say. Let's say an absurd. So you can do create you can also do an absurd. The absurd obviously going to specify a query for the existing record. And so this is pretty useful if you know, you know, want to either create a record or update it if it already exists based on say a query for some ID that you might have or some user token. But yeah, that's there's really no limit to what you can do logic wise in experience designer for a particular hook. It's just sort of you just want it wrapped up in this convention of you register the hook. You take care of all your logic either directly within the handler function or through a series of nodes. And then at the end, you just need to make sure to invoke flow manager not handle to get the execution back back on track into the flow manager node and onto the next step. I think that probably about covers it unless there's anything else you could think of work. Can you just show what would happen if you had two or three hooks and how you sort of have to daisy chain those together. Oh, sure. Yeah, I mean, there are a few options for doing that, but the typical convention would be. Actually, I already have one set up out here. No, these are all distinct. So the typical convention would be and the other can be the confusing to wrap your head around. At first, but I'm going to increase this to two outputs. So now you can see there are two nodes coming out of here. And so what I'm going to do is I'm going to change. And so by changing this from just passing along the message object to passing on in a light in array, I'm telling this that OK, there are two outputs here. This message object goes out of the first output and then nothing fires on the second output of this case. So that no dot send updated to be like this is still saying, hey, send that message out of this first pin here. That's where my hook logic is going to happen. And then here outside and after the hook registration, I'm just going to do. Return. No, come message. I'm saying that this is going out the second pin. Keep in mind that sort of this is in the context of our initialization code executing. So this is saying, hey, after you've gone and registered this hook, let's move on to the next node. And let's just say this is a dear customers ample have to chain those together. So you essentially have to sort of passive execution here at the outset when the project is initialized, you know, your registration code is going to go register this hook move on to the next hook registration through pin two. If this is the same thing, you would chain on to hook three and so on. Meanwhile, pin one is reserved for the actual execution of that hook and is being triggered, you know, when that hook actually fires through this node dot send. Worth pointing out that. So at the base at sort of the root level of a function node. You know, the return statement is what's going to invoke the next hook or the next next pin for whatever function node you're dealing with. But within a function within a function node, you're going to need to use this node dot send method to get it to fire that next pen. This return message really only works at the at the root level of execution of a function node. And no dot send is valid here as well. You could easily just do. Use it in both cases to avoid any potential confusion if that convention makes more sense to you. If. Anything else, I'm or any questions around hooks. Are there any questions. Or look, is is everything clear? Is everything you. Okay. We have a next question move on to. So real quick before we move on, I want to. How to debug and I think Andrew showed you in the function node one way to do it is with no dot warn. So you have this debug console on the right hand side. That will show a debug messages and errors as they happen on the right hand side. And so you can put no dot warn messages in your function nodes to kind of see where logic is firing when you're trying to find something. And so this can be useful. If you want to see the variable names of something like you don't know what's going on and you want to see a variable or you're just putting something so you can see where your logic is going within a function node. So that's one option. The second option is a debug node, which is. It's a little green node. And you can show that. That you can link together and that will also show up in the debug console on that fires. The one thing to remember is. Like any debug it's great in development and you can use as many as you want normally because the traffic is pretty low. But we want to make sure they're all turned off before it goes to production because they do use memory and there are a couple options in a debug node that can use a lot of memory and can. Can crash the system if you have a lot of traffic. So like I said, it's great use them as many and I do a lot when I'm trying to debug stuff. I use them a lot in the dev environment, which is you make sure we turn them off before we migrate stuff up to production because they definitely don't want to turn down and production. Actually, I may, you know, anyone else on the team, do you have any questions about using folks debug. Actually, it's so. This debugging to be actually very good. One more question. Without removing it, we can we directly turn off the identity. If I don't want to remove the debugging node, which I've added. I need to just disconnect it. You can turn it. You can turn it off Andrew. There's of that green button at the end will turn it off. Yep, so this is active. This is an active. Okay. As far as the warn that the node dot warn you can put logic in there to have like a master, you know, debug flag. And that may be turned on in your settings that you want to check. Otherwise, you want to comment those out. Again, we just don't want to have a lot of again, if there's a lot of traffic and a web in the bot. All of that adds up in the memory, all those all those warning messages and things like that. So we just want to try to limit that as best we can. Yeah, so like Mark said, we'll often have a debug flag in our settings and, you know, wrap some node dot warns and whether or not that is set to true. And yeah, it's very important to have especially if you are in generally should try to avoid. Outputing the complete message object as that could be rather large. But if you are, you certainly need to make sure that those are disabled for going to production because the. Longing the complete message object or any other. Large piece of data has a significant performance cost. Okay. So, I think that's a good question. Any more. I want to make sure that you guys are good with hooks because that's probably where a lot of your logic is going to be. So is there any other. Concepts or examples you want from a for hooks. Yeah, maybe I have something but can we write like this hooks independently. Like different on different lines like they should have like one who is not like. Can we can it be connected with each other without connecting each other can we write independently through. Sorry, I'm going to try fully understood the question. So I'm saying can we like the hooks independently like rather connecting with each other like first hook like customer time talking about customer. I'm saying it with the first two and next one and like to third one like to each other. So can we write independent with the suits. Yeah, I mean you could certainly you know say on one tab you have the set of code you could. Or you can say something like this. We're like this is a two rather than changing them together or. Or you asking about something. Yeah, so I mean this is yeah, this is valid. It's just you know you're sort of duplicating these nodes. So yeah, doing the training method just kind of saves you from having to copy that boilerplate over and over again. Yeah, one of the things that we're trying to do is is simplified maintenance the best we can. So let's say for example, we find out that we need to update something in dependencies that we've got a fix or a change or enhancement. We don't want to run around and have to find all the places where that's being used. So we just try to keep it simple. The other thing is inject nodes and Andrew can talk a lot more about this. Don't always fire the way you think they're going to fire they they sometimes fire they fire. I think the order in which they were created on the in the project. And so when you think a variable may exist because you have them laid out sequentially on your page. So we don't and so we have seen historically we what we've tried to do is streamline the use of inject notes so that if we're using an inject note to. It's to set up all of these hooks that it all happens at once when we start using lots of inject notes things don't always fire when you think they're going to fire. Yeah, yeah, so early on we used to have a much higher reliance on say using inject notes where. Okay, we would have this one inject once after you know point one seconds and then let's say this one injects once after you know point five seconds or however long we thought that the code associated with this inject node would take to run and try to sequence things that way. But obviously you know then if the execution takes longer that sort of falls apart and also if I then have another node over a different tab that's set to the exact same timing. It is going to be you won't really have a sense as to which one is actually going to fire first. It's not even actually like what order they were added in and gets down to ultimately behind the scenes this node red code. We'll get boiled down to essentially just an array of node information behind the scenes and it would come down to like which order in the array each inject note is so that's a huge part of why we came up with the system where you know you'll see these inject nodes you'll see them in each module tab. So you'll see two point one seconds but this project context and the waiting dependencies means that it does not matter what order they fire in anything that is dependent on something else will await that dependency successfully regardless of the order of the inject nodes so yeah they are useful for some things but. If you're using them for some sort of project initialization code you should stop and ask whether or not it should just have to be done through the module system instead. So just sometimes with the dependencies if you have to add additional dependencies just have to do it in one place is easier again it's just about trying to keep streamline code and not have the same code repeated over and over and over if we don't need it so our recommendation would be the daisy chain the hooks together. That's our best practice obviously you can do what you need to do and what you want to do but that's just what our recommendations. Okay. Sorry so is there another particular question next to cover or. And we talked about debug was there any questions on the debug stuff. Okay and then any other questions on hooks. Sorry one other quick thing point head on debugging just because it's not necessarily obvious if you are looking at debug messages let's take this one for example if you click so most of them should give you an indication of what noted originated from if you click on it it will take you to that node which can be very helpful when trying to track things down. Okay Andrew would you also just quickly talk about the air trapping error catch stuff because I think that's important that's something that we've added into our framework as well in in the past when there's any kind of errors let's say a variables not defined or not initialize whatever it would show up in the debug console but it wouldn't show up anywhere else. And so unless you are watching real time as things happened you would know there was a problem and so what we want to do is have a centralized place to have errors logged so that we could go back and review it and say oh wait there's something we're seeing the same problem over and over and over there must be some sort of initialization error going on. And so Andrew came up with this process this sort of generic catch all error trapping process that we incorporated and applied to all of the function tabs so I just want to make sure I know we didn't I didn't see it on some of the examples and I just want to make sure we talk about that this is important to us as the as the hook process. Yeah, so. I like to say that's one of sort of our core modules it establishes these two schemas for error types and actual error instances by default when the module is added you won't see any of those schemas what happens is. So when an error happens that is handled and that error handling happens through all these modules you'll see a catch all at the top that will then go and finally error into our error handling module. When an error is created it'll see whether or not there's already a sort of error configuration for that type of error if not it'll go ahead create it so you'll start seeing entries like this for error type. And there are a few settings in here around you know by default there's a. In the setting to specify who the default emails are the notification should go out to there are thresholds that should when indicate that an email should go out of more than X number. These errors occur in a day the default is zero with the thinking being that you would want emails to go out whatever sort of a new error is encountered so someone can go and review that. And then the actual error instances look something like this telling you session ID if it's known the timestamp when it happened what type what the message was and what noted originated from. So like Mark said you know you will you know get errors logged in the console here but by default there isn't going to be any persistence of those so we definitely had a need to get a better handle on when errors were happening when you know no one happened to be watching. And so yeah the code in the original module it handles that sort of automatic creation of types sending out notifications when appropriate trying to sort of gracefully handle the error by just giving you know the user depending on each channel a message as you know that something has gone wrong and there's just another little routine in here to reset our accounts every day. And you can utilize this on code outside of the modules let's say in custom hooks you know an error I can just copy this over here and this is again sort of similar boilerplate code that can just be copied and pasted to any tab where the project context has been pulled and it will just take the error it'll assume that the by default it's going to use the tap name is the sort of error type. Name and so through this mechanism here whenever any on handled error happens in any code on this tab it'll find a link to here and then into the air handling module. Any questions about that team. So I would like to just circle back quickly to custom handlers because I think it's again this is another important concept. But way that Andrew designed this framework and I know he mentioned it last week but I just want to kind of repeat this the core modules were designed so that we don't have to update those and that gives us the ability down the road to roll out updates so if there's a new feature or fix to a core module and we can roll that out to everybody without a lot of work. From an implementation standpoint and so the custom hooks is one piece of that where you can create this the custom code and sort of isolated from the standard code so that you can do. Custom process is custom logging reporting all that kind of stuff the handlers are another custom handlers are important piece because then it allows you to. Override the base functionality for again for something something custom without actually updating the core modules so Andrew if you can just talk about how you would set up a custom handler and how that works real quick I just think it's an important concept. Yeah so. Find a good example here. Yeah let's just go with like the custom after launch handler. So yeah similar to hooks and like Mike was saying we've sort of tapped created a bunch of potential handlers within the modules for you to tap into to be able to customize. Aspects functionality without having to edit the module itself so you won't break sort of your upgrade path. So in this example here. We are establishing a custom after launch handler so that handler is offered up by the base intense module here. And it fires after the after the launch node is triggered so you know if you want to say record maybe a piece of like you know data about the fact that. The experience has started for a user or anything else really established or clear some flags in session whatever you need when the application first. So if you are a separate or rather I guess the experience first or separate user. You can register a handler that will then be invoked here in the base intense module so it will check if any after launch handler is registered it all let it do its thing. Before moving on. So here you know similar to with flow manager we're grabbing our project context in this case the dependency we want is base intense since that's a module or looking to register a handler with. And very slow motorhugs you know I'm going to the base intense start register handler method I'm telling you what event I want to handle this case after launch this needs to meet exact match or else you'll get there about it being unknown sort of handler. And then you have your actual handler function. Which again would take in for most of these you're only going to be taking in the message object as a parameter and then doing whatever you would you know do similar to hooks you can easily sort of chain your logic here through a few series of nodes. In this case the one difference would be so in the hooks you're ultimately going to handle flowman call flow manager dot handle. With a handler and it might vary from handler to handler so you would want to be clear it should be clear clearly defined in the documentation for that module. So in base intense for example we're expecting the after launch handler to be to be potentially asynchronous we're waiting it here. So in my example here you know if it wasn't asynchronous it would just return that would execute fine but. We want to have code stretched out over a few nodes or a potentially asynchronous handler. Then you get into you would want to return let me see if I can find an example here to show you as I walk through it. So essentially what you're going to want to do so this is yeah this is a basic example for a simple simple after launch handler that is just you know going and say blocking a message indicating or adding a new property of the message something like that let's say I wanted to like record a piece of data. So. So. And this is getting into sort of if you're not familiar now within JavaScript obviously we knew pretty much you've actually use a sync away but you know there is the sort of lower level promise declaration that is very helpful in situations like this. So you would essentially be establishing establishing a promise here within the promise. You would. And actually these declarations not necessary you're going to come in within your promise you're then going to say you know just attach a reference to the resolve and reject functions from the promise. So we'll say message that was off equals resolve message reject equals reject I will pass along that message to the next node. And then I'm going to from this handler return the promise. And then let's just say I have additional. Additional function node let's say I'm creating a record or something. And then at the end here I want to make sure that I resolve this so be attached the resolve handler for the promise to the message object. So at this point I would you know call that to resolve the promise. So through that sort of chain what's happening is the handler fires here it's returning. It is returning a promise. So in this case we're going we've invoked it we're waiting that promise. And then you know once everything in here is executed the record has been created. We will then come message to resolve to invoke that it's not necessarily a pattern that you'll find you commonly will have to utilize. But it's worth being aware of this is this can be a very helpful pattern for. And then you can do a lot of things that you can do longer running either. You know hooker handler executions. You can do a lot of. Yeah you can do a lot by utilizing. Basin minus programming with an experience designer. Just need to be a little bit careful about the execution of it to make sure that everything is being piped correctly. So this is on that on that note it's worth noting that. The the editor in here is a bit outdated with regards to its validation. So you will see warnings come up if you use things like async and a weight. If they're perfectly fine it will execute fine. It just is giving unfortunate warnings because like I said the job is script validation in here is. Unfortunately updated. But it's all it's all valid the underlying underlying node instance that is executing everything is much more up to date than the validator here. So kind of there's like all the different modules have different handlers and those are in the documentation that I shared with you. And so just gives you a different you know sometimes just doing stuff through hooks isn't where you want to do stuff and you can't maybe get to something that you need to or when you want to do something. So the handler should just important to be aware of you may not use them, but be aware of them as another mechanism for. So you can just do a custom code and being able to do things after like after the launch happens that you want to do something custom without having to modify the. The modules to make sense. To give just a quick rundown and sort of the basic modules here so base intense. So you're going to see handlers for after launch and fall back that would fall back would be when no known intent fires so what you want to do in that case with a default here of saying you know sorry I didn't understand. And then the other big point that you would probably want to integrate with commonly would be within. Sorry, I mean the flu monitor to have here. And then there's a picture there are handlers for you tie in here after the flow manager output for pin one which is sort of when you're still in the middle of the flow or pin two when you have ended up low. Those would be the most commonly tied into and registered handlers. Those are going to be the big ones. So to kind of go back to Daniel you had a question about when to know when people dropping out of flows right so that's a potential where you could log you know a custom handler to log where people are inflows into a custom schema. And then you would want to do that with a hook because you'd have to have a thousand hooks to do that whereas you could do it with a handler. And then have something that then just writes a record for with the session and then you have that schema that you can then use to create reports from. Okay, that's very helpful. Thanks. Actually, I see there was a question from you about me and being able to have input with submit or skip buttons, you know, whether it's possible. Yeah, actually, actually, you have told us that the zip code we have to take her in input form, but also allow user to skip that part. There is no option to keep two buttons in single input like if you are taking the input, then we can submit only we cannot skip that input. So there is any way, one other way by which we can do that that I want to know. Let's see what would the best approach for that pay so. Really, you would need to get into sort of a custom input at that point. The most straightforward approach for that is using what we call adaptive cards. So you have the adaptive card editor. Customs of code input. So here this editor allows you to. Create a custom, you know, custom little input form. So you would use this to create a simple little form that essentially has your zip code input and has two buttons, you know, you would tie. And then you would have to get into using custom events, most likely. And so you would have your one button that's going to submit that. And then your other button that is going to. Well. I apologize, I know we're at time and unfortunately I have to hop off. But one thing, you know, maybe you guys can talk about maybe some practice assignments that you, you know, you can recommend for the team so they can practice, you know, what they learned. Today, and what we will do. Andrew and Mark is before the next session will, will submit to you a list of questions and topics. You know, from the team so we can kind of plan and think through. It gives you an opportunity to think through like how you want to run the meeting. That sounds good. Yeah, we're at time. I think I think we have a good discussion on hooks today. Like said, that's foundational. Want to make sure that that was understood because that's a bulk of what you'll be using as well as a Lisa introduction to handlers. And then on the next session, we can then look at some more advanced topics. As far as next steps. Let me, there's a sample project in there. Let me. Let's look to figure out why it's not working at sample Jade project and get that fixed and then we'll send a note at everybody. And then I would just go in there and maybe build a couple of hooks and practice doing some hooks and seeing if you have any questions with those hooks building custom hooks and. I'm working with using those with flows and then see what other questions you may have based on what you've done on your older projects. So there's some stuff that you'd like to compare like in our old project we did this. How would we do that in our new project. Then let's take a note of those and we can kind of look at those in the next session. Does that work for us? Okay. Hopefully those teams speak up if you feel otherwise, but that to me sounds like a good plan. Excellent. So I will send out the link to this recording once it becomes available to everybody and then we'll go ahead and get the standing meeting going for every Tuesday at this time. Obviously, if you have questions before that you can send them to me and we can try to get them answered before the next session. Otherwise we'll talk to you next Tuesday. Is that work for everybody? Yeah, sure. Thank you. Thank you, everyone. Appreciate you. And Andrew. Thank you. Depending on your time zone, have a great day or have a great evening. We'll talk to you later. Bye.