Building a Talk ChatGPT App with React Native Expo, NestJS, Google Text-to-Speech, OpenAI and TS

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone welcome back to cod with Betto I'm super excited to bring you this very cool video and in which we are going to learn how to create a an application that is going to allows us to talk with chat GPT and as you can see here we have the demo so as soon as I start pressing this this red button we are going to start recording our voice or just speaking to the phone and the phone is going to recognize our voice and then we're going to send the this message to the vand so we're going to be creating as well a vand with nestjs uh it's going to be pretty fun now uh once we send this message to the vend CH GPT is going to reply but we are going to be using as well a Google Cloud API call speech sorry text to speech to convert the response from GPT to an MP3 file and then send that to the client so that we can uh play that record ing on the mobile application so let's see the demo all right I'm pressing and then I can start talking okay hi chbt can you just say hi to the audience and present yourself and yeah thank you so I released and then on the left side we can see in today's video you'll learn how to build an account that lets you converse with me chat GPT if you're new to the channel don't forget to subscribe and if you're looking to become a react native expert head over to code with v.d to check out our comprehensive react native course or our react with typescript course with a super discount including templates and free examples now let's dive into the demo all right so as you can see on the left side I have my terminal where I'm hosting my server nestjs application which it's a framework to build not J uh based applications for backend development so let's send another message um thanks for your kind introduction you're welcome I'm here to help and provide a great learning experience if you have any questions or need assistance with anything feel free to ask let's make this demo engaging and informative cool thank you um just as AO can you tell us who Steve Jobs was Steve Jobs West is not a known figure it is possible that you may be referring to either Steve Jobs the co-founder of Apple Inc or Kanye West the American rapper and fashion designer please provide more context or clarify your questions so that I can assist you accurately Steve Jobs Steve Jobs all right and this response is very L was an American bu industrial design I'm going to Rel so that we don't have to listen to all that uh but yeah so we have also this replay last message Steve Jobs was an American bus and if I press it as you can see it's going to play the message again okay so please tell us who was Steve Jobs in a short sentence Steve Jobs was the co-founder of Apple Inc and a Visionary leader in the technology industry all right thank you for your response you have been very helpful now let's start with this video all right you're welcome I'm glad I could assist you let's dive right into the video and start exploring how to build an app that allows us to converse with chat GPT if you have any questions or need any help throughout the video feel yeah so maybe we need to got a stop button here but as you can see this is working just fine on the background we are just sending the text to the vand and we are using a dependency to do that so to recognize the voice and then translate it to text and then send it to the backend and do you know the translation and then from text to speech and send that MP3 back to the user so this is what we're going to be building guys so if you like this video please make sure to subscribe if you haven't already and and give it a like and also guys as always this code is going to be available to you for free on at COD with. so if you go to code with. Dev projects you are going to find this to GPT project and then if you click here you're going to find dependencies videos and if you scroll all the way down you can see the links for GitHub and download it and yeah once you are here you can check out the react native course if you want to become a master in react native and if you want to support the channel check out the react native course and you're going to become a master this course is very complete and also I'm uh actively updating it with the latest uh release of Expo SDK and all the good stuff and also I'm currently working as well on this react with typescript course so if you want to become a master in react with drip uh go to cod. and check out this react with drip code course we we have a cool deal for you right now it's um just for early beards because this is a pre-sale but as soon as we finish this course is going to be a little more expensive so if you want to take advantage of this opportunity you can enroll now now that being said guys let's start with this video okay guys so before we actually jumped into the code I want to talk a little bit about the architecture that we're going to be doing for this application so this seems like a very simple application but it's a very complex application under the hood because we are going to be dealing with a server and also we're going to be communicating with uh apis providers like open AI for CH gbt and also Google text to speech and so let's see how this is going to be working for so we need a client side application right and here we have this device and which represents the application that we're going to be creating with react native right now for the server because we're we need to communicate with open Ai and Google text to speech and also if you want to add more complexity to this application it might be a good idea to have a server so that you don't need to handle everything on the client side and also when we are dealing with these apis that we need to pay as developers to use them it's uh it's very recommended that you handle this Logic on the server so that you don't you don't expose anything to the client that could be used against you so for example a client could abstract your API keys or something like that so you don't want that that's why we are going to create This Server now for the server we're going to be using next nest ja sorry and Nest it's a framework that allows us to build applications uh backend or server applications using not JS uh by default uses typescript so it's really nice and also uh it's a very popular framework that it's very scalable okay so with that in mind uh we're going to be communicating then to uh open Ai and Google so the way this is going to work is that we need to translate the voice of the user into text now we could use uh you know speech to text from Google to do that but it's going to be expensive for us thankfully the devices that nowadays the users uh have can handle this uh on the client site so we are going to be on react native we're going to be using a dependency to translate from speech to text and this is going to be working locally so we don't have to pay anyone and this Computing is going to be on the client side so we are going to get the text from this so once we have the text um let me just say here text once we have the text we can send this text to the server all right so we are going to be sending this text to the server and in the server we're going to be handling the conversation with GPT so we're going to say okay chat GPT here's a new message and this message is going to be sent to open AI of course we need to keep track of the conversation not just the the last message but the history of the conversation we're going to think we're going to keep things simple here I'm just going to be handling one conversation uh at the time so when I install my server it's going to be just dealing with one conversation to keep things simple but you can you know integrate a lot of stuff so once CH GPT responds to us we're going to get text right so we're going to have text at this point and with this text what we want to do is make another request in this case we're going to be using Google we're going to send the text here so I'm going to say text and then check uh sorry Google API is going to reply to the server with an MP3 file so let's say MP3 file basically it's going to be an audio for this text once we have this audio on the server we can send it back to the client and let me oops let me delete this we're going to send this MP3 file back to the client and once we have this on the client what we can do is just play This MP3 file which is going to be the latest message that we sent to CH GPT of course because I want to keep things simple I'm just going to be dealing with the last file of course we could expand the functionality of this of this application Maybe by adding a database and then also using something like S3 from AWS to store all the audios that we're going to be having for the user like the history but this is going to be very complex to to do in one video that's why I'm going to try to keep things simple but if you want to scale this application you I mean you can take this as a vase and then scale from here it's going to be fairly easy I mean depending on what kind of you know what kind of functionality you want to you want to have but yeah if you want to provide for example uh records of the conversations that the user has uh has created you can do so but in this case what I'm going to do instead of having a bucket like S3 or a database I'm just going to save the last reply on the client side so this message that we have here I'm going to save it locally so that we have the feature of Replay as you can see here here we have this button uh and we can replay the last message but as soon as we create this flow again we send another message to chat GPT to the server we get a response as soon as we get another file I'm going to replace the latest one or yeah so so the last one is going to be replaced for the latest one and yeah so this is what we're going to be doing we are going to need to create a server we're going to need to create a a front end application using react native and then using open Ai and Google DTS and yeah so basically this is what we're going to be doing guys I just wanted to make sure that we we are on the same page and we know what we're going to be doing in the role of each of each part of the code or each part of this um application so let's get started okay guys so let's start by creating the front end which is going to be the react native application I'm going to start by creating a new Expo project we're going to be using Expo so let's go ahead and now that I'm here on the desktop I'm going to run the command MPX create Expo app and I'm going to use typescript so I'm going to select template and then I just want the blank typescript without navigation so let's select this one and the name for this one is going to be tutorial GPT or talk GPT hit enter and now let's wait a little bit all right guys so the app is ready so let's go ahead and access this folder or I can just simply open this on Visual Studio code by saying code tutorial T GPT okay guys so here we have the react native application right as you can see here this is just normal stuff but in this case we have typescript support which is really nice uh so let's go ahead and run this application uh as you can see here we are using mpm but I don't really like to use mpm so what I'm going to do is just delete this package lock Json as well as a not modules and just run jarn basically we're going to be switching to jarn now we need to wait a little bit while we wait let's go to code with Betto and grab the dependencies that we need for this. GPT front end so as you can see here front end we're going to be using um react native voice which is a library that allows us to translate the voice of the user to text okay so this voice is going to do that and then we we're going to be using Expo AV this is going to allows us to play media media like videos and audio in this case so to play the MP3 file we're going to be using this Expo AV and then Expo file system file system is going to just allows us to save the last message uh MP3 file into the device so that when the user you know opens the application again it's going to have access to the last message that jpt sent it okay so now uh let's just copy this dependencies and then move this out of the way and paste it here right so let's wait a little bit until this is done all right and that's it so I'm going to be pre-building this application the reason for that is because uh I believe that this uh react native voice dependency is going to be using a native code so in order to in order for this to work on the simulator we need to make the build so to make the build let's run MPX npx Expo prebuild but I just want to prebuild this for iOS um so let's say platform iOS and if I hit enter they're going to be asking me for my bundle I'm just going to select the default hit enter this is going to start creating the native code for IOS as you can see here now we need to wait a little bit until this is done while we are creating this project what we can do is um select the the app. TSX and actually start working a little bit on the UI for this application so let's just um copy what we have here on the right side just going to delete this text and say that this is going to be to GPT of course this is going to be a very basic UI um we don't want to you know waste a lot of time just working on on the UI okay and and yeah so this is uh compiled as you can see here the folder it's created and now we can run this on the simulator by saying MPX export run iOS okay and I'm using the other port for this uh for this uh application so I'm just going to cancel and stop the other server okay I stopped the other server I'm going to run npx export run iOS this is going to create the build for this application on my my simulator okay so then I'm going to have another text here so here I'm going to change this text for you know press and hold this button to record like the instructions for the user to use this application uh and yeah so I'm going to add just style to this to this text here I'm going to say font size of 32 and then font we bolt and because I want some space between this and the text below I'm going to say margin bottom of 30 oops going to delete this okay so as you can see here on the right side um it's asking me if I want to open this application so I'm going to say open then let's add this margin bottom here all right okay and this is working just fine as you can see here U yeah so let's continue with this UI I'm going to create another text here and this text is just going to be your message because we want to show the message that the user is going to be sending right now for for the subtitle that we have here I'm going to create um a style well I can just copy a style that I have here so I'm going to add this style here equal to and it's going to be um this style right now now um this is not what I wanted let me change it super quickly okay all right so this is going to be the St for the the message and we can have maybe some spacing between this so what I'm going to do is change this container by adding a padding so that we have some space on the left and right and the background color is going to be white so I'm going to delete that one all right let's delete this status bar and also I'm going to create a button that is going to be in charge of uh replaying or playing the last um the last message so let's import this from react native and also I'm going to be using a pressable and this pressable is going to be the botton that the user is going to be pressing to record new messages so let's say that the title for this is going to be reply last message and whenever we press this we want to reply the last message but of course we don't have anything yet so what I'm going to do here is just try to work a little bit on the UI and then we can start adding the functionality let's create now the press all press all can have components inside like in this case it's going to be hold to speak uh so hit save and then we can add a style right so for this botton what I'm going to do is going to create a style super quickly here the style is going to look something like this now this border color is going to be changing depending if the user is pressing right so we need a variable to do that but for now let's delete this and just say light gray right and that's how it's going to look all right so this is looking looking good this is a pressable of course and whenever we press this uh we need to handle the recording of the audio all right so let's try to add this functionality and change this to be a light green when we are pressing so that the user has some feedback also let me just um let me just add a quick style to this by saying margin vertical of of 10 and maybe a little uh a little you know font size more like 17 for example okay so this is going to be the message so let's go ahead and create a variable here this is going to be call border color and set order color equal to react I'm just going to say use State and um this is going to be by default light gray so we can specify here that this is going to be just between light gray and um light green and if I hit save uh we should be able to now change between these two values so if we go back to this uh pressable and instead of having this hardcoded color I'm going to say border color okay and now it's gray and the pressible uh component has an on press in uh event here and what we can do here is set the Border color to in this case uh light green so when the user starts pressing uh we're going to set this to be green and when the user releases so on press out we went to basically do the same so I can just copy this and change this to be and if I uh put my autocomplete here you can see that we have these two values which is really nice because we specified that this is going to be a union type so light gray in this case and if I hit save now let's try this out whenever I press you can see that now this is green and um when I release it's going to be gray cool so this is working now uh what we can do I mean what we want to do here is actually start recognizing when we press in and whenever we press out we want to stop recognizing so how can we do that so for in in order to do that we're going to be using the audio library but of course this uh this library is a little a little I mean I I wouldn't say it's hard to use but it's going to have like a lot of code in order order to deal with all the cases that we that that we can have for example when the user starts recording um the result of the recording and stuff like that so to abstract a little bit of this logic I'm going to create a new folder and I'm going to create some hooks right so in this folder hooks I'm going to create a new file that is going to be in charge of uh dealing with this Library so I'm going to say use voice recognition. TSX and in here what I want to do is import some things from react but uh before I do that I want to import voice uh from and if you remember we have this um voice from react native voice all right so here we have this dependency now this is going to be a custom hook guys so also when we are importing this dependency we have a lot of methods that we can use as you can see here uh Speech end event and we can access these events so we can have full control of the speech so I just want to grab the error event in the case that we have an error and also results event so let's grab this results event and yeah so let's try to abstract this logic here I want to have a variable to hold the state of this recording so let's create an interface because we are using typescript and this is going to be my interface State and we are going to have some some things like for example when the user uh when we have recognized or what we have recognized so let's let's call this recognized and this is going to be a string then pitch string error so we are going to be handling everything here is going to be of type string end string as well started it's going to be string then results results is going to be an array of strings actually so results it's going to be an array of string like that we are also going to have partial results and these things um basically are like what we have at the end and partial results is going to be like what we understand because you know most of the time this is not going to be very accurate especially you know if the user doesn't speak English very well like me so we're going to have some partial results and then finally I'm going to add a variable so that we know when the user is recording I'm going to call this recording and this is going to be a Boolean so that we can keep track and update the UI accordingly depending if we are recording or not okay so this is going to be the interface this is how it looks now let's go ahead and create a custom hook down here so let's export const use voice recognition this is going to be a function now if you are not familiar with custom hooks basically when we say use at the beginning of a function in this case it means that this is going to be a hook and react is going to run this hook before everything else when we are using it so let's initialize the state going to say say state so this Hook is going to be in charge of handling the state of the voice right so let's use the hook user State and uh pass here the type now u in this case I want to have a initial state so we can simply just copy and paste this here uh just initializing these variables with empty values cool so this is how it's going to look now we can actually start adding the functions that come with um with this voice um with this voice Library here so let's go ahead and do that here the first one is going to be reset state I'm going to say reset State this is going to be very useful because um whenever we want to delete what we have recognize we need to call this function so let's use a call back here and this callback is going to set the state to whatever we had before so I can just copy this here and paste it here so this is basically just uh setting the state as it was before all right and use callback it's going to have a and use callback is going to have a dependency array as well and this is going to be depending on the set State now uh I think uh I have an error here I think this is before after yeah so after these Cur Braes we have this array of dependencies yeah and this is how it looks so this is going to reset the state so let's just copy this one and paste another function down here this function is going to be called start recognizing it's going to look like this and this callback is going to be asynchronous I'm going to delete this here what I want to do when I start recognizing it's going to be I think I'm missing something here okay so we have this reset state function I'm just going to copy this and paste it down here but I'm going to change the name in this case we want to create a function that is going to start recognizing so this is going to be in charge of start recognizing and this is this function needs to be asynchronous so the first thing that I want to do when we start recognizing me to delete this it's actually reset the state because it it could be that we had something before so if we reset the state we are going to delete the messages that we had before right now here I'm going to have a tri catch and the strike CCH is going to look something like this in the case that we have an error I'm just going to put it on the console here and inside the strike CCH I want to actually start using my voice Library so I'm going to say voice do start and if I just press dot you can see that we have a lot of events that we can access from this uh voice so let's say start in this case this is going to start and we can specify the local here which means uh the the language that we are going to be dealing with in this case it's going to be English but you can change this to be Spanish or whatever your language is and then uh if we come back here we need to reset State here put this as dependency okay and then uh yeah so this is going to start recognizing then we can do the same thing for stop recognizing we have as you may guess by now a stop recognizing here so I'm going to create another function that is going to be just handling this stop once we have sto maybe we want to have another to cancel recording so I'm just going to create another here and these functions need to be inside of this oops and these functions need to be inside of here yeah okay so that's for cancelling then we have other one that is going to destroy the recognizer basically you know it's going to stop everything and reset the state very important here and now we have all these methods that we are actually not using at this point and also we have this state so let's return these uh these methods as well as the state and the set state but how we are going to be dealing with the state changes so in order to do that we need to have a use effect so I'm going to create a use effect here and this effect is going to be just listening for voice events okay and let's just create the first one here we're going to have things like for example voice on and if I press and if I type just on you can see all the events that we can access from this uh from this voice so for example when the speech starts what we want to do here well we're going to have a call back function and we are going to have an event here as well so I'm going to say just any for now and I just want to access this event to update my state if you remember we have this variable state that has all these things so that when we are using this use uh this hook we can access all these things depending on uh what's going on right so when the speech starts I want to set the state to be uh equal to the previous state but in this case I want to you know set everything that we had before but I'm going to say started equal to I don't know and here we can put just whatever you want for example I'm going to say started and just add this em Emoji then I going to say it's recording equal to True at this point and yeah so whenever we start recording we are going to trigger this listener and we are going to update the state so that we can update the UI as well this way we're going to have a a lot of um you know control over what's going on and we can update easily the UI and do all that kind of stuff so let's say on speech recognize and what I want to do here is another callback and then set the state as well in this case accessing as well the previous state I want to say that this is going to be equal to previous state and then just say recognized and changing this to be this Emoji right and we can do stuff like that of course I need to pass quote here and this is how it's going to look okay so now I'm going to just paste this events uh basically they are going to be doing the same but for example if we have an error I just want to update my state saying that we have an error passing the error that we are having and set is recording equal to false on speech results we want to set the results as you can see here to the value that we are getting and here we are typing these results from these types that we are importing here so these are types or yeah types that we can use here and then we have you know updating the state these events like on a speech partial results we're going to set that to the partial results and basically that's why we added these fields on the state because we have these um because we have all these events that that can go inside these these fields right finally we have this um on a speech volume change and we're going to set the pitch in this case and finally guys this is very important we need to clean up whenever we unmount this um this component in this case we are not going to unmount it until we uh close the application but if you have this in a component whenever you unmount that component it's a good idea that you have here the destroy and then uh we can say voice do remove all listeners okay so this is going to make sure that we have everything clean and clear and yeah so this is all we need to do here we are going to be updating the state from this hook and then we have all these methods that we can access and this is going to be uh just now very easy to use if we go back to the app and now we can say for example const and then I'm just going to say use voice recognition and we can start uh utilizing you know whatever we need in this case I'm going to use the state start recognizing stop recognizing destroy recognizer and that's all we need for now so let's grab this state and one cool thing that I like to do when I'm debuging or developing I can just uh I can just duplicate this text and put the state but the state is an object right so what we can do is say Json do stringy and set the state and if I hit save you can see that we have the initial values of course that looks ugly but if we pass here a replacer in a space of two this is going to look like that so now we can see what's going on all the time right and then whenever we start pressing this button I want to start recognizing so I'm going to say start recognizing and whenever I press out I want to stop recognizing stop recognizing and yeah so and then after we have the result maybe we can have another function that is going to be handled submit so let's save this for now and uh just try this out okay so something went wrong okay guys now something very important here this app has crashed because because it's attempting to access private privacy sensitive data without the usage description now because we are trying to save uh documents and also access the microphone of the user we need to uh basically ask for permissions so to ask for permissions let's go to the app. Json and here I'm going to go all the way down here after web and I'm going to add these plugins in this case I'm adding adding this react native voice plugin and here we are going to need micro microphone permissions and speech recognition permissions now you can change this for your custom whatever message you want to use but in this case let's just save this and what I want to do now is actually stop this clear my terminal and rebuild this again so I'm going to say x rebuild platform iOS let's wait a little bit and then run on this on the simulator so I have a shortcode for this XO Ron iOS this is like a alas that I have set up on my computer but the command is going to be npx export run iOS so it's the same thing now I'm going to minimize this here and let's see if this is going to work now one thing that I want to make sure is that the device is not on silent mode so let's make sure that this is and we also have some volume here all right and let's try this again so I'm going to hold and now I have this alert that is telling me that uh we want to access so let's allow everything and now we have this information that is changing every time that I'm you know talking but in this case uh you know we have like a bug here because I wasn't pressing so let's hold and and as soon as I you know leave this button uh we are going to stop recording now of course this is shaking a lot maybe I can put this uh after we have this pressible so I'm going to put it here hit save all right let's try this again all right testing testing one two three testing okay and this is jumping but yeah so this is working as you can see here we have the results okay and once we have these results I can just stop and graph these results from my State and send it to the vacan and do all the crazy stuff that we want to do cool so now uh yeah so what I'm thinking is that maybe I can um maybe I can just try to handle try to create this handle submit okay guys so now let's try to create this function handle submit because at this point we have all we need right we just need to send this text message that we are grabbing from the user to the back end and then we need to handle that on the back end so uh well another thing that I that I'm thinking now is that we we also need to save the file that we're are going to be receiving remember that we're going to have this replay last message function or functionality so let's go ahead and create this function here I'm going to say in this case of con handle submit this is going to be an narrow function as well async because here we're going to be dealing with the request and all that so Hand of submit uh it's going to look something like this the first thing that I want to do is actually validate if we don't have anything on the results so here on the results you can see that we have um you know text but if we don't have anything and if you pay attention this is an array so I'm going to grab the position here if we don't have something here I I'm just going to return early so that we prevent making a request to try GPT and our back end and waste of resources now after this we want to try so let's create a TR catch if something goes wrong put it on the console and um yeah so what I want to do here is actually petch the data so we're going to send the this message and then we're going to receive the audio right so fetch the audio and then uh this audio is going to be a blob if you don't know what is a blob basically blob stands for binary large object and this kind of data is usually usually used when we are dealing with files like videos like MP3 in this case images as well so from the server here okay so fetch the AIO from the server now to make the fetch request I want to create another function so that we don't have uh everything here and what we can do here is maybe create a new folder called UTS and then create a new file called Fetch audio dots all right now in this in this file I'm going to create my fetch so let's call this patch audio this is going to be like a helper function it's going to be async and we are going to have actually a text as parameter of typ string so we're going to pass a text let me close this so that we can see better and what I want to do here is just grab the response from the server so we are going to be doing just a simple patch request now in this case um we don't have the end point yet so I'm just going to leave an empty an empty string and then we need to specify some options this is going to be a post request so the method is going to be post and then we need to specify as well some headers because we are dealing with um content type and all that in this case it's going to be application Json so content type application Json finally we we need to pass something on the body which is going to be the text so I'm going to change this to be stringly FY and then pass the text okay so basically I'm changing this to be a string and now this is uh this is the same as saying text so this is simpler we're just passing the text and then with the response I want to return it so I'm going to say await response remember remember that we are going to get a binary large object so in this case I'm going to say block okay and then um just hit save now this is not going to work yet we don't have an endo but what I want to do here is use my endpoint in this case I'm going to say process. end and what I want to do here is just create an end file to store my my end point so let's create this end file and I'm going to name this I don't know Expo public and then um my endpoint this is going to be equal to my endpoint of course I don't have it yet but I'm going to put it here in a moment so what I want to do now is just copy this go back here and paste it now of course uh J typescript is going to yell at me because this might be undefined but if I just put an exclamation point this is going to work just fine now uh make sure guys that you are using at least Expo 49 because these environment variables are just compatible with Expo 49 and above that's why I'm using this I don't need to install anything this is really nice so uh yeah so yeah this should be working once we have the endpoint now let's go back to the app we were working on the handle submit and what we can do here inside this I can say cons audio blop this is going to be equal to a weit petch audio which is our function um and then this is going to take the text right so we can grab it from the state do results at position zero remember that this is an array and yeah so that's it once we have this block we can do whatever we want with this file so the way we're going to be handling this file is going to be using the file reader from JavaScript so this is going to look something like this const reader equal to new file reader okay and if you are not familiar with file reader basically is going to let web applications asynchronously read the content of files or raw data stored on the user's computer using file or PL objects to specify the file blah blah blah so basically blows which is what what we are dealing with so what we are going to do here it's just initialize this reader and then we can say what we can access some some methods like for example onload and then we are going to create a function here this is going to be an async function that is going to get an event so I'm going to say e and then uh this event we can check it right so event. Target and type of event. target. result it's equal to string so basically we are going to have the audio on base 64 which is a super large string that's why I'm checking this string here and then that is going to be the data right so we can grab this audio audio data from the event. target. result but this this data guys is going to look something like this I'm just going to put it here this is how the data is going to look like this is a super large string that contains the base 64 of the file but the base 64 is going to be here after this comma so we don't want this thing here we just want whatever we have after the comma that is the actual data the audio data so from the result what I can do is just use the split function or method and split this string like this so we are splitting this in two parts and we are going to grab this part so after the split I'm going to grab the position one this is going to become an array so if we put brackets here this is how it looks position zero position one that's why we are grabbing position one all right and that is the data okay so once we have the data what I can do is save it so to save the data we need to you know save data this is going to be an audio so at this point we are going to be using the file system from Expo so let's go up here and import that here we can import all as file system and then now that we are here we are going to be using audio as well from Expo AV to play that audio once we have it okay all right so and one thing that we can do here is set some options from audio we can access like set audio mode async and this is going to allows us to basically modify some settings from the user like for example allows recording iOS equal to false then stays active in background equal to false and then for example place in silent mode this is very important that you put it to true because otherwise you're going to spend two hours wondering why you can't hear anything and the reason for that is because we had silent mode so if we set this variable this is going to play the the sound no matter what no matter if the user has this silence okay all right and then we have for example should doc Android this is true and then play through eror blah blah blah equal to false so I just grab this so I just grab this from the documentation but yeah important thing here is just play in silent mode for iOS I would say all right so let's use this file system let's go down here and what I want to do save the data right but let's create a function that is going to be in charge of doing that so if we go to the utilities folder we can create a new file that is going to be write audio to file dos okay and I'm just is going to copy this name close the browser for now let's create this function this is going to be an async function as well and we are going to get the audio data as parameter this is going to be of typ string remember that this is base 64 which is a super large uh string okay so once we have this we can actually just uh save this but before we save this we need to give it a name and the name name that I'm going to be using is going to be temp or temporary file MP3 this is the extension and before we uh we do that we can save this in a path so this is going to be the path but we cannot we cannot simply just pass this string we need to generate a we need to use the file system in this case and say document and I need to import this so I'm going to say import all as file system from Expo file system okay and now we can access this system. document directory and if I hover you can see that U pointing to the directory where the user documents for this app so we are going to save this in the documents so we can just concatenate this right so the file is going to be on the documents temp and the name is going to be temp MP3 now let's actually save it this is just the path we need to save it so let's say file system uh file system. write async WR string async as string sorry this is going to write an entire contents of file as a string so let's select it pass the path and also the data which is the parameter that we are getting and finally once we have saved this we need to specify the encoding file system remember that we are dealing with base 64 so we can select it here and once we have done that um we can simply return the path so that we can use this path to play the audio later so I'm going to return the path hit save and of course we need to export this function so let's say expert here all right and let's go back to the app in the app here we can simply say a wait uh play Sorry write a sync nope write audio to file um we are going to pass the audio data and remember guys that this function is going to return the string or the path so we can just grab this path in a variable Okay cool so everything looks that it's working at this point we have the path once we have the path we want to actually play this sound right away so that the user doesn't need to wait too much so what I going to do here is just say await play from path but now this is going to be another play audio this is going to be another function so this function play from path it's going to be another utility function so let's go ahead and say play from path. yes and let me just copy this name okay this is going to be a function so let's say export a sync NOP export the name this is going to be a constant uhuh and then async Arrow function okay and this is going to graph the path as parameter the path is going to be string and what we want to do here is actually uh access or use the audio from Expo now uh if you remember we can import audio from Expo AV so let's say audio from Expo a and let's put this inside a tri catch because this is going to be a sync and if we have an error I'm just going to put it on the console okay so inside here I want to say cons sound object and the reason for that it's because we need to create a new instance of this audio sound okay so that we can access methods like a we sound object do load async so this is going to load uh basically media media from the source and the source is going to be a URI and it's going to be the path that we are passing as parameter okay and then what we want to do once we have this loaded it's just another await and say object. playay async so this is going to just play the audio and yeah so that's it for this function let's go back here and just call this function by saying play from path passing the path and let's wait for this all right and finally guys we want to actually just destroy the recognizer because at this point we have uh you know we have sent that message to chat GPT chat GPT has responded and we don't want to you know have that information again so we can call this destroy recognizer and this is going to basically reset everything here and yeah so once we have that if you pay attention we are not actually using this BL we are just setting up the reader and then what we can do after we set this reader here we can say reader. read as data URL and we pass the block here so this should be working at this point uh if we have an error we're going to put it on the console but basically what we are doing here is just super easy we are just uh you know we're putting these functions everywhere so that is not very complicated to read this function first of all we are validating that we have a message to send if we do have a message we are going to create this post request to our backand that we haven't created yet uh we pass the message and then the file reader is going to start once we have this Blu from the response so we grab the Blu we grab the base 64 which is the data we save it to the uh to the files in the device and then we grab it from there and play it after we play it we destroy the last message that that the user recorded and then uh we just call this read as data URL passing passing the blog this is going to just do this okay and that's it guys so once we uh call this again we should be able to just redo the same over and over again so now what we can do is just go down here and enable this handle submit and what we can do down here is just say await play from path and we pass a URL path so we don't have the URL path here but we can create like for example a a variable to hold this so let's go back all the way here and what I want to do is just create this URL path that is going to contain uh the path to the last to the last message and now what I want to do is um grab the file from the local storage so that we are able to play this uh even though the user can close the application and then come back so let's create a function called the list files this is going to be an async function uh we are not going to pass anything as parameter and now what I want to do here is say track catch this is going to be uh ning function so if we have an error if I can write here U we're going to put in the console so let's grab the result equal to a wait and we're going to be using the file system from Expo read directory async this is going to return uh whatever we have on the file system so we need to pass the file URL which is the document directory and then uh this is this might be undefined but I'm going to put a exclamation point okay and of course now we have this error because I haven't provide uh an unpress here but what I want to do here is just validate that if we have actually some results here so I can say result. length this is going to be an array if this is greater than zero what I want to do is grab the the file name that is going to be add results at position zero and then grab the path from that the pa the path is going to be file system document directory plus the file name okay and then we can set this URL to this URL path variable that we have here and then what we can do is just grab this URL path variable and reutilize it here as a path now we need to make this a sync and hit save now everything is going to work just fine uh and what I want to do now is actually once we have this this path we can play the audio and also set this path to the URL path variable that we have here so that we can play last message um as soon as we get this this file uh let's hit save and I think that's all we need for this uh for this you know for this application this should we should be able to record a message now once we press this and as soon as I released we are going to call this handle submit which is going to send the result of the recognition grab the file save it and play it now we need to start creating the back end in order to to for this to work and also we need to create some configuration uh before we oops and also we need to have some configuration on Google Cloud create a project enable text to speech API and also create an account on open Ai and also create an a uh API key so that we can make request so let's go ahead and start with the back end okay guys so let's continue with the backend the first thing that I want to do it's going to be inst install nestjs CLI so this is a CLI that we can use with nestjs which is really nice and and we have commands to create a project like this one that we have here so let's go ahead and install this globally by running this command on the terminal so I'm going to put this out of way we can see and I already have it but I'm just going to run this again once you have the nestjs um package installed we can actually start using this CLI and create this backend project all right so now I can say Nest version for example and you can see that I have the version 10 so I'm going to clear my terminal and here in the desktop I'm going to create a new Nest application by running the command Nest new and then the pr the project is going to be to GPT backend okay and now this is really nice they are asking me what package manager I want to use and I want to use journ in this case so let's select it and this is going to install installing the dependencies and it's going to install uh all the things and it's going to come with some uh API routes and some configuration that we can actually use which is really nice now if this is the first time that you are seeing njs don't worry I'm also not an expert on the vicant field but I was able to be build this project and also deploy it to um to and I was able and I was able as well to deploy it to hiroku which is really nice to me and yeah so it's not really hard you're going to see in a moment all right and now the application is ready as you can see here uh we can now access this talk GPT oops we can now access this talk GPT folder and then we can open this on Visual Studio code so let's do that okay guys and this is how a njs application looks like as you can see here we have controllers modules and services we have we have this app. module controller and all that basically this is like the end point that we have at this point and let's try to run this if I run the command nextest um I think I can say death nope okay let me close this let's go to the package Json you are going to see that we have this um start dep okay so I can say yarn start dep I think okay and now we have an error because I have my other back end running let's try to run this again okay now it's running so to test this out let's go to the Explorer and I think this is going to be on Local Host 3000 all right and there we have it so this is working this hello world it's coming from this API service we also have this module which basically is like declaring uh declaring the controllers and providers the app controller is going to be like the Handler for this hello so you can see here this is the get request that we are creating called get hello and yeah so let's build on top of this now another thing that I want to mention is that if we go to code with Betto do death let me make this smaller so that we can see um I have here some dependencies that we're going to be using the first one is going to be Google Cloud text to speech open AI m eour m is optional if you want to just try this out on your local machine you can just put your credential directly so what I want to do here is actually first before we well we can go ahead and install these dependencies so I'm going to just copy this and paste it here going to stop the server clear the terminal and install the dependencies all right so now I want to go to Google Cloud website here so and as you can see here I have already this uh to GPT project but let's go ahead and create a new one so that you can see how it's done if you click on new project let me make this a little bigger uh this is going to be tutorial tutorial GPT okay so this tutorial GPT is going to be like my project for Google cloud and I'm going to hit create this is going to start generating this tutorial project on Google cloud and this should take like a couple seconds and then we can select this project now if you pay attention up here I'm have uh I have now this tutorial gbt project now what I want to do here is just search for uh text to speech and then hit enter and now you can see that we have this API here that says Cloud speech to text and also text to speech which is the one that we want right if we want to change speech to text we can use this one but in this case we want to change text to speech so let's select this one going to close this alert here and enable this uh this API into this tutorial GPT project so this is going to take a couple seconds so let's wait a little bit all right and that's it guys all right now we need to create some credentials as you can see in order for us to be able to connect connect to this service from our back end now let's select here create credential and I'm going to make this a little smaller so that we can see a little better uh which APR are you using in this case is going to be text to speech so let's just leave that like that then what data will you be accessing in this case um in this case we can say data belonging to your own application such as app Cloud first store um I think here we can select application data we don't need like the user to consent in this case uh are you planning to use this API with compute engine nope next and then service Account Details display name so in this case it's going to be GPT for example um in this I'm going to say tutorial tutorial and then this is going to be the ID service description this is optional so I'm just going to hit create and continue all right grant the service account access project I'm going to select owner I think uh I can say here nope this is optional yeah so let's just hit continue I guess yeah I think we can just leave this as owner or maybe current user owner yeah so let's continue now uh we have show inherit permissions okay let's close this here and hit done all right now if we go to credentials you are going to see that we have this uh this here so I'm going to select it okay guys now I'm going to select this service account that I have here and and here let's select Keys all right and let's add a key create a new key and here this is important we're going to select Json and hit create all right and as you can see here now I have this key which is a Json file in my files let's close this and if I bring my um my files this this file guys it's going to be like the credentials that we need to connect to this server so let's go ahead and go back to the code and here what I want to do is just drag and drop these credentials to my folder into the back end of course you want to be careful with these credentials so I want to close this of course I'm going to be deleting this but this is this is just a file that contains your credentials and it's going to look something like this uh yeah so and now I'm going to close my files now that we have here this is like the API key that we're we're going to be using to connect to Google Cloud so let's go back to Google uh that's all we need once we have this key we can use this service from the backend application so let's go back to the um let me make this smaller let's go back to the apis and servers yeah so here we here we are in the dashboard and we're going to select the usage of the API um when we start using it now let's go to open AI web website we are going to need to create an account as well as developers and once you have done that what we can do is just go to the uh manage account no view API keys so if I do Z here let's click on view API keys and here you're going to need to generate one of these if you don't have one already uh I have a lot of keys as you can see here but you cannot reutilize the same one as you can see here if you lose this key you need to create a new one by clicking this button uh but I'm going to be using the same the same one that I have already but you need to create one if you don't have one already so copy the key and yeah so you're going to be good to go now once you have your key for open AI we're going to be able to use their models so let's go back to the to GPT backend project at this point we have the Google Cloud project and also the open AI account and what I want to do now it's going to be create a new nend file and this n file is going to contain my credentials the first one is going to be uh Google application credentials and the second one is going to be open AI API key so here you're going to paste your key that is going to look something like this and then you're going to paste here the route to this file that contains our credentials to Google Okay to Google cloud in my case it's going to look something like this so let me just copy the route and paste it here basically I'm putting the route from users Betto desktop test back end in this case it's going to be um to GPT backend and then the name of the file which is this one oops and I just show you my credentials but I'm just going to copy this I don't really care because I'm going to delete this project anyway so if you want to look at the credentials they are going to look something like this uh and yeah so let's just close this out and just paste this name here so basically I'm putting the route to this Json file and now we can use these credentials with this environment variable so let's hit save close and let's yeah let's keep moving the the next thing that I want to do is going to be go to the main uh the main TS file and here uh I want to configure my environment variables that I just create so we can say config Fromm remember that we used we installed this dependency so now we can simply call this config here and this is going to grab our environment variables and it's going to make them available to us now we can hit save now one thing to notice guys is that here we have here we are listening to the port 3000 and this is fine for development but when you are going to deploy this we can change this to be Port so that uh so that this is going to grab another Port when it's on a deploy um production environment and so that you don't have an error yeah and when we are developing we're going to be using this U these 3000 but when you deploy you can Define your port on your service for example on Heroku you can you can uh set your Port there and then you can grab it from the environment variables all right so that's that's all I want to do here now let's just start creating the Handler for this let's go ahead and create first the first one which is going to be the gbt uh so let's follow this structure that we have here right let's create a GPT in this case it's going to be service all right so the service is going to be gp. service.ts and this is the file guys that is going to be handling the logic and the conversation with HPT so let's close the Explorer for now I'm going to start by importing an injectable then we're going to need some things from open AI so I'm going to say from open Ai and now let's go ahead and create this injectable all right and this injectable is not the one that I want here okay injectable and here what we want to do is export this class this is going to be a class called chat service and now what I want to do here is going to be uh declare some variables so private open Ai and then I'm going to import open AI API okay guys so we are going to start by importing open AI from open AI so let's say open high and this is going to be actually just open AI like that and now we can use this uh to initialize a new instance of open AI this is going to be uppercase of course and this is going to take our app key so we can grab that from process. m dot in this case let's go to the end file and grab this variable return here and paste it here all right now we can use this to start with uh the conversation with ch GPT so so first of all inside this class we are going to have a Constructor and also we are going to have some variables the first one is going to be the conversation so this is going to be a private variable and I'm going to say conversation and this conversation basically is going to be an array of messages so conversation history now here we are going to have the rle and for this we can use I think open AI um well the role is going to be a string and then we have the content which is going to be a string as well so the role basically is going to be between assistant which is chpt uh well the system and also the user and then the content is going to be the message so we want an array of this so what I can do is just say that this is going to be an array equal to an empty array all right and then inside the Constructor I'm going to say I'm going to actually put this configuration inside the Constructor and hit save now I'm going to uh just and actually what I can do here it's uh create another variable private open AI uh which is going to be open AI like that and then here in this constructure what I want to do here it's going to be just say this do open AI uh and then assign this configuration to this instance of open AI all right okay so we have this instance and then the array of messages now let's start by creating a new method after this Constructor this is is going to be an async and I'm going to name this uh chat with jpt we are going to grab a Content which is a string uh as parameter and here we can say conversation history we are going to start pushing this to the history so I'm going to say push roll is going to be in this case user and the content is going to be whatever we we are getting here all right so let's hit save okay this is working fine now um after this what I want to do is say chat completition and we are going to pass this conversation to chat GPT so let's say away this open AI create or chat sorry and the chat let me see no chat. competitions. create and here we can specify the messages so the messages are going to be the array of um the conversation history that we have here so we can pass this um just by saying this dot conversation history and just as an example um I'm I'm going to copy this here well let's just say that this is going to be the conversation history and then we can specify the model and the model is going to be 3.5 turbo which I think is the cheapest one uh let's hit save now um yeah so the messages guys it's going to be an array right this is going to be an array and um we can say like preload some messages here for example let's say r equal to system in this case which is going to be chat gbd and the content is going to be you know something that you want to preload for example you are and a helpful assistance okay and then comma and everything else so we can spread this conversation here now here we have an an error that says that no overload matches this call which means that roll string is not assignable to a create completition request message and I think we can fix this by declaring this here um and maybe we can import this from open AI so this is going to be like an interface that is going to declare the chat completition request and and then we can reutilize this uh here um so here maybe okay guys and here I have an error because we have said that this was going to be of typ string but this could be actually function or user system or assistant and what I want to do here is actually just uh hard code these options here and let's see see if that's going to remove this error okay so yeah that fixed the error now it's complaining because we are not using this chat competition uh so yeah so let's keep moving on now what I want to do next here are here we are just training the model right and then we are going to be appending all the requests or messages that we are sending from the front end and this is going to be saved in this array of course when we uh when we restart the server we are going to lose this history and this is going to start with just one message which which is this one but yeah so once we have this result from open AI what I want to do is say this dot conversation history and then push the response from GPT so I'm going to say rooll in this case is going to be assistant and then the content is going to be equal to the chat completition data or in this case it's going to be I think choices so chat completition do choices and then this is going to be an array which is going to contain the response at the position zero so I can access the message and then the content so what I'm doing here is just setting um the main adding the the response of chpt to the history so that we have context for the next for the next message right so for example in the demo we were talking about Steve Jobs and CHP remembered that we were talking about Steve Jobs because uh we were saving the history okay so now that we have this onage history we want to actually return this so I'm going to say return chat completition data sorry it's going to be choices add position z. message. content so we want to send uh so we want to return this uh content to the person who is using this chat with gbd right so which is using this this API we want to return just the last message okay so once we have this last message we are going to be sending it to the API of Google so let's create um well before we do that let's create another file here this is going to be GPT do controller TS so for the controller of GPT we need to import controller from njs then we're going to be dealing with a post request and a body so let's import this and import the chat service which is going to be this one this we just created this is like the service like the logic and here we can Define this controller so let's say controller and the name is going to be well the path is going to be in this case chat and we need to export this class chat controller and I'm going to say here a Constructor with a private read only chat service of type chat service okay so let's hit save now let's handle the post so I'm going to say post here the path is going to be talk and this is going to be an async function so this function is going to be called talk to GPT you can change this if you want but we are going to get here a body so I'm going to say body and we want to grab the content variable from this body and the content um is going to be of typ string right and it's going to look something like this now we can simply say return and we are going to be using the service that we created chat chat with GPT which is the Handler and we need to pass the content if you remember so if I just pass this everything is going to work just fine so here this this is going to be like the Handler and the logic we are abstracting this on the service we are basically just calling this function from the instance that we are creating here right and we are passing the content that we are grabbing from the body this is really nice I really like this syntax now let's go ahead and create now the uh controller I mean the service for the speech right so let's go ahead and do that I'm going to create a new file here and I'm going to name this file text to speech. service.ts let's go ahead and create text to speech instead of servers I'm going to say controller. TS in this case so one is going to be the service one the controll let's start with this service so for talking to Google Cloud you're going to need an injectable as well from NS then let's import text to speech client from Google Cloud okay and then injectable export this class this is going to be text to speech client sorry service this and uh we can declare a variable private that is going to be the client of type text to speech client then we need to initialize this on the Constructor so let's say this do client equal to new text um text to speech client so we are creating an instance of this um this client here of the text to speech so that we can access their methods right so let's create an async function here named synthesize speech and this is going to get a request body okay now um this request body is going to contain a response so we can say await this. client. synthesiz speech and we pass the request body then we can return the response do audio content all right so this is the service we are using text speech um this client has this method syn uh synthetize speeech synthesize speech and this is going to basically receive the text and it's going to return um the MP3 okay so this is going to be the service now we need to create the controller so let's go to the text speech controller let's start by importing the controller from NJ we are going to be dealing as well with a post we're going to be getting a a body and returning a response so let's import Now text to speech service which is the service that we just created we're going to be using it and then uh let's import response from Express all right let's import now the chat service we're going to be using the chat in this Handler let's create the controller here the path is going to be text to speech and finally let's expert this class I'm going to name text to speech in this case it's going to be controller and let's call The Constructor here we are going to be dealing with some private rate only variables which is text to speech service and this is going to be text to speech service then we also have I can um this is private can duplicate this and in this case it's going to be chat service so here we are just initializing the services and now we can access this um the values I need to open cly Braes here now let's handle the post request the path is going to be synthesize and let's create this async function synthesiz okay so we're going to have a body with a text and this text is going to be of type string then we are going to be returning a response this response is going to be of type response from Express as you can see uh we are importing it here right and uh finally we can have a try C in the case that we have an error just want to put it on the console for now and now we can actually start handling this uh this request to Google in this case I'm going to say GPT response first first of all we need to grab the GPT response right so the GPT response is going to come from the chat service so we can say chat service. chat with GPT and we are going to pass the text once we have this response we can create the the audio the audio version right now before we do that we need to uh create some parameters for this request so I'm going to call this this constant request and then we need to specify some things like the input and here is going to be the gbt response. content sorry response I think it's it's the only thing that we this is the message that we are returning here uh here if you remember we are just returning the last message so we grabbing that message here uh yeah let me close this so we are going to be grabbing this message here this is the content the chat GPT response then uh we need to specify a voice this is a really cool feature that we can use with uh text to speech API we can specify things like the language also the gender and the name name you can learn more about these options on the documentation uh but yeah so I'm going to select that I want a female and this is the name and the language is going to be United States English then we can say configuration like the encoding type in this case we need to handle an MP3 file so this is going to be inside the the request that we are going to be creating now that we have these uh settings we can say audio content and this is going to be equal to await this. text to speech synthetize speech and this is going to take the request body so let's pass this request and now we can actually access this audio content and what I want to do here is just return it to the client the way we do that is going to be just saying rest we set the headers of audio MP MPEG and then set this content right and this is all we need to do in the case that we have an error we can have something like status 500 and then passing the error and change this to be error put this on the console and yeah but this is basically what we need to do but now there's another thing that we need to do before we are actually done so I'm going to close this and then I'm going to be redirecting myself to the main.ts sorry to the app module this one and here we we are handling the app controller and app service but we are not going to be using those we're going to be using the text to speech controller and also we're going to be using uh for providers the text to speech service and also the chat service so these are the classes and handlers that we did and we need to add them here so that we have access to them let's wait a little bit and now this is running and we can actually start making request to this back end from the front end now one thing to notice guys is that because I'm going to be creating the request from the from the react native application instead of saying that that I'm going to be Point pointing to the Local Host I want to say that I'm going to be pointing to my I IP address now I'm I'm not going to be showing you that but uh yeah just as a reminder so let's leave this server here I'm going to bring my front end okay guys so if you remember here are here I am in the front end code we have this fetch audio um function that is handling this um you know this this request and here I'm putting the Expo public endpoint which in the background is going to look something like HTTP then slash slash Local Host uh 3,000 but of course I changed this for my IP address so that's why I don't I don't want to to show this but the path to this end point if you remember is going to be text to speech and then synthes size so this is how the endpoint looks and if I go back to the back end here uh let's just put it here going to make this terminal smaller so we have this path which is text speech uh sorry let me go to this text to speech and then we have syn synthesize and then we have synthesize so that's why we are saying text to speech synthesize all right this is the path that we are handling here we are going to be passing this text Tex if you remember we have this text here uh we're going to grab this text on the back end and we are going to pass it to chat GPD to get the response we're passing it here we get the response we put it into the request to Google we grab the audio from Google and we send it back to the user that's why we are getting here we are getting this file okay so now that we have this let's actually try to run this this again I'm going to restart the server just to make sure that everything is going to work fine I'm going to say jarn iOS and let's wait a little bit this is going to restart the application all right and let's see if this is going to work hello testing okay okay and this is going to make the request all right so here we have an error that's says that fetch audio doesn't exist and yeah we didn't export this function now that I'm seeing here so I'm going to export this let's go to [Music] the oops let's go back here and let's import from the utilities all right let's see if that fixes the issue all right let's see what's going on here let's try to run this again testing testing all right then now we have an error here oh yeah and that is because I forgot to put my API key so I'm going to put my API key and then I'm going to come back okay okay so I'm just going to close this all right testing [Music] testing let's wait hello how can I assist you today okay and this is working guys so I was missing my credentials on the back end but of course I don't want to show you that uh but yeah once I push put my credentials everything worked just fine and we have these responses from chat gbt so maybe we can finish this video by asking Chad GPT to say a goodbye message hey um can you say a goodbye message for the audience thank you right let's see if this works certainly here's a goodbye message for you it's time to say goodbye for now I want to express my heartfelt gratitude for the time we've spent together whether we laughed shared stories or simply enjoyed each other's company I Tre those moments dearly you've made a positive impact on my life and for that I'm truly grateful remember our cats May diverge but the memories we've created will always stay close to my heart Farewell My friend until we meet again take care and may your journey be filled with joy and success okay guys now you heard it please make sure that you subscribe if you want to check out the code go to code with. if you want to truly Master react native check out my course and also check the new react with t course the templates the projects and everything that you need is going to be at cod. thanks for watching this video and I'll see you in the next one bye
Info
Channel: Code with Beto
Views: 13,403
Rating: undefined out of 5
Keywords: ReactNative, NestJS, TypeScript, React, Expo, Expo49, GoogleTextToSpeech, OpenAI, ChatGPT, FullStackDevelopment, AIChatbot, MobileAppDevelopment, JavaScript, BackendDevelopment, FrontendDevelopment, GPT4, VoiceRecognition, Tutorial, HowTo, CodeWithBeto, Beginners, Talk GPT, tutorial, fullstack, google, api
Id: hhstKDaci2k
Channel Id: undefined
Length: 104min 57sec (6297 seconds)
Published: Mon Aug 28 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.