[{"data":1,"prerenderedAt":432},["ShallowReactive",2],{"footer-primary":3,"footer-secondary":93,"footer-description":119,"quick-connect-openai":121,"quick-connect-openai-next":165,"sales-reps":180},{"items":4},[5,29,49,69],{"id":6,"title":7,"url":8,"page":8,"children":9},"522e608a-77b0-4333-820d-d4f44be2ade1","Solutions",null,[10,15,20,25],{"id":11,"title":12,"url":8,"page":13},"fcafe85a-a798-4710-9e7a-776fe413aae5","Headless CMS",{"permalink":14},"/solutions/headless-cms",{"id":16,"title":17,"url":8,"page":18},"79972923-93cf-4777-9e32-5c9b0315fc10","Backend-as-a-Service",{"permalink":19},"/solutions/backend-as-a-service",{"id":21,"title":22,"url":8,"page":23},"0fa8d0c1-7b64-4f6f-939d-d7fdb99fc407","Product Information",{"permalink":24},"/solutions/product-information-management",{"id":26,"title":27,"url":28,"page":8},"63946d54-6052-4780-8ff4-91f5a9931dcc","100+ Things to Build","https://directus.io/blog/100-tools-apps-and-platforms-you-can-build-with-directus",{"id":30,"title":31,"url":8,"page":8,"children":32},"8ab4f9b1-f3e2-44d6-919b-011d91fe072f","Resources",[33,37,41,45],{"id":34,"title":35,"url":36,"page":8},"f951fb84-8777-4b84-9e91-996fe9d25483","Documentation","https://docs.directus.io",{"id":38,"title":39,"url":40,"page":8},"366febc7-a538-4c08-a326-e6204957f1e3","Guides","https://docs.directus.io/guides/",{"id":42,"title":43,"url":44,"page":8},"aeb9128e-1c5f-417f-863c-2449416433cd","Community","https://directus.chat",{"id":46,"title":47,"url":48,"page":8},"da1c2ed8-0a77-49b0-a903-49c56cb07de5","Release Notes","https://github.com/directus/directus/releases",{"id":50,"title":51,"url":8,"page":8,"children":52},"d61fae8c-7502-494a-822f-19ecff3d0256","Support",[53,57,61,65],{"id":54,"title":55,"url":56,"page":8},"8c43c781-7ebd-475f-a931-747e293c0a88","Issue Tracker","https://github.com/directus/directus/issues",{"id":58,"title":59,"url":60,"page":8},"d77bb78e-cf7b-4e01-932a-514414ba49d3","Feature Requests","https://github.com/directus/directus/discussions?discussions_q=is:open+sort:top",{"id":62,"title":63,"url":64,"page":8},"4346be2b-2c53-476e-b53b-becacec626a6","Community Chat","https://discord.com/channels/725371605378924594/741317677397704757",{"id":66,"title":67,"url":68,"page":8},"26c115d2-49f7-4edc-935e-d37d427fb89d","Cloud Dashboard","https://directus.cloud",{"id":70,"title":71,"url":8,"page":8,"children":72},"49141403-4f20-44ac-8453-25ace1265812","Organization",[73,78,84,88],{"id":74,"title":75,"url":76,"page":77},"1f36ea92-8a5e-47c8-914c-9822a8b9538a","About","/about",{"permalink":76},{"id":79,"title":80,"url":81,"page":82},"b84bf525-5471-4b14-a93c-225f6c386005","Careers","#",{"permalink":83},"/careers",{"id":85,"title":86,"url":87,"page":8},"86aabc3a-433d-434b-9efa-ad1d34be0a34","Brand Assets","https://drive.google.com/drive/folders/1lBOTba4RaA5ikqOn8Ewo4RYzD0XcymG9?usp=sharing",{"id":89,"title":90,"url":8,"page":91},"8d2fa1e3-198e-4405-81e1-2ceb858bc237","Contact",{"permalink":92},"/contact",{"items":94},[95,101,107,113],{"id":96,"title":97,"url":8,"page":98,"children":100},"8a1b7bfa-429d-4ffc-a650-2a5fdcf356da","Cloud Policies",{"permalink":99},"/cloud-policies",[],{"id":102,"title":103,"url":81,"page":104,"children":106},"bea848ef-828f-4306-8017-6b00ec5d4a0c","License",{"permalink":105},"/bsl",[],{"id":108,"title":109,"url":81,"page":110,"children":112},"4e914f47-4bee-42b7-b445-3119ee4196ef","Terms",{"permalink":111},"/terms",[],{"id":114,"title":115,"url":81,"page":116,"children":118},"ea69eda6-d317-4981-8421-fcabb1826bfd","Privacy",{"permalink":117},"/privacy",[],{"description":120},"\u003Cp>A composable backend to build your Headless CMS, BaaS, and more.&nbsp;\u003C/p>",{"id":122,"slug":123,"vimeo_id":124,"description":125,"tile":126,"length":127,"resources":8,"people":128,"episode_number":132,"published":133,"title":134,"video_transcript_html":135,"video_transcript_text":136,"content":8,"status":137,"episode_people":138,"recommendations":149,"season":150,"seo":8},"81417d25-26d2-4f05-be37-7ced51a0594e","openai","899796860","Use OpenAI's APIs to generate images with DALL·E and social posts with GPT-4.","b3d3b5a4-2946-4c72-bf88-e8bc933bd7c0",11,[129],{"name":130,"url":131},"Kevin Lewis","https://directus.io/team/kevin-lewis",4,"2024-01-19","Generate Images and Social Posts with OpenAI","\u003Cp>Speaker 0: Chances are you've heard of OpenAI. They're the company behind ChatGPT. Now today in QuickConnect, we're going to integrate with OpenAI's APIs to use both their GPT 4 model and their DALL E image generation model to enrich data in our director's project. Here, I've got a set of articles, a set of recipes, and we'll be using OpenAI to write a social post for us to promote this article and to generate an image which we can then use, on the web page or in social posts. On the OpenAI side, all we're gonna need is an API key.\u003C/p>\u003Cp>Send over to your dashboard, create a secret key, take note of it somewhere. We'll use it later. And then we're ready to go over into directors and set things up there. So over in our directors project, let's create a new flow. Let's call this one generate social post, and we will use a manual trigger on the article's collection on the item page.\u003C/p>\u003Cp>So this is our trigger. I wanna show you something interesting about this. So if we go over and refresh our item, we now see we can generate a social post here. Going back over to the flow and refreshing it and taking a look at the logs, we see here that we only get the ID of the article, and we actually wanna use the title of the article. So the first thing we need to do is create an operation called article, and we're gonna read that whole the whole article object.\u003C/p>\u003Cp>So we'll be going into the articles collection with full access, and we will want the trigger dot Bobby dot keys 0. So that is inside of that object where the ID for this item is. So now article will return the entire object. Now it's time to go and actually go to open AI and get it to generate a post for us. So we'll create a new operation.\u003C/p>\u003Cp>I'll call it generate. And we'll make a web request. This will be a post request to their chat completions endpoint. Now we need to authenticate ourselves with our API key. We'll do that with a header.\u003C/p>\u003Cp>Authorization bearer space, and then our API key, and then our request body. Now it's a little bit of a big object, so I'm gonna copy and paste a starting point to discuss here. We'll be using the GPT 4 model, and there are 2 messages we're gonna send in an array. The first is a primer for the system to tell it what we expect of it. So we're telling it here.\u003C/p>\u003Cp>They're an editor of a food blog. They take in recipes. They spit out social posts and the audience is busy professionals with little time. And, of course, you can tweak this for your specific use case. And then we get to write our actual prompt itself.\u003C/p>\u003Cp>So I'll say write a Twitter post for our article dot title recipe. So this is a dynamic value that is returned out of this object here let's hit save let's hit save again and let's rerun this flow notice it takes a little bit longer to run this time that's because it's actually going off to open ai and back So if we refresh here, we'll see a new log appears. And we'll see the returned value contains a data object with an array called choices. And inside of this object is a message and content. And that is a viable social post, or at least a starting point something to help us out.\u003C/p>\u003Cp>So the last thing we want to do here is actually save that social post back to the item. So we will add one final operation here. We will update data. We will update an article using that same key from earlier. So, trigger dot Bobby dot keys 0, I believe is what it was.\u003C/p>\u003Cp>And the payload we want to send is going to be social. That's the name of the field. And the value, it's quite nested. I did take note of where it was earlier, though. Generate because that's the name of the operation that returns this value.\u003C/p>\u003Cp>Generate dot data dot choices, that was an array, dot message dot content so let's save that let's refresh here and let's just try this one more time So lemon herb roasted chicken. We will hit generate social post. We'll wait just a moment, and we should see over there in the social box, our social post has been created. So that's the first half of what we're doing today. This is a double whammy.\u003C/p>\u003Cp>So now we're gonna create a new flow to generate an image. So now let's create a second flow for the image generation. I'll call this 1 generate image. It will be a manual flow trigger again on articles on the item page, except this time, we're going to ask the user for an image prompt. So we will require a confirmation which will pop up a model you'll see in a moment.\u003C/p>\u003Cp>So I'll call this confirm, and we can provide any number of keys. We just want one prompt. Of course, you might choose to make this a little more descriptive to users, but we're just gonna add an input with the value well, with the name of prompt. So what we're gonna do actually, once again, let's see how this works. So let's go back to our item.\u003C/p>\u003Cp>Let's refresh. And inside of flows, there's now 2. Here's generate image, and here's our prompt. So I will call this lemon herb roasted chicken in a baking dish, and I'm sure you could create something a little more creative. Let's run the flow.\u003C/p>\u003Cp>Let's refresh our flow and take a look at where that prompt has gone. And just like before, inside of our body, we have an array of keys. So that's the ID of the article, but we also have this prompt here. So we're gonna use that and immediately go off to DALL E, the image generation endpoint, and we will, and we'll generate an image using that prompt. So we'll call this one generate.\u003C/p>\u003Cp>We'll make a web request again. It will be a post request to this URL. Once again, we need to validate ourselves, so we will add the same header as before, authorization bearer space token, and then we have the request body. This is what the request body looks like. We pass in the prompt.\u003C/p>\u003Cp>We specify the size from 1 of the provided allowed sizes. With DALL E 3 at the moment, you can only generate 1 variation at a time. But if you use other DALL E models, you might be able to generate multiple. We'll just use 1, and that's the name of the model. So let's hit save once again, and we will rerun this flow.\u003C/p>\u003Cp>We see that's taking a little longer because now it's actually going off and generating an image for us we'll wait for that to be complete here We'll go back to the flow. We'll refresh to look at the new log, and we'll see here that in the data that is returned is an array called data with a revised prompt and a URL. Now we want to import this image via URL into our directors project. Now flows don't provide a way to do that out of the box. So I'm actually using this lovely community, community extension, which does allow us to import images from external URLs.\u003C/p>\u003Cp>So I will link this along with the video, but I've already gone ahead and made that extension available in this director's project. So let's add a new operation here. We will use this file import. I think I'll call this one import, and we provide the URL. So that came from the step that we could generate dot data dot data and dot URL like so And what file import will do is return just a string, and the string is the ID of the newly imported file in Directus.\u003C/p>\u003Cp>So instead of demoing it at this point, we're just gonna go ahead straight away and include that image inside of our post. So update data once again, very similar to before, articles, full access. The ID again will be trigger dot Bobby dot keys 0, and the payload will be image, and we just want that value there. So import because it doesn't return an object. It just returns a string.\u003C/p>\u003Cp>So let's hit save, and that should be everything we need. So we have lemon herb roasted chicken here. So let's go ahead and generate the image. Let me get my prompt back. We'll run flow on the current item.\u003C/p>\u003Cp>We'll give that a few moments to complete. It should go off, generate the image, import it to direct us, and then update this item with that newly imported file. So let's see if that works. There we go. Fantastic.\u003C/p>\u003Cp>Hurrah. So in this episode of QuickConnect a little bit longer, we've done 2 things with the open API the open AI APIs. We have created a flow which on demand can create a social post. And the nice thing is if you don't like it or you don't like the image, you can just press the buttons again, and it will go ahead and regenerate them. And the second one generates an image with the DALL E, model.\u003C/p>\u003Cp>It imports it into Directus using that extension and then includes it here inside of the item. I hope you found this super interesting. I had a lot of fun putting this one together, and go forth and have fun. See you next time.\u003C/p>","Chances are you've heard of OpenAI. They're the company behind ChatGPT. Now today in QuickConnect, we're going to integrate with OpenAI's APIs to use both their GPT 4 model and their DALL E image generation model to enrich data in our director's project. Here, I've got a set of articles, a set of recipes, and we'll be using OpenAI to write a social post for us to promote this article and to generate an image which we can then use, on the web page or in social posts. On the OpenAI side, all we're gonna need is an API key. Send over to your dashboard, create a secret key, take note of it somewhere. We'll use it later. And then we're ready to go over into directors and set things up there. So over in our directors project, let's create a new flow. Let's call this one generate social post, and we will use a manual trigger on the article's collection on the item page. So this is our trigger. I wanna show you something interesting about this. So if we go over and refresh our item, we now see we can generate a social post here. Going back over to the flow and refreshing it and taking a look at the logs, we see here that we only get the ID of the article, and we actually wanna use the title of the article. So the first thing we need to do is create an operation called article, and we're gonna read that whole the whole article object. So we'll be going into the articles collection with full access, and we will want the trigger dot Bobby dot keys 0. So that is inside of that object where the ID for this item is. So now article will return the entire object. Now it's time to go and actually go to open AI and get it to generate a post for us. So we'll create a new operation. I'll call it generate. And we'll make a web request. This will be a post request to their chat completions endpoint. Now we need to authenticate ourselves with our API key. We'll do that with a header. Authorization bearer space, and then our API key, and then our request body. Now it's a little bit of a big object, so I'm gonna copy and paste a starting point to discuss here. We'll be using the GPT 4 model, and there are 2 messages we're gonna send in an array. The first is a primer for the system to tell it what we expect of it. So we're telling it here. They're an editor of a food blog. They take in recipes. They spit out social posts and the audience is busy professionals with little time. And, of course, you can tweak this for your specific use case. And then we get to write our actual prompt itself. So I'll say write a Twitter post for our article dot title recipe. So this is a dynamic value that is returned out of this object here let's hit save let's hit save again and let's rerun this flow notice it takes a little bit longer to run this time that's because it's actually going off to open ai and back So if we refresh here, we'll see a new log appears. And we'll see the returned value contains a data object with an array called choices. And inside of this object is a message and content. And that is a viable social post, or at least a starting point something to help us out. So the last thing we want to do here is actually save that social post back to the item. So we will add one final operation here. We will update data. We will update an article using that same key from earlier. So, trigger dot Bobby dot keys 0, I believe is what it was. And the payload we want to send is going to be social. That's the name of the field. And the value, it's quite nested. I did take note of where it was earlier, though. Generate because that's the name of the operation that returns this value. Generate dot data dot choices, that was an array, dot message dot content so let's save that let's refresh here and let's just try this one more time So lemon herb roasted chicken. We will hit generate social post. We'll wait just a moment, and we should see over there in the social box, our social post has been created. So that's the first half of what we're doing today. This is a double whammy. So now we're gonna create a new flow to generate an image. So now let's create a second flow for the image generation. I'll call this 1 generate image. It will be a manual flow trigger again on articles on the item page, except this time, we're going to ask the user for an image prompt. So we will require a confirmation which will pop up a model you'll see in a moment. So I'll call this confirm, and we can provide any number of keys. We just want one prompt. Of course, you might choose to make this a little more descriptive to users, but we're just gonna add an input with the value well, with the name of prompt. So what we're gonna do actually, once again, let's see how this works. So let's go back to our item. Let's refresh. And inside of flows, there's now 2. Here's generate image, and here's our prompt. So I will call this lemon herb roasted chicken in a baking dish, and I'm sure you could create something a little more creative. Let's run the flow. Let's refresh our flow and take a look at where that prompt has gone. And just like before, inside of our body, we have an array of keys. So that's the ID of the article, but we also have this prompt here. So we're gonna use that and immediately go off to DALL E, the image generation endpoint, and we will, and we'll generate an image using that prompt. So we'll call this one generate. We'll make a web request again. It will be a post request to this URL. Once again, we need to validate ourselves, so we will add the same header as before, authorization bearer space token, and then we have the request body. This is what the request body looks like. We pass in the prompt. We specify the size from 1 of the provided allowed sizes. With DALL E 3 at the moment, you can only generate 1 variation at a time. But if you use other DALL E models, you might be able to generate multiple. We'll just use 1, and that's the name of the model. So let's hit save once again, and we will rerun this flow. We see that's taking a little longer because now it's actually going off and generating an image for us we'll wait for that to be complete here We'll go back to the flow. We'll refresh to look at the new log, and we'll see here that in the data that is returned is an array called data with a revised prompt and a URL. Now we want to import this image via URL into our directors project. Now flows don't provide a way to do that out of the box. So I'm actually using this lovely community, community extension, which does allow us to import images from external URLs. So I will link this along with the video, but I've already gone ahead and made that extension available in this director's project. So let's add a new operation here. We will use this file import. I think I'll call this one import, and we provide the URL. So that came from the step that we could generate dot data dot data and dot URL like so And what file import will do is return just a string, and the string is the ID of the newly imported file in Directus. So instead of demoing it at this point, we're just gonna go ahead straight away and include that image inside of our post. So update data once again, very similar to before, articles, full access. The ID again will be trigger dot Bobby dot keys 0, and the payload will be image, and we just want that value there. So import because it doesn't return an object. It just returns a string. So let's hit save, and that should be everything we need. So we have lemon herb roasted chicken here. So let's go ahead and generate the image. Let me get my prompt back. We'll run flow on the current item. We'll give that a few moments to complete. It should go off, generate the image, import it to direct us, and then update this item with that newly imported file. So let's see if that works. There we go. Fantastic. Hurrah. So in this episode of QuickConnect a little bit longer, we've done 2 things with the open API the open AI APIs. We have created a flow which on demand can create a social post. And the nice thing is if you don't like it or you don't like the image, you can just press the buttons again, and it will go ahead and regenerate them. And the second one generates an image with the DALL E, model. It imports it into Directus using that extension and then includes it here inside of the item. I hope you found this super interesting. I had a lot of fun putting this one together, and go forth and have fun. See you next time.","published",[139],{"people_id":140},{"id":141,"first_name":142,"last_name":143,"avatar":144,"bio":145,"links":146},"82b3f7e5-637b-4890-93b2-378b497d5dc6","Kevin","Lewis","a662f91b-1ee9-4277-8c9d-3ac1878e44ad","Director of Developer Experience at Directus",[147],{"url":131,"service":148},"website",[],{"id":151,"number":152,"year":153,"episodes":154,"show":162},"3b8b7d34-a0fb-4ea6-85ff-2b5bfbb8e0b6",1,"2023",[155,156,157,122,158,159,160,161],"502dcf7e-c23e-4dfd-b147-65f5abaea5c7","a230c9ef-8db4-4c00-a0cb-9524f7934eb0","5f41dc16-29b7-485f-a6e1-081c3f1acc4f","8f933ee9-4e4f-4e35-8c1f-e99ad0684bfa","71e081db-92f8-4978-b020-7d2460a46187","8e47020d-bd5a-43a7-bca9-54af4f5d465d","bfb8bc25-ef1b-4544-b50d-402008c638a1",{"title":163,"tile":164},"Quick Connect","1171b046-491e-4cfb-a68c-527b89c2c348",{"id":166,"slug":167,"season":168,"vimeo_id":169,"description":170,"tile":171,"length":172,"resources":8,"people":8,"episode_number":152,"published":173,"title":170,"video_transcript_html":174,"video_transcript_text":175,"content":8,"seo":176,"status":137,"episode_people":177,"recommendations":179},"979db4da-a870-4120-94ee-bd80789f411c","firecrawl","cf7a056d-fa10-4bc5-8cc3-c2b9ef59b684","1026203173","Integrating Firecrawl with Directus","d0a87153-8475-433f-aca0-dea9802caf03",10,"2024-10-16","\u003Cp>Speaker 0: Hello there. I'm really excited about this tutorial. So on Directus TV, we already have a show called Quick Connect, which shows you how to integrate third party services with Directus using Directus Automate and Flows. And in the spirit of that show, today, I'm gonna show you how to integrate FireCrawl with Directus. Now here they say that they turn websites into LLM ready data.\u003C/p>\u003Cp>And what that means in practice is you can feed it a URL, provide some options if you want, and it will go and take a look at that web page and return some structured data for you like so. This is their scrape endpoint, which will take a single web page and scrape some data from it. They also have a couple of other endpoints, crawl and map, but today, we're gonna use scrape. Now I've already logged into FireCrawl Cloud and generated an API key, which I'll copy for later. You can also self host FireCrawl, but for ease, I'm just gonna use their cloud product here.\u003C/p>\u003Cp>Now I have this directors project over here with a new empty collection called companies. In this collection, there are a few fields. URL, a name, a description, mission, and a boolean, a true force value, is it open source. And our goal will be to provide the URL and then have FireCrawl automatically populate the rest with flows. So let's go ahead and create a new flow.\u003C/p>\u003Cp>So this is our automation builder if you've not seen it before. I'll call this one get company data, I guess. And we are going to use a manual trigger, which will add a button to the side of collection and item pages. So we're going to say we'll run this on the company's collection. What else matters here?\u003C/p>\u003Cp>We're going to, not require selection, so the button always works. And we're going to require confirmation, which will pop up a modal. And in that modal, we will just add a URL. We'll make it a string input, and we'll make it full widths. And I think that's all we need to do here.\u003C/p>\u003Cp>So just to see what happens here, if I go back to the, to the company's collection, we now see this button here, this manual flow, trigger. I click that. It pulls up the box, and we'll put in a URL and hit run flow. So now if we go back to our flow, we should immediately see that there is one log. And in here, there is a body, and the URL is the value that we typed.\u003C/p>\u003Cp>Fantastic. Now we need to actually do something with it. So, let's go ahead and add a new operation here. And, honestly, fire crawl is pretty sick. You can just make one web request.\u003C/p>\u003Cp>Let's take a look at their docs. We're gonna use the LLM extract, endpoint here, and let's just take a look at the kind of construction of this API call. It's a post request to this URL. We're gonna pass in our, our API key here as an authorization header, and then they give us this kind of JSON payload here. Here, it's telling it to go ahead and extract specifically these four fields, the company mission, does it support SSO, is it open source, and is it in Y Combinator?\u003C/p>\u003Cp>And it's saying you must go get all four of these. So let's actually just turn this straight into a flow request, request URL, operation. So we're gonna do a post request to this URL, post request to this URL. I'm gonna go and copy my API key again here, and at the end of this I'll, I'll destroy the key. Authorization authorization, bearer API key, save, And then there's the request body.\u003C/p>\u003Cp>And, honestly, it contains a little more than we need, but this contains everything we need. So we'll just pop that in there. The only thing we wanna do, of course, is pass in the URL that we put in the box. So we'll replace this with trigger.body. URL.\u003C/p>\u003Cp>Fantastic. Let's save that and see what happens if we go over to content, press the button, and type in directors.io. We see that's running. That's running. That's a good sign.\u003C/p>\u003Cp>It means it's going off and making the request, waiting for the request. And then we see there is a second log. And we get some data back. There was a 200, so it was successful. Inside of data, there is a property called data, and then there is this value called extract.\u003C/p>\u003Cp>Extract contains all of those custom keys we asked for, company mission, supports SSO, is open source, and is in YC. And then always when you scrape, you get this metadata object, title, description, language, Open Graph data, source URL, and so on. So, really, all we wanna do here now is we wanna take this data and create a new company from it. So let's add a new, let's create a new operation on the resolve path of that web request. Let's call it create data.\u003C/p>\u003Cp>We're gonna create something in the company's collection. We'll give it full access, and then we just need to provide a payload. So let's go ahead and do that. We have an object here. We have a name.\u003C/p>\u003Cp>Oh, we have a name, and we're gonna pass in the value of the last operation dot data.data.metadata dot title. Then I, for one, am I'm just gonna copy this and edit it each time. So we have name, URL. So that's last .data.data.metadata. Source URL.\u003C/p>\u003Cp>We could, of course, just take it from the trigger body URL, but this is properly formatted. You'll notice I typed in directus dot I o, but when it came back in the payload, it came back with the with the, with the protocol HTTPS and so on. So we have name. We have URL. We have a description.\u003C/p>\u003Cp>Now this one is also from the metadata description. We have the mission. Now this was a custom piece of data we asked to be extracted. Company mission is what we called it. And finally, we have open, open underscore source.\u003C/p>\u003Cp>Last data, data extract and then is underscore open underscore source and then remove that trailing comma. So I believe that's the name of all of the fields. We'll figure it out in a moment when when it inevitably doesn't work. We'll hit the button again, directors.io, and hit run flow. Once again, that's going off to fire crawl using their endpoint and there we see there we see it straight here.\u003C/p>\u003Cp>URL name, description, mission, and the boolean is open source. Let's, let's try that once more. Let's go in here and say firefirecrawl.devrun flow. So let's see. And in theory, we should just give that a moment, and there it is.\u003C/p>\u003Cp>So now you can go ahead and grab more data. Now, of course, if we take a look at this endpoint here, you can provide custom properties, and it will try its best to get data out from that. They have a couple of other interesting things which I'll draw your attention to even if I don't think it works in this context. They have extracting without a schema. So this extract here was us creating a a schema.\u003C/p>\u003Cp>Right? You can give it just a text. You can give it a prompt. Extract the company mission from the page. But the thing I don't like about that is you're not explicitly saying what the name of the key is, so you don't necessarily know what it's gonna be at the end.\u003C/p>\u003Cp>I like creating a schema personally. They do something else that's kinda interesting. If I take a look at where is I think it's in their API API reference here inside of scrape. They have this interesting thing called actions. So you can get it to wait, to take a screenshot, to click, write text, press a key, and scroll.\u003C/p>\u003Cp>And the combination of clicking and writing text means you can get it to interact with your web page. You see it here, actions, wait two milliseconds. You could get it to, like, sign into things perhaps, perform search terms. I think it's super interesting. And then take screenshots, of course, and upload those to directors if you fancy.\u003C/p>\u003Cp>So there's a lot of flexibility in this. Having seen kinda how easy this API is, I think I'll go ahead and turn this into, an extension some point in the next few weeks, which we can release as part of Directus AI. But, yeah, that's how to integrate FireCrawl with Directus using Directus Automate. Hope you found this interesting, and by all means, if you have questions, just reach out.\u003C/p>","Hello there. I'm really excited about this tutorial. So on Directus TV, we already have a show called Quick Connect, which shows you how to integrate third party services with Directus using Directus Automate and Flows. And in the spirit of that show, today, I'm gonna show you how to integrate FireCrawl with Directus. Now here they say that they turn websites into LLM ready data. And what that means in practice is you can feed it a URL, provide some options if you want, and it will go and take a look at that web page and return some structured data for you like so. This is their scrape endpoint, which will take a single web page and scrape some data from it. They also have a couple of other endpoints, crawl and map, but today, we're gonna use scrape. Now I've already logged into FireCrawl Cloud and generated an API key, which I'll copy for later. You can also self host FireCrawl, but for ease, I'm just gonna use their cloud product here. Now I have this directors project over here with a new empty collection called companies. In this collection, there are a few fields. URL, a name, a description, mission, and a boolean, a true force value, is it open source. And our goal will be to provide the URL and then have FireCrawl automatically populate the rest with flows. So let's go ahead and create a new flow. So this is our automation builder if you've not seen it before. I'll call this one get company data, I guess. And we are going to use a manual trigger, which will add a button to the side of collection and item pages. So we're going to say we'll run this on the company's collection. What else matters here? We're going to, not require selection, so the button always works. And we're going to require confirmation, which will pop up a modal. And in that modal, we will just add a URL. We'll make it a string input, and we'll make it full widths. And I think that's all we need to do here. So just to see what happens here, if I go back to the, to the company's collection, we now see this button here, this manual flow, trigger. I click that. It pulls up the box, and we'll put in a URL and hit run flow. So now if we go back to our flow, we should immediately see that there is one log. And in here, there is a body, and the URL is the value that we typed. Fantastic. Now we need to actually do something with it. So, let's go ahead and add a new operation here. And, honestly, fire crawl is pretty sick. You can just make one web request. Let's take a look at their docs. We're gonna use the LLM extract, endpoint here, and let's just take a look at the kind of construction of this API call. It's a post request to this URL. We're gonna pass in our, our API key here as an authorization header, and then they give us this kind of JSON payload here. Here, it's telling it to go ahead and extract specifically these four fields, the company mission, does it support SSO, is it open source, and is it in Y Combinator? And it's saying you must go get all four of these. So let's actually just turn this straight into a flow request, request URL, operation. So we're gonna do a post request to this URL, post request to this URL. I'm gonna go and copy my API key again here, and at the end of this I'll, I'll destroy the key. Authorization authorization, bearer API key, save, And then there's the request body. And, honestly, it contains a little more than we need, but this contains everything we need. So we'll just pop that in there. The only thing we wanna do, of course, is pass in the URL that we put in the box. So we'll replace this with trigger.body. URL. Fantastic. Let's save that and see what happens if we go over to content, press the button, and type in directors.io. We see that's running. That's running. That's a good sign. It means it's going off and making the request, waiting for the request. And then we see there is a second log. And we get some data back. There was a 200, so it was successful. Inside of data, there is a property called data, and then there is this value called extract. Extract contains all of those custom keys we asked for, company mission, supports SSO, is open source, and is in YC. And then always when you scrape, you get this metadata object, title, description, language, Open Graph data, source URL, and so on. So, really, all we wanna do here now is we wanna take this data and create a new company from it. So let's add a new, let's create a new operation on the resolve path of that web request. Let's call it create data. We're gonna create something in the company's collection. We'll give it full access, and then we just need to provide a payload. So let's go ahead and do that. We have an object here. We have a name. Oh, we have a name, and we're gonna pass in the value of the last operation dot data.data.metadata dot title. Then I, for one, am I'm just gonna copy this and edit it each time. So we have name, URL. So that's last .data.data.metadata. Source URL. We could, of course, just take it from the trigger body URL, but this is properly formatted. You'll notice I typed in directus dot I o, but when it came back in the payload, it came back with the with the, with the protocol HTTPS and so on. So we have name. We have URL. We have a description. Now this one is also from the metadata description. We have the mission. Now this was a custom piece of data we asked to be extracted. Company mission is what we called it. And finally, we have open, open underscore source. Last data, data extract and then is underscore open underscore source and then remove that trailing comma. So I believe that's the name of all of the fields. We'll figure it out in a moment when when it inevitably doesn't work. We'll hit the button again, directors.io, and hit run flow. Once again, that's going off to fire crawl using their endpoint and there we see there we see it straight here. URL name, description, mission, and the boolean is open source. Let's, let's try that once more. Let's go in here and say firefirecrawl.devrun flow. So let's see. And in theory, we should just give that a moment, and there it is. So now you can go ahead and grab more data. Now, of course, if we take a look at this endpoint here, you can provide custom properties, and it will try its best to get data out from that. They have a couple of other interesting things which I'll draw your attention to even if I don't think it works in this context. They have extracting without a schema. So this extract here was us creating a a schema. Right? You can give it just a text. You can give it a prompt. Extract the company mission from the page. But the thing I don't like about that is you're not explicitly saying what the name of the key is, so you don't necessarily know what it's gonna be at the end. I like creating a schema personally. They do something else that's kinda interesting. If I take a look at where is I think it's in their API API reference here inside of scrape. They have this interesting thing called actions. So you can get it to wait, to take a screenshot, to click, write text, press a key, and scroll. And the combination of clicking and writing text means you can get it to interact with your web page. You see it here, actions, wait two milliseconds. You could get it to, like, sign into things perhaps, perform search terms. I think it's super interesting. And then take screenshots, of course, and upload those to directors if you fancy. So there's a lot of flexibility in this. Having seen kinda how easy this API is, I think I'll go ahead and turn this into, an extension some point in the next few weeks, which we can release as part of Directus AI. But, yeah, that's how to integrate FireCrawl with Directus using Directus Automate. Hope you found this interesting, and by all means, if you have questions, just reach out.","9c575c49-4fb1-4eed-9731-e1e1acb55da3",[178],"4830ae03-22cd-4399-82f2-5767bf5cf0cc",[],{"reps":181},[182,238],{"name":183,"sdr":8,"link":184,"countries":185,"states":187},"John Daniels","https://meet.directus.io/meetings/john2144/john-contact-form-meeting",[186],"United States",[188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237],"Michigan","Indiana","Ohio","West Virginia","Kentucky","Virginia","Tennessee","North Carolina","South Carolina","Georgia","Florida","Alabama","Mississippi","New York","MI","IN","OH","WV","KY","VA","TN","NC","SC","GA","FL","AL","MS","NY","Connecticut","CT","Delaware","DE","Maine","ME","Maryland","MD","Massachusetts","MA","New Hampshire","NH","New Jersey","NJ","Pennsylvania","PA","Rhode Island","RI","Vermont","VT","Washington DC","DC",{"name":239,"link":240,"countries":241},"Michelle Riber","https://meetings.hubspot.com/mriber",[242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,219,430,431],"Albania","ALB","Algeria","DZA","Andorra","AND","Angola","AGO","Austria","AUT","Belgium","BEL","Benin","BEN","Bosnia and Herzegovina","BIH","Botswana","BWA","Bulgaria","BGR","Burkina Faso","BFA","Burundi","BDI","Cameroon","CMR","Cape Verde","CPV","Central African Republic","CAF","Chad","TCD","Comoros","COM","Côte d'Ivoire","CIV","Croatia","HRV","Czech Republic","CZE","Democratic Republic of Congo","COD","Denmark","DNK","Djibouti","DJI","Egypt","EGY","Equatorial Guinea","GNQ","Eritrea","ERI","Estonia","EST","Eswatini","SWZ","Ethiopia","ETH","Finland","FIN","France","FRA","Gabon","GAB","Gambia","GMB","Ghana","GHA","Greece","GRC","Guinea","GIN","Guinea-Bissau","GNB","Hungary","HUN","Iceland","ISL","Ireland","IRL","Italy","ITA","Kenya","KEN","Latvia","LVA","Lesotho","LSO","Liberia","LBR","Libya","LBY","Liechtenstein","LIE","Lithuania","LTU","Luxembourg","LUX","Madagascar","MDG","Malawi","MWI","Mali","MLI","Malta","MLT","Mauritania","MRT","Mauritius","MUS","Moldova","MDA","Monaco","MCO","Montenegro","MNE","Morocco","MAR","Mozambique","MOZ","Namibia","NAM","Niger","NER","Nigeria","NGA","North Macedonia","MKD","Norway","NOR","Poland","POL","Portugal","PRT","Republic of Congo","COG","Romania","ROU","Rwanda","RWA","San Marino","SMR","São Tomé and Príncipe","STP","Senegal","SEN","Serbia","SRB","Seychelles","SYC","Sierra Leone","SLE","Slovakia","SVK","Slovenia","SVN","Somalia","SOM","South Africa","ZAF","South Sudan","SSD","Spain","ESP","Sudan","SDN","Sweden","SWE","Tanzania","TZA","Togo","TGO","Tunisia","TUN","Uganda","UGA","United Kingdom","GBR","Vatican City","VAT","Zambia","ZMB","Zimbabwe","ZWE","UK","Germany","Netherlands","Switzerland","CH","NL",1773850437884]