Building a PostHog node for n8n 📈
1:52:22

Building a PostHog node for n8n 📈

n8n 13.02.2021 862 просмотров 13 лайков

Machine-readable: Markdown · JSON API · Site index

Поделиться Telegram VK Бот
Транскрипт Скачать .md
Анализ с AI
Описание видео
In this live stream, we built a PostHog node for n8n with Ricardo Espinoza and Tanay Pant. Note: The initial difficulty with Lerna was because an old version of Node.js was being used. It was resolved after the live stream by updating the Node.js version Resources: GitHub repository: https://github.com/n8n-io/n8n Contribution guide: https://github.com/n8n-io/n8n/blob/master/CONTRIBUTING.md

Оглавление (8 сегментов)

<Untitled Chapter 1>

hello hey everyone welcome to our first live stream and would love to say hi in the chat and i'd also love to hear where you're joining from so today i have with me a very special guest ricardo espinoza hey ricardo hello yo so ricardo has been one of the most active contributors to n10 and has created more than a hundred nodes and he now works at na10 as an integrations engineer so ricardo how did you discover naden uh that's a good story uh i used to check uh well i still check protocol every day first thing in the morning and i remember yeah watching the project getting really excited about it uh immediately download the project run it locally started using it and yeah it was love at first sight yeah and since the project was built on no yes and i had some experience on it yeah i remember creating my first note and after that yeah i just couldn't stop cool that's awesome and what was the first note that you created it was mandrill it's called which is a melting company for sending transactional emails yeah that was like one year ago almost something like that that's awesome and today you're gonna take us through the same journey of discovering nhn uh building a node um from the source code and creating a node for us that's correct thanks here we go cool so what we did a few days ago was we did a poll and uh the top two contenders for which not that we should create were action network and post hoc so with action network uh we couldn't acquire unfortunately the api key in time so we're gonna go with post hoc today so hopefully we'll be able to still cover action network in one of the later live streams but today we are gonna build post hoc cool so i'm gonna share my screen and uh ricardo is gonna take me through the process of creating my node for anything awesome so and again ricardo do you want to tell me a bit about uh the whole settings of nhn like the workflow automation tool generally what do you use it for ah that's a really good question i guess i use it for everything nan empowers me to connect anything to everything it's really good when it's when you start using it and yeah you start getting like a breath of it you're gonna want to automate everything you find in your life with it guys that has a the features that i can mention you can you know keep data synced between multiple systems you can move data from one system to another you can even build your own backend api with it and yeah i like to think about it as max one of our co-workers said this api legos so yeah it's really cool awesome and i see in the chat we have uh stray joining us from india welcome trey uh great to have you here cool um now what you're going to do is um go to github and take a look at a newton's repository what do you say ricardo sounds good cool so we have anything here so we can take a look at the structure and i can share the link to the repository for you as well oh let me share the screen again yeah is it cracking a bit perfect that's it okay so

cloning the github repository

first step would be cloning the github repository locally so i can build it right yeah that's correct okay so let's do that so any specific location on my computer i should clone this oh no you can clone it whatever you want okay let's do desktop and generally if you are just running anything um you can do with npx na10 or you can install it with npm run docker join it in cloud but since we are going to be creating a node we need to build the source code so we're going to be cloning it locally and building it like that so git clone right and then we go inside the directory and what would be the next step now uh okay uh any n is built uh as a mono repository so all the dependencies library that the users are within the same repository in order to link all those dependencies we have to use learner uh it's an npm tool so yeah let's do that because that takes quite a bit okay so we can issue that command and then we can go through the file structure and take a look at what's inside what's under the hood cool so we do learner bootstrap yeah minus hoist perfect okay so while this is running so this usually takes a few minutes um we can take a look at an agent's repository so here we have different folders so i see we have a json file for learner this for npm and which would be the folder we'd be working in today we're gonna be working on probably if you want to contribute to the project you're gonna be working on the folder packages okay yeah there you can find you know the distinct the different modules that indian is built in so you have the cli which is of course the cli there you have uh the rest api within the folder um yeah i do there you have the databases the database migrations the database structure in the folder core you have you know everything related to code like when to activate a workflow how to decide debate a workflow and so on the editor ui is you know everything that is in the ui which is uh by the way is built on view js no depth is a cli that allows you to escape the project uh we're not going to be using that today but yeah it is an auction too as well this it is like it creates a template where you can start working on when developing notes and notes base is where you're going to be working if you want to develop a node definitely uh and workflows yeah it has uh a lot of utility functions to manipulate performance i would say but you can open now notes base and we can check have a look at the structure there could meanwhile let's take a look okay so we got an error here um yeah let's do something do learn clean okay yeah because i wonder if the what is in master right now is not building got it okay so i did a bootstrap hoist again okay so yeah okay then let's go with the project that you already downloaded maybe master is not building right now which is okay cool so i am gonna get the project that i had already locally before so when i do that um would you tell us a bit about how the different nodes work like how are they interacting with maybe an api and what are the different components of a node in terms of the operations as we call internet and they perform or the credentials that they have yeah basically you can have uh well there are two types of notes on anything we have regular notes and triggered notes uh the trigger knows just start workflow and within the trigger nodes we have like three types of three subtypes as you call it the ones that use a webhook api the ones that do pulling against a rest api and the ones that we had uh depending on event that happened in another system so that would have like a queue you're imagine that you're attaching to a queue and would you receive a message you want to start a workflow um yeah i guess those will be like yeah two type and two issue type of note that we can have got it just to keep you an idea that what you can do with the regular note which is what we are gonna be doing today is pretty much anything that you can do with node. js but the most common uses use case that we have is building a rest api and consuming a rest api right so while we figure out um the issue with learner do you maybe have uh and what's the best way to sort of get the repository before it errored out uh do you mean get the latest changes yeah um yeah no so the latest master is in building right now yeah uh that's usually not the case we i might need to check that but yeah i would say from after you usually you should check the latest changes from answer got it do you have a repository that you can send over and uh we take a look at so while we received this from ricardo let's take a look at the packages folder again to see where the node would exist so today if you go in uh note space and inside the notes folder you'd see all the different notes that exist in name so you see we have active campaign acuity scheduling and so on so inside these um you have different files and like some of these files we'll be creating today so as you can see like active campaign is a rather huge uh node with a lot of different operations and resources um but one thing that is within all the nodes is you know a file which is the brand name uh dot node dot yes and that contains all the settings of the node type the default name that's gonna show up uh the logo and so on and other than that we have usually this file called generic functions. ts which gets the details of the credentials and uh basically handles sending the rest uh request to the rest api of that particular service um other than that we have a logo file which is either in png so we i think ricardo svg is the best practice here right yeah yeah i would recommend going with the svg when you can because you don't have to care about the size uh a couple of places where you can find good svgs usually the company that you're creating the notepod they have a section on their website it's called either branding or press and usually you can find them there is no we sometimes use a web page called vecta. io it's a really good resource and there is a couple of keycap repositories that have a good uh good uh amount of svg nodes uh yeah i think we can try again can i just do cheap checkout to the vimeo remember the noteworthy yesterday a couple of weeks ago a couple of days ago yeah do check out dimi and then do learn another so we go in the desktop folder again and then we will be checking out a certain branch right we need to go limia believes is called so okay but you already have it uh clown so you can just go cd on there and that's it oh got it so in that case i would then do a git checkout uh exactly but generally this would be master yeah exactly okay do learn a clean yes and then dude learn you know bootstrap minus my hoist right um so while this builds um what would you recommend uh in terms of when we are when an svg for a certain node is not available uh and we have to use png uh would you what are some things that have to be kept in mind like does it need to be certain size uh should we somehow compress it uh what are the best practices that's correct you have to be 60 by 60 pixels and compressed the the website that we usually use to compress the png and logos are is a tiny psg that con i believe is spinning yeah which language so still no building and we are joined by jan from uh from the uk hey great to have you in the show so ricardo um the learner bootstrap didn't work here either what would be the next step uh okay let me what about something what about if i share my screen yeah let's do that okay so tiny png is a website you mentioned for uh compressing the website uh compressing the logo of the okay give me a second that's good let me see i'm gonna add it as a banner down there and another great uh website that i found for uh getting the logos for and the branding colors as well because we do include brand colors in the logos too is brandfetch. com so it's a good website for uh getting the logos and then you'll have you can resize them and use them in the notes as well yeah sometimes i just usually sometimes i just go find them on google images that's a good place to find no as well so maybe yeah just the company name and um logo and maybe ed square so it shows up there okay cherry wine perhaps this one right here can you see it yes uh can you zoom in a bit oh so you're using vs code is that something uh that you'd recommend uh using while building notes for anything yes of course you can use any editor you want but i would recommend this one can you see it better now uh i'd say one more zoom um let us know in the comments if you are unable to uh read as well so in that case we can increase the zoom amount what about let's say i'd save one more time one more yeah perfect okay then yeah let's do what you did already learn and clean and then they're not blue struck minus hoist oops okay perfect this zoom level is good yes it's building it shouldn't take a long time so while it builds uh perhaps we can talk a bit about post hoc because uh like that's one of the services that we uh picked up and we built a note for today okay got it uh yeah so i can share my screen on that as well okay so yeah like this is post hoc and uh it's an open source um product analytics tool you can build dashboards with it uh visualize analytics and so on and it has i think a couple of different offerings so i already went ahead and created an account on their cloud offering and you can also i think run it on docker run it self-hosted so i imagine that we'll need to have a setting in the node uh to account for the fact that people might be using it on the cloud but maybe they are running it locally and other than that they seem to have a great uh api documentation as well so we'd be using the documentation on the rest api to sort of build out the functionalities so yeah um i was looking at the dogs ricardo and it seems uh they have a couple of different ele different uh i wanted to call it elements but since they have a thing called elements here different resources as we call them in an a10 so we have elements events people trends users so what do you think uh would be a good use case for us to create today yeah the best use case i would say is to sending events to the tool to pass up perfect then we can see in the dashboard is how it renders out and how somebody using that in a workflow would look like perfect yeah that's correct right yeah having a bunch of events that you have in the data in your database and then sending them to to pass up perfect so i'm gonna uh pass over the control of the screen back to you okay so yeah learner finishes and then you know the first thing that we have to do every time we have to we want to create a node is create a folder within the node uh folder so this is in packages node space and then yeah within packages notes base and then nodes perfect so let's go ahead and do that and what's the style guide like what do the uh what are the best practices in terms of naming a node like i see that we are probably following the branding of the tools like i see with active campaigns cs capitalize and so on um so what what's the how should a folder be named for a particular node yeah it should be old folders as you can see follow the pascal case format got it um and in case like we have a table for instance which doesn't have pascal k so it would just be uh first letters capitalized yeah okay yeah i guess passive k will apply in case you know there are two words instead of just one got it so there wouldn't be a space in the name of the folder that's correct that that's going to be allowed so every hand once we create the folder now we need to have like a file a file has the same structure but a big similar structure that the folder is the folder name uh plus dot no plus dot pf as you can see if i open other nodes all of them follow the same app this one is not the best example follow the same structure so the name of the node uh dot node dot yes that that's good that what i usually do is just copy and to you know to start creating this folding assignment of the note i just go and create uh fine for another note ricardo are you still there right here oh the cat is back sorry you cut off when you were mentioning about the scaffolding oh i'm sorry about that was what we usually do when once we have the file what i usually do is i go and look for another node that had a similar functionality to the one that we're going to be creating and you know copy paste back here and start you know working on top of that got it and would you say some of the notes for instance have way more functionality than other because maybe uh they have a more extensive rest api or maybe they are just older notes uh which have been like fully built out um would you say some nodes are better as compared to others in terms of copying the initial scaffolding from or would it depend on yeah i would say i mean yeah if you're going to be if we're going to be consuming and rest api probably i'm going to copy from a node that also consumes a rest api which is in most of our cases to be on it yeah so yeah running profit well i know it's consumed as a rest api so that's the reason why i'm gonna be copied from there perfect okay copy here paste it here okay he looks way bigger than he looks from the screen ready okay once we copy this i see we have a lot of different options could we maybe uh go from the top to bottom in terms of uh what are we doing for the different pieces of code yeah i mean what's going on yeah all the notes you know uh is basically a class and that class implements another type it just means that you have to define or conform to all these properties uh in order for the node to work usually the properties that are on the descriptions are the ones that would affect how the node will look on the ui for example you can have it running right now but do you have it running luckily sorry yeah let me do something really quick do you want me to show the uh profile node no i have already okay and nh10 would be running on the 5678 board of localhost i'm gonna give you an example once the node is load you're gonna find it here on the right menu and you're gonna of course you can add it to the editor ui so but what you can see here is what is defined here on the file that i was trying to show for example you have the display name is what you find here the logo of course is the logo that is admin when you add the notes editor ui and what is chan here on the right menu uh the subtitle is what you're gonna see right below the name uh we have the name of the note which is this one right here which by the way is different than the one that it is on the menu and the corner which is probably you can see the outline here is that color that you can see there and this is the brand color that you mentioned that we yeah that's correct that usually is so do you know well you can either inspect the quarter of them of the logo or that's usually also an info that you can find on the company's website got it so i guess yeah let's do that let's make it let's make a joke in the ui first and um the pieces of code that you're commenting right now uh these were specific to the node that you copied the code from yeah and not really i just want them the warning right now because we are not going to be using that right now okay but yeah we will get there so yeah i can just start and you know no data just change the class name to what it should be the logos the node's name let's here as well can the display name and the class name be different uh the class name yeah the class name has to match the name that you have from the folder that is plain anchor the difference yeah but uh i don't think we've ever done that you know it should match perfect okay the name and i noticed that uh in the name you have p small so is that something that's done with all the names yeah that's correct there's a standard here we use comment case instead okay so i don't have a logo right now i don't have the lower right now but i'm going to add it in a bit we're going to be consuming the boss i can send the logo over to you okay what's up api uh i hear you received it okay so i just also got a message uh from jana founder and ceo so he mentioned that this is probably the issue that i faced uh is probably because of the node. js version so i mean that is something to keep an eye on is uh that you're using uh updated node. js version which might be the case here i'm not sure when i updated mine last time so thanks ann yeah that's why i recommend using mbm because you can control the version that you have real quick with the cli god okay and i just sent over an svg logo of post hoc to ricardo so we can use that uh for the node hey almost there so would you be pasting the file in the folder now yeah that's correct you are about to see that yeah here you have it perfect and here on icon i can properly you can see how i reference the logo right here so we have we can do the png or svg and the naming scheme is similar to the name of the node that you have follows the same of the property name the only thing is you have to add the file before then that make sure that you always you know have the tension perfect okay so okay i'm gonna be commenting this is not needed right now since okay what we have in property is what you are going to see when you double click on the node if i go to at the campaign right here when i open it this right here everything you can see here is what we define within properties uh nen uses like has a preview ui elements where you that you can use to ask the customer for different type of information whether it is in a string a number uh yeah a date a caller and we have a couple more so i guess our next step right now will be to build our ui if you can use so i had a question um in anything there is a resource there is an operation and then there's different fields so the highest level thing is resource so let's say we took a look at post hoc's documentation which i can bring up on the screen now um so we have a couple of different things here like elements events people so these would be translating to resources in it and things within that like listing events creating an event basically crude operations those would essentially be uh operations and then the things that we need to send off to the endpoint would be fields for that is that correct yeah is that correct usually the if you are building a node for a rest api the resource that the rest api of your familiaris api is the resource that you're going to use here that's usually the case and the operations uh yeah the crew operations create delete get all and update yeah you might find something sometimes something different and this is the chaos possum they have instead of even create they have something evan let's take a look yeah i don't remember though so they have list trends okay so we can get uh events here and then we can specify properties that as well yeah that's correct i can go to i guess you can into the event post event you must be around there okay so this is an example response so example request would be uh yeah it is not quite that one you this you have to scroll a bit more okay was it a different page oh go to post only probably then point okay go to this scroll a bit okay we have a whole list of other endpoints yeah singular yeah is that one so here we see it's like a post request and here we'll have to specify whether we are using the cloud or running it or self hosting it so api key we generate from our account and okay these are the details for which we need to have fields so maybe events is a resource uh send single event could be your operation and these would be the so this probably would go in the credentials part of the ui yeah that's correct maybe the instance name as well yeah that's correct we're gonna need the instant name and the api key for the credentials and depending on um it seems like the event and properties uh we have to provide and timestamp seems to be an optional uh parameter just correct that well i think even name and properties are required the only thing that is optional is a timestamp perfect so yeah we basically are we're going to build the ui that we need so the user can provide these fields don't know perfect so this is the uh functionality that we'll be implementing in the poster or today yes that's correct we're gonna be yeah they call it capture and event we're gonna do even create an event just to keep it a bit standard with what the other notes do we usually use you know create they get all on update perfect before we move on um i see we have another question uh in the stream from teflon dude so he asked would i be correct in assuming that svg files are preferred over png files for icons since the svg files are vector based and have infinite resolution oh wow that's an amazing question that probably max have an answer for okay um perfect and i think uh another good thing about these uh icons is like uh these if you zoom in to the editor ui um they would still show nicely uh and maybe the png files um oh god yeah yeah i got it now i guess it means it's too big you said yeah actually uh yeah it would look way better mostly if you have a higher resolution screen you probably are going to notice the difference type but i always try to go with the svg version perfect and uh we recommend that uh svg be used if it can be instead of png yeah actually we're on the process because at the beginning we didn't have support for svgs just pngs and we are on the process of moving all the png logos to spgs perfect makes sense cool um then back to you let's create this functionality so first of all uh would we be uh looking at okay how do we just get the note there with maybe no functionality no resources just post hoc showing up in nhn is that it that it yeah that's correct that's good okay let's then yeah make this let's make the no joke on the ui and then we will go and create the parameters work i'm going to be commenting things in the meantime because we don't need it just yet okay if i build this if i run the project right now with this node we still we're not going to be able to find it on the menu so hence you're not going to be able to add it to the editor ui what um in order to do that we need to register the no we're not we have to tell nan that he needs to load that note the this is actually one of the common mistake that i usually see and to do that we hope to the notes based note notes base folder okay within there you're gonna find a package dot json file within that file forget about it this now you have a property called nodes not right you just have to add it there so it lists all the nodes that show up in the editor ui infinity yeah yeah if i remove all these lines in here general they are not gonna show up on the ui okay we don't want that to happen yeah that has happened quite a lot to be honest actually does uh we always have to to get that question in the community got it so is there any good practice when adding a new node here yeah we just add an alphabetically usually okay so it should be sorry about that no is the worries usually full follow the same pattern here will be the folder and here the name of the file and i noticed that um it says here nodename. node. js instead of ds is it because of how edit10 gets built when uh you compile the code yeah that's correct because your reference you're referencing the js code that was transpiled that's good that you mentioned that because right now we're gonna build the project so we're gonna do npm run build this is probably just gonna be needed the first time that you don't know the project you know switching between branch okay and uh learn about strap voice so that needs to be done only once um yeah okay i mean if you don't know the project did you do it once you don't know but if you change branches and the library's version changes then you're gonna have to be doing learner again okay how long does the process of uh npm run build usually take yeah it takes a bit i guess it's gonna depend on your computer but i would say take a couple of minutes this will move on though okay um the order okay the project is built now we have to run the program test mode and we do npm from that okay takes a bit and now since we added um the name of the node on uh just like the line with this nodes uh posthawk talk. node. js this would show up in the editor ui now when you open it yeah on a start top nam will read this file and we'll start loading all the files that and that are listed on this arrive as you can see if i refresh now you can see that here is the perfect even added to the editor ui no we choked it's fine now as i mentioned we still do not have any ui we didn't know if you double click on it you will see that this is empty that's what we are going to build now

add the parameters

we're going to add the parameters that the user need to provide in order to you know achieve the operation which is creating a an event perfect so where do you start right now yeah that's when the i was as i was mentioning the properties arrived comes into play there is a bunch of ui elements that you can use as i mentioned before um all of them follow the same structure and what i mean by that it's all of them you know display name type and depending on the type you can have extra options but most of them are pretty much the same uh as we mentioned before probably if you know because he's consuming a raise address api he's always gonna have a resource and operation this is not required but this is like a standard that we have within the company uh actually if you check all the other notes you're probably going to find that all of them have resource operations organizing the functionality that way we can you know ensure that um that all the functionality is highly findable by the user because sometimes they can have why some python operations acquire some resource so okay our resource we said will be event so i remember that um we took a look at post hog and it said uh events so is that something that we do in nhn uh like should the resources always be singular oh yeah that's correct glad that you meant all resources and all operations are always singular so let's say if you're doing a crm and it has a resource like contacts or companies so when building a node for that we have to name the resource contact company and so on yeah that's correct okay and default is the one that would be selected when you boot up the node for the first time yes that's correct when you open the note and then it's looking for what to render and it renders that file that field you're gonna see that the default is gonna be selected i mean if it exists within the options perfect okay then our second required standard file is operations singular as well and in our example this will be create we set it as a default as well and yes and now i guess you can you can let me know since you up there what are the other fields that we need in order to create an event i remember that one was event name okay let's take a quick look at what the documentation says so i've added that up so we have event one called event uh where we enter the event name um then we have properties which have a couple of things like uh distinct id and then key value pairs and then we have another optional item uh optional field called timestamp okay perfect switching let's do that we have as i mentioned before we have a bunch of types if you go here you can see all the time that we have boolean collection caller date time takes collection json multi-option number options so everything you need probably is already built in here so you know every name is just as a string we are going to use the string type and just i see like you have called it event name here uh and this is um in camel case so the rest api asked for event so it doesn't have to be named in the same way no exactly i mean later you're gonna see how we can reference that name on when the node is executed and then you know assign it to something different before sending the request perfect okay this is not needed because this is just for options my default will be empty and then event okay this is of course is required i mean this field right here is very important if it is required the nodes won't let it won't let you execute it until that field is filled so since we need the name in order to create an event then i made it required okay the other field you mentioned was so now let me bring it up we have properties so this looks like an object uh which has a distinct id which is your user's distinct id and then a couple of key value pairs yeah i'm going to add it outside the object but probably going to make saying it's going to make sense later okay and i guess like um you can get data in a way from the users of the node in the most convenient way for them and then you can always restructure it when sending it to the rest api yeah exactly that's exactly what we're doing here the it doesn't have to exactly match the shape of the ui u of the rest api because we can later map that data to something that the recipe i understand i see a small typo with the name distinct id oh here all the variables in n10 are gonna be uh named in uh cameron here can you share with me the link of the api real quick sure there you go in case uh you're wondering i can also add a link at the bottom if you'd like to take a look at what the end point of postdoc looks like and we're going to be using that for building up the ui and meanwhile if you have any questions uh for those of you listening uh please feel free to enter them in the chat and we'd love to answer those okay we have the distinct id the other thing that we need are properties let's add that now to appropriate things we have it isn't an object that we have to do key value pairs we have to use another ui element it's called fixed collection and let's say if we are building some other node and we need boolean uh type just as an example or we need a certain element type but we don't know uh what it's called in an a10 i know we are working on a guide for that uh for the docs so that you can get that detail but meanwhile like what's a quick way inside the editor to get that information yeah i mean you can just go to the type properties infection and then you could see all the types that we have you can also score see the component that you're interested in on another note and then inspect the code and just copy from there like which is later that i'm doing right now i'm just gonna copy this distinct collection on here perfect that's a quick way uh to then prototype and check how things look probably because it doesn't happen before okay let's call our fixed collection properties i see another question coming in do we use uh tabs or do we use spaces oh will you stop does this number yes perfect yeah actually you can see here down here that i haven't set it to i and we have uh dot editor quantity file that you i believe you can add to any editor and in our moment i mean if you load it will automatically make sure that you are using tabs and certain sizes instead of spaces okay um so now we are doing fixed collection so what does this actually look like because i think like string is explanatory in terms of it's going to be a field where we can oh yeah i can check an example is it similar to what we have in the set node yeah actually that's what it will allow me to somehow isolate that properly you know we're going to have an object and then it will separate the properties from the main parent so in this case this will be the properties and here we will have name and key sorry key and value yeah they usually add as many as they want so yeah i mean i guess we're gonna it's gonna look better this is gonna be description you can set this to just be able to save one value or to sell multiple values if you say that you just have to not sell multiple values then you know you wouldn't be able to have more than one okay if that makes sense yeah but here i think the rest api allows us to send couple of key value peers so we put type options to multiple values true appropriate value okay we are all set here and the last field is if i remember correctly is timestamp right yeah since timestamp is not required we are going to use a different type as well it's called additional fields and you can see how it will look here we as a standard we always want just to show the users the fields that are required and the ones that are optional you can always use and you know they will be nicely hidden here so you do not overwhelm the user with you know a bunch of parameters maybe this is not the best example but if you go to something like salesforce that have you know maybe to add you have yeah just the email and the first name but you have like a thousand optional fields then this starts to make sense so let's do that so rule of thumb when creating nodes uh the things that are required for the api to give back a response they should be beneath the resources and options and everything else that is optional goes in the additional field section yeah that's correct okay let's do it as i dig with the fifth collection i'm gonna get it from no um why do you uh look for additional fields so that uh you can copy okay yeah exactly usually the collections all call additional fields that's what i was looking for that mean perfect that's handy oh it is thank you and we have uh type to provide dates mistake time to recover there then okay now let's see how this looks now every time you make changes to the ui you have to run the npm uh around that again so i'm gonna kill the project here i'm gonna do empty and run this again just gonna rebuild the ui uh actually the ui has been it's been building every time i saved that's transpiled it's been built the problem is that nan don't load the latest changes on the start so i have to start any and again so those changes are reflected on the ui got it okay refresh if i open the note you can see that we have everything we need right now we have the m name here you can see the description that we said there the distinct id the properties now you can add a bunch of properties under additional fields you have you know the timestamp that is optional and we didn't write the code for this calendar pop-up to come by so is it because it's because of the pre-built your elements yeah that's correct that comes out of the box awesome and it gives it won't let us execute the note because we haven't filled out the required fields yet yeah that's correct here is you can see the error around here i try to execute it you're gonna tell me which uh parameters have to be set in order to be able to run the node so i guess we're still missing two more parameters in order to make the pull request and then the http request and that's the api key um the url right yes and uh i'm bringing it up to my screen um one thing that we are missing right now is a distinct id as well um it's inside properties so would that be something that we need to add as well oh yeah we're gonna be mapping now mapping that out before making the request perfect so okay let's do and add that crunch every sensitive information that you need to store like api keys it is handled by credit by credentials within nan and within the credentials you can ask the user for you know these credentials and they are going to be store on the data encrypted on the database so you don't have to worry about them being you know locked within and please go by default in any 10 sqlite database yeah that's correct by default on that unless you define on the environment variables do you change the database it's going to be default always it's a cool execution so to add a credential

add a credential

we have we go through the same folder notes no space which is inside packages right yeah that's correct inside packages and there is another folder called credentials we create a new fielder new file there we use the same name that we use for the note it's a post hog and we added apis is that something that we add to all of them yeah as you can see that you can you're going to find there all over the place because probably most apis use an api key perfect i'm just going to copy the code i'm from here i'm going to add it here this is a much smaller file because not so many options that need to be entered i guess yeah and do we usually there is just one one field here which is the api key that's the most common case so as you can see when if uh i have a question so if we were building just uh i mean just as an example only for post hoc cloud then we would need only api key as well but since we want to generalize it for people maybe who are self-hosting uh we'd ask for two options here yeah exactly we're gonna as you can see this is quite similar to what we do with the note we just name it this is the name we're gonna use to reference those credentials within the nodes so it's the same as the name of the class button yeah here this is the display name we're gonna see what that about a bit and what's this documentation url oh okay this is gonna point to the ne n dot probably i'm gonna

create the credentials

but when you create the credentials and you don't have what to find then uh and you open let me show you for example you want to add credentials and you don't know where for example i find this access token you can open right here and that's the direction of the node in the dots and it would give you detailed instructions on how to get those credentials perfect okay i'm going to meet this in the meantime but that should be included and uh just in case uh somebody is curious around uh where the code for the documentation lives uh it is also on github yeah that's correct we have another rebel portal that perhaps you can share the idea and here we have the repository for the documentation okay this is we have api field and now we need one more field plus the user which is the url these both have strings yeah that's correct but you can see you here can use the same ui elements that you can use within the note though all of them are available down here and now we have to reference uh to tell nan to load these credentials as well which is quite similar to what we did with the nodes actually you go to the same file within node space it is the packet doj oops so no space back you start jason same fight baby yeah instead of registering in the notes um all right you do it on the credentials and we call it registering a credential registering a node yeah that's correct okay cool you're gonna still define it but if you know again if you don't add it here it's not gonna show up on the ui and these are the only two things that have to be added to package. json for things to show up in um in the ui right yeah is there anything else that needs to be added in this file um no right just notes and credentials in case that you need to add a use a custom npm package for some reason you can if you want to have access to that package within node then you have to add it here as well as a dependency got it but engineering yeah that's what i was about to mention you usually do to have everything you need within the know we try to uphold avoid as much as we can dependencies okay i'm gonna add it right no oops where are you okay alphabetical as well yeah i'm not following the rule right now but yeah okay do as we say not do as we do okay and now we go to the node and basically we just tell in the end that this node has access to that credential type so remember then the name that we are here is the name that we're gonna use here okay so now since you called it postdoc api this node wouldn't have access to uh like earlier it was profit well for instance it just has access to that yeah that's a way to i would say linkedin yeah okay now i close here give the process run it again and uh do you already have uh instance of postdoc running or are you going to use cloud it i probably going to use cloud actually you can charge your credentials okay i can uh share my screen now so as i mentioned i already went ahead before the live stream and created a cloud account for post hoc so uh this is what it looks like and i haven't created anything else other than what was present by default so i took a look at the api on their website on their documentation and it seems that we need to get personal api key so clicked on it and like they have a pretty good description that's always great to see in documentation it's like way to find the api key so we'd go to uh my accounts personal api key then we have to give it a name let's call it 10810 and i'm gonna take myself off the stream for now so that this stays private so i clicked on the create key button and i can then copy it over and i'm gonna send it yeah i think actually i have ones right here so i don't think okay yes so i uh run the program depth mode again we came here we refresh as you can see when i open here now this section credentials open chosen perfect you can have multiple post hoc accounts attached to the same node so if you go to create new you're gonna see the two parameters that we have which is which are url and api key i already have one here and let's say we are using the cloud what would be the uh okay yeah but um that's gonna depend i guess it's gonna be the host name um the whole direction of the server where you deployed the default uh postcard cloud uh what is the url by default uh that's a good question you must be on the dots okay let's see it's https apps dot app. posthawk. com so assuming that some people might be trying out uh the cloud version should should that be put as default and yeah actually yeah that's a good point we've got to send the url of this to you oops okay yeah you can set up before by placement again and with this effect existing api keys as well uh yes okay i mean uh if they exist the value probably has been said to them so uh but i guess okay if i go i refresh if i go now i said by the way okay of course you have to set your api key i think i have it set already we would here so we will check that in a bit so i guess we are fully done with the ui now we have to take this data and make the actual http request right okay let's go to do that go to the know which in the case of um event creation is a post request yeah that's correct so let me delete this because it's not gonna be near today then i'm gonna while you clean this up i'm gonna quickly share my screen um so on their documentation they actually uh say this is like https your instance. com so this would be the url like if you're self-hosting uh that you'd have to enter in the url field and these would be the endpoints but we'll define it later on okay ricardo back to you so what are we doing right now

setting the description for the execute method

okay and you're setting the description for the execute method is the one that is going to be executed when you execute the note so okay to make the http request let's first make a function we usually have a file called within the node folder called genetic functions and then you there are you know you can have a bunch of helpers so it's always called generic functions and all the files uh yeah i mean it's not listening not necessarily have to be this the uh that name can be any name but we usually use any functions if you open all the other nodes you're gonna see that and we can copy base code from them and just uh take it all into the specification yeah as long as it is uh apm res api yeah the generic function should be pretty similar because all of them and i'm just doing an um http request okay oops okay no this is okay this is not needed because this is for the trigger so yeah when consuming a rest api which is what we are doing right now we actually have one method which is api request and just pass a couple of parameters uh the method in this case will be both the endpoint slash event and the data we have to either send on the body or on the query this one doesn't have query but it's okay because we don't need it right now so let's start changing adjusting this and i noticed uh like we already have some headers set here from the uh the note that you copied it from so yeah probably a couple of these are not gonna be needed we're gonna chat in a bit so i'm gonna open up uh i can share my screen let's take a look at the documentation um so it seems there's a couple of ways to send the api so if you look at the api overview under authentication we can either send it as a header with like to appear authentication or we could put it in the request body but we could also put it in the query string so they do offer like a couple of options here so what should we go with does it matter yeah i guess i'm gonna go you can use either but i'm gonna go with the body version okay so that goes in the body and i see like um perfect they do have they used to have a username and password of authenticating as well but that's deprecated now okay i'm gonna give it over to you okay uh yes i guess then in the heater the only thing that we need is the content type strong in example the url would be what we define okay something that i forgot to mention we have um a bunch of utility functions to make all sorts of things within nodes for example access the credentials that the user provides that probably you are going to need to consume never to consume the rest api and also we have helpers that let you make the http request so this is all handled for you got it right here just referencing the credentials that keep in mind that this is as you can see this is the same name that i use here yeah and also the credentials file right yeah exactly those three have too much and here that response will give me the credentials that the user input so since i have access to here to the your url so that okay credentials. url and okay so in the other one it was string because there was oh okay no it has to be added object because there could be a couple of things yeah and here will be slash whatever the person is in on the endpoint this is just literally you know assembling the url which will be the base plus whatever we pass in the parameters in this case would be slash event so the method is coming from the parameters but okay here and then just changing them okay i'm gonna quickly pop over to the documentation um so here we see we have this sorted out for assembling the url because ricardo already is getting this information from the credentials file this slash capture is going to be the endpoint that we are going to define later on um in the header he has mentioned content type application json and all this other data we are getting uh from the ui of anything so we pretty much have the bits and pieces ready to send it off to the api yeah that's where everything seems to be okay with our function okay okay make sure that everything is okay we import a helper and did we also send the api key in the body oh yeah good point yeah i think we forgot that we do whatever the user say plus the can you show again how is the proper name things api key right um i'm not sure we better check uh okay you mentioned in the body yes you're right uh api underscore key yeah okay so now it should be done here now we have to import this function on the node so we are able to use it now we should be able to make an http request from them okay the first thing that we have to do now is grab the parameters that the user define in the ui there is a helper function to get these parameters called get no parameter so i have a question for you here uh so we see a couple of things defined in the execute so you mentioned like this is a method that we need to run the node um so i see we have items uh that is that defines the data that a user enters in the ui no ident is the input data that is coming to the node ah okay then okay so if there's data that already exists in the workflow that's getting inside the node and maybe yeah if you have a node right before the the the backup node then you're going to be able to access the data that then no output outputted here within the execute function got it and then we have resource so for resource i see that um yeah i mentioned that you're getting the zeroth object yeah actually i didn't win i had this as a folding right here because it's pretty much what you're gonna find with creating an api node uh yes but if you go to the other nodes you pretty much have the same structure you always grab the resort and the operation and then it over all items we're iterating over all items because we're gonna exit make the http request for as many items uh these no gets for example if i have um i don't know i might secure no a database note before this one and if you do a ghetto that retreat i don't know 10 persons okay join people you want to uh add those 10 people to possible you don't want to make a for loop so it's going to be easier for the user like that so and it will automatically understand okay yeah our number of items came from um the previous notes so act on all of them one by one so actually that was the first thing that i thought was like magic because i thought at the beginning that actually i was looking for a for loop now i thought i had to you know do a for loop every time uh i went to italy over a bunch of islands um no i mean any end does it for you it's really good because if the workflow is really small perfect and here then we can do any like conditional logic on uh the resource and the operation that people have selected so resource event operation create then that's the action the node is gonna take behind the scenes yeah that's correct right now yeah here we are getting the resource program there is just one so probably this is going to take the event and create and yeah brown we're going to get all the

get all the parameters

parameters uh right here in order to send them to the api using the same function we just have is just get no parameters and you put the name that you define right here then you have access to that data perfect let's do it and here unlike the resources and operation you mentioned i because it goes in the for loop so get all the pieces of data and iterate over them yeah that's correct oh yeah this is pretty much which is great because if you uh let's say uh and no have uh a billion or 10 million items coming through you just create three note workflow or and then yeah it will automatically do all of them yeah perfect uh where's significantly speeds up the dev time as well like if you are creating back-ends or uh things for reporting it's very quickly to set this up as compared to you know set all that up so it's almost like creating uh packages for a programming language because you create this node once and everybody else can then uh use it in their nhm instances uh they don't have to write code for connecting to post algorithm yeah that's 100 correct awesome okay we have every name this thing id and now we need the properties i can see how creating nodes for an a10 is addictive oh yeah when this not working you just want to keep doing it yeah because this might be empty regard how did you get started with this uh process of note development uh because like you were one of the early adopters like you came in very early so how did you learn all this what was that i just saw what jang had done with the other notes and i just started you know trying testing until everything worked out baby also was pretty responsive to be honest so that's one of the reason why the project i keep contributing because if i had any questions we didn't have that much documentation but then if i had any questions he would quickly answer to me so yeah jan is our founder and ceo and also the creator of na10 and uh he is still really active on the community uh like if there's any questions uh they always get answer uh very quick it's also really cool to see i think ricardo got a lot of knowledge from him and then regatta is also now mentoring everybody else in the company and we call him sensei ricardo yeah i mean the first note that i developed the mandarin note that it was terrible just because i put every all the fills using a string i didn't have that we have more than a string as ui elements and then john told me oh you can use you know six collection um collections uh oh i see okay we have this body okay so looking at the there sample query we you already got the event name here api key is being sent from the generic functions. ts file properties we have here distinct id we have here and body uh i think timestamp is one of the other things oh yeah that's great that's really good and body is okay this is going to be the body of the post request so how do we handle time in any time so i saw that um we have a date time ui element which opens up this nice calendar pop-up um how does that how does any 10 handle that input that comes from that ui element oh it is format uh utc i'm gonna and a bit i'm gonna print it then you can see he actually thing is using moment under the hook so it's just an instant the moment that is formatted to uh okay i forgot the name of the how to send the parameters i know the one is properties i know that we have how is it called the even event okay that's what i will tell you that doesn't matter how you put the fields in the ui you can always map right here before sending the request i mean you in the ui is called event name but then you can i can set it in the body as an event perfect and then we have time stamp outside as well yes but that's under additional feed so we have to do if so only at this if that field is set yeah that's correct because the things is optional if it is not set we don't want to add it to the body uh but you also know that field has a specific format right um the timestamp field yes let's take a look so yeah it does say optional timestamp in iso 8601 format um i am very curious to know what that is uh okay so that is uh eo4 5y hyphen um mm hyphen dd yeah i'm going to use moment which you can always import the library uh within a note because we use it internally so probably moment is going to be helpful to parse the date to put that form perfect back to you so n18 already imports a lot of useful packages um for no development like request because i saw in generations you're using the request library here we can use moment so if you are looking to maybe create some functionality take a look if anything already has that and regarding the best place to look for that is in package. json in the node space folder yeah that's correct there you can see all the oops all the no packages npm packages that you have access to perfect so before adding your own maybe uh take a look if anything already has something like that so we don't uh bloat up the repository and the dependencies yeah correct okay oops here is this thing okay how is this piece so let me share my screen like this right it's distinct underscore id yeah just map it to different formats and here we use this and why have we uh not defined it inside the body object uh because it's a part of properties okay that's good so yeah the only tricky thing here is we have to map an array of key values to just one object i think i have done that before so i'm not gonna start from we have a message from chris thanks for nate and masterclass learning so much uh thank you sensei ricardo for this oh really cool thanks for joining us chris okay i'm gonna copy this because i did it before but this is literally mapping uh the data to something the api the up the post out api understand i'm looking crazy here okay now we have all the parameters and we have then in the format that we want and now we have to make the actual http request uh and we reach out to the method that we have uh in the that the one that we just imported perfect let's see okay because this the first parameter is a method going to pause second parameter is the path which is i don't remember can you share with me so um first parameter was uh okay so let me share my screen so it is capture oh okay the end point so third part of the url is being defined in generic functions itself okay that that's correct and the third parameter is the body we have formed in this file yeah exactly and to be honest i think we should be all set this is not needed awesome so now we execute the node and it's gonna there's a data dashboard you know what send me for private your credentials so you can charge your dashboard because let's do that give me a sec there we go so url would remain the same since we are both on uh yeah can you switch screens while i add the new credentials oh yeah let's do that oh no hold up i have it on live stream okay um let me i get we can delete them okay so i am gonna generate a new ap here ricardo okay sorry my screen froze so um okay so we are going to generate a new one um using the same method so it's nice it's a quick administration uh within post hoc as well if you accidentally expose your api key on a live stream like me it's uh easy to um yeah fix that okay so i have to give you the previous one and send a new should i share my screen or let's look at your screen now yeah you can see i already added them so let's see how it goes okay so now we are looking at your cutter screen so you have added my api key yeah i just did they're right here now let's create another name i don't know any intestine and id i guess this is the user id and it can be whatever so let's do testing in the meantime okay that didn't go quite as expected that exceeded something it's a 403 what does that mean let me see access to the requested resources forbidden maybe i didn't save the credentials okay let me take you after uh a second just to make sure okay i was too quick oh yeah give me a second sure okay so meanwhile by ricardo yeah but i guess because if you develop a new one the first time you hit the the http request successful then you are the man yeah that's like a uh occasion to pop the bottle of champagne okay garbage okay wait a second of course so yeah and i have like a default dashboard when i um logged into it is weird because it's telling me that the api key is invalid let's look at your screen okay let me check what's going on there but let me send it to you again okay i wonder if it takes a while for their api keys to be active i shouldn't be honest okay i'm gonna ah honey still is so that gave me good perhaps is the first one that you share with me did you just create another one i know it's the same one right um okay uh what uh how does it start for you the api key all right that's it hey sorry ends in k that's correct um maybe do you want to show it on your dashboard with your id because yeah give me a second let me set up the because i already have one so let's take a look at uh while ricardo is figuring that out let's take a look at post hog so we have a default dashboard which it says my app dashboard and okay i'm just going to refresh this page okay i see we have a dashboard number here and there is no data because we haven't sent anything to it yet so it seems like we can also create a custom graphs here and see we have events here which is perfect because i think this is the end point we'd be actually sending it through to and we have actions event stats um any electric atta no do you think it's is it because we are sending um the api key and body do you think that might be no i don't think that's okay yeah okay so i'm gonna uh share your screen now so we can uh help debug with you okay yeah i'm trying to put the dots to see me and send me a primary different okay so we have the content i've said if anybody spots uh what we are doing wrong please um send a message in the chat always helpful so with the distinct id says your user's distinct id but i think that's not an issue right now think think okay don't tell me stop okay give me a second no it's got you there is a pool so you added a console. log here to debug yeah i mean i guess i will delete that come on so i see we have api key we have event um properties distinction i wonder if they have two types of api keys or something because he's telling me the price oh do you think it's because we haven't entered a key value pair because those aren't optional oh succeed perhaps no that's not the case okay go to settings oops oops and there is nothing that i can do now projects ah is different the personal life api key than your pro api key i see that that's great oops um yeah voila also if you look on the document for the post-only public endpoints it says on the top update these endpoints can be accessed with either your team api key or personal api key but that doesn't seem to be the case you just work with the project api but not with the with the personal api but it also says for this api you should use your team api key from the project settings page so ah yeah i guess we're gonna be saved there so maybe the personal api keys for something else yeah probably so if you go to events you can see here the event and even with the key pair that we set cool so should i send you my project id so we can see um of course okay so how let me so project let me show you my screen um how do we get the project id uh okay let me tell you real quick is on the left menu under projects okay default project okay let me send this over to you there you go this would show up in my dashboard i think okay so we have this digital right now okay you just send it right yes okay in case i go here and then take this safe and then hit i can see the kind of screen right now i see here oh yeah yeah the refresh okay let's refresh no nothing yet or do you think it's under events yeah it's on the events ah okay of course because we sent it to an event and we have it we have the timestamp and the data that you entered so distinct id you said testing and these are the key value pairs and i also have your ip address yeah that's added by the by them yeah perfect so can you see maybe uh how this would look like if somebody is using um post hog with um let's say maybe we can do is we can add an

add an interval node

interval node which like triggers the workflow every second uh we can have a set node to specify um some key value or actually we don't even need a set node we could uh have a random number being generated in expressions that's good right so let's do that do you want to do a crop yeah let's do a crown i can crown trigger per second uh with custom i think uh just trigger this every minute and then maybe we can do with interval because with that you can trigger every second i guess you can do that with cron as well if you use the custom cron uh custom cron expressions but uh quicker this way i guess okay one every second this is gonna be cool hopefully we don't hit the right limit so we update the workflow and then this should be you should be getting can i share my screen now just yes oh there's one event click here to load it and yeah it's sending data every second basically so this is quite useful so let's say oh okay yeah let's deactivate the workflow before we hit the api a little bit but um no this is quite useful um i think what we could be done is we could be getting data let's say from an iot device like i mean how awesome are iot devices uh we could get data like temperature send uh pressure and stuff maybe send it to mqtt it's getting sent from the device to a queue and it then catches that data with mqtt trigger like we now also have kafka and so on and then it pushes to postdocs so you can really visualize the data that's coming in nicely yeah that's correct that's good this is really cool um yeah this is awesome so we're gonna hang out for five more minutes um unless there's something else so like if you have any questions please uh comment and we'd be happy to answer anything yeah i'm just gonna share ricardo screen to see the awesome workflow that we just built and um regardless you're going to send now a pr to the code base so that oh yeah probably uh we're gonna add a couple more operations probably get all day and delete and that should be properly released on monday so you're going to be able to use it awesome that's quick i can see how this is really addictive okay just is when developing nodes one burning be careful because he's really addictive and then i can tell you that that's true because you have developed by some already yeah it's really fun i think like um it's almost like developing packages for i don't know i used to be a python programmer earlier it's like developing packages for that because okay you create it once and it's just so rewarding seeing people uh use the notes that you created in workflows enabling so many different things um that's really awesome yeah what was the last note that you created uh legato that that's a good question yes i think it was i mean that i made changes too to the demio that you were working on i think that was literally yeah i think like uh that's that's a good dirt as well so we just for some context what we did was we are planning to do some uh webinars in the next uh next weeks so we uh we're gonna be using demio for that and they have a rest api which is awesome so we also created a node for that to just get some uh details from there and do some registrations um okay so i see a couple of questions from chris first question is um do you have a good tutorial on how to do the initial setup so yeah right now we have on the one of the github repos there is uh there's the steps that you need to follow to set up the perhaps you can share that tonight yes um chris also just for context uh we are also ricardo and i are working on a tutorial on how to create your first node so estimate we probably have something made next week a new page in documentation like detailing how you can create your first note so everything we did today distilled down but till then uh we have uh contributing. md so it has some information on uh setting up your uh dev cycle or dev tooling so you know clone the repo go into the folder do a learner bootstrap um npm run build and so on so this is how like you can follow till now on how to uh set it up initially for yeah for development and if you're using mac you'll have to do xcode uh select hyphen have an install so that installs like git for you that installs a couple of things right so that's going to be useful and how next question is from chris how to install learn on a mac so i saw this recently from the tutorial uh that ricardo is working on so if you have npm installed already uh you can install it by doing npm install iphone hyphen global uh learner so that will uh yeah help you install learner and then you will be able to do the initial bootstrap host let's add it here and we have um final question from chris how to run dev mode so i think the contributing. md has information on running this dev mode so it's npm run dev so i think maybe ricardo you can uh tell us a bit about um when do we so i from what i understood is initially we did learn a bootstrap then we did npm run build and pm run start for the first time so unless we add a new package like i know moment. js or something um we don't need to do learner bootstrap voice or unless you're changing branches um you only have to do that once and after that you can when do we have to do npm run build like if there's any changes yes just the first time because yeah i mean mpa bill is just transpiling the code but when you do npm and run dev your npm run death is watching all the files and every time a safe is made then it change transpile all those files automatically we have to sadly restart the server so the ui notes that you know there were some changes on the on the notes but everything you change on the execute function it's okay you do not have to kill the process and run it again but everything you change on the ui i mean everything that is under properties then you have to run npm brown death again got it um hope that answers your question chris um we're gonna stay online for maybe uh two more minutes ricardo in case there's any more questions and um yeah okay chris says he gets it um perfect and uh yeah next week we'll have this guide coming on so i think we'll announce that on twitter i think so we have that in the docs we also have a reference for different data types so if there's a string um if there's a you know you need to use date time maybe something like a fixed collection and you don't quite yet know like what are the different types we'll have a reference so you can see okay it looks like this and i want that in my notes so you can copy the code there and explore a bit more that was good awesome thanks chris for joining and uh thank you everybody for tuning in this was really fun and yeah i hope this was uh helpful and uh thanks a lot ricardo for showing us how to create notes um of course we hope to be building more of these based on this and yeah it was a lot of fun thanks a lot i really enjoyed we have some technical difficulties at the beginning but in general i really enjoyed yeah so looking it would be weird if there would be no technical difficulties like that those all just pop up on live streams it's gonna happen okay all right thank you everyone this was a lot of fun and hope to do this soon again and uh have a nice evening or have a nice day wherever you are okay good bye

Другие видео автора — n8n

Ctrl+V

Экстракт Знаний в Telegram

Экстракты и дистилляты из лучших YouTube-каналов — сразу после публикации.

Подписаться

Дайджест Экстрактов

Лучшие методички за неделю — каждый понедельник