application Chatbot et Traduction

Création d’une application Chatbot et Traduction avec Nextjs et React Native à l’aide de ChatGPT (OpenAI)

Qu’est-ce que ChatGPT ?

  1. https://github.com/hrupesh/nextjs-chatgpt-BE
  2. https://github.com/hrupesh/RNChatGPTApp

Créer le ServerSide avec Nextjs

npx create-next-app@latest 

OU Ajoutez un indicateur dactylographié à créer dans typescipt 

npx create-next-app@latest --typescript
dev fil 

OU 

npm run dev 

OU 

prochain dev
fil ajouter openai 

OU 

npm i openai
mkdir src && touch config.ts
importer { Configuration , OpenAIApi } depuis  "openai" ; 

const config = nouvelle  Configuration ({ 
    apiKey : process. env . OPEN_AI_KEY
 }); 

const openAI = new  OpenAIApi (config); 

exporter  openAI par défaut ;
toucher . env
 type d'importation { NextApiRequest , NextApiResponse } de  "suivant" ; 
importez openAI depuis  "../../src/config" ; 

type  Data = { 
  résultat ? : chaîne | indéfini ; 
  erreur ? : chaîne ; 
} ; 

exportez le  gestionnaire de fonction asynchrone par défaut  (   req : NextApiRequest,   res : NextApiResponse<Data> ) { if (!req?. body ?. question ){     res. statut  



  
( 400 ). json ({ erreur : 'Paramètres non valides' }) 
  } achèvement 

  const = attendre openAI. createCompletion ({ 
    model : 'text-davinci-003' , 
    prompt : req?. body ?. question , 
    temperature : 0.8 , 
    max_tokens : 2048 , 
  }); 
  rés. statut ( 200 ). json ({ résultat : achèvement. données ?. choix?.[ 0 ]?. texte }); 
}
 type d'importation { NextApiRequest , NextApiResponse } de  "suivant" ; 
importez openAI depuis  "../../src/config" ; 

type  Data = { 
  résultat ? : chaîne | indéfini ; 
  erreur ? : chaîne ; 
} ; 

exportez le  gestionnaire de fonction asynchrone par défaut  (   req : NextApiRequest,   res : NextApiResponse<Data> ) { if (!req?. body ?. query || !req?. body ?.  



  langue ) { 
    rés. statut ( 400 ). json ({ erreur : "Paramètres invalides" }); 
  } 

  const { query = "" , language = "English" } = req?. corps ; 
  const achèvement = attendre openAI. createCompletion ({ 
    model : "text-davinci-003" , 
    // Nous demandons l'API dans le format ci-dessous 
    // Le ?? après `query` est juste une 
    invite HACK : `translate ${query} ?? in ${ Langue}` , 
    température : 0.8 , 
    max_tokens : 2048 , 
  }); 
  rés. statut ( 200 ). json ({ résultat : achèvement. données ?. choix ?.[ 0 ]?. texte }); 
}

Créer une application avec React Native

npx react-native init <votre-nom-de-projet> -- template react -native- template - typescript
fil ios 
fil android 
  OR 
réactif natif run-android 
réactif natif run-ios
importer  React , {useState} de  'react' ; 
import { View , Text , StyleSheet , Image , Pressable , TextInput } from  'react-native' ; Application 

const  : Réagissez . FC = () => (   <View style={styles.container}>     <Text>Bonjour React Native !</Text>   </View> ); styles const = Feuille de style . créer ({ conteneur : { flex






  
    : 1 , 
    justifieContent : 'center' , 
    alignItems : 'center' , 
  }, 
}); 

exporter l'  application par défaut  ;
importer  React , {useState} de  'react' ; 
import { View , Text , StyleSheet , Image , Pressable , TextInput } from  'react-native' ; 
import { Conversation  as  ConversationIcon , Translate } from  './assets' ; 
import { Conversation , Traduction } de  './src/components' ; 

interface  ContentProps{ index 
  sélectionné : nombre ; 
} 

const  Contenu : Réagissez . FC < ContentProps > = ( { selectedIndex } ) => { 
  switch (selectedIndex) { 
    case  0 : 
      return <Conversation /> 
    case  1 : 
      return <Translation /> 
    default : return <></>; 
  } 
} Application 

const  : Réagissez . CF = () => { const
  [selectedIndex, setSelectedIndex] = useState< nombre >( 0 ); 
  const  changeSelection = ( sélection : nombre ) => () =>  setSelectedIndex (sélection); 
  return ( 
    <View style={styles.container}> 
      <Content {...{selectedIndex}} /> 
      <View style={styles.tabBar}> 
        <Pressable onPress={changeSelection(0)}> 
          <Image style={ styles.tabIcon} source={ConversationIcon} /> 
        </Pressable> 
        <Pressable onPress={changeSelection(1)}> 
          <Image style={styles.tabIcon} source={Translate} /> 
        <
      </Afficher> 
    </Afficher> 
  ); 
} ; 

styles const = Feuille de style . créer ({ 
  conteneur : { 
    flex : 1 , 
    justifierContent : 'flex-end' , 
    alignItems : 'center' , 
  }, 
  tabBar : { 
    flexDirection : 'row' , 
    justifierContent : 'space-around' , 
    alignItems : 'center' , 
    paddingBottom : 30 , 
    rembourrageHaut : 20, 
    backgroundColor : '#82AAE3' , 
    width : '100%' , 
    shadowColor : "#000" , 
    shadowOffset : { 
      height : - 6 , 
      width : 0
     }, 
    shadowOpacity : 0.2 , 
    shadowRadius : 10 , 
  }, 
  tabIcon : { 
    width : 24 , 
    hauteur : 24 , 
  }, 
}); 

exporter l'  application par défaut  ;
mkdir src && cd src && composants mkdir && composants cd && touch index.ts 
mkdir Conversation && cd Conversation && touch index.tsx && touch styles.ts
import  React , {useCallback, useRef, useState} de  'react' ; 
import { 
  Image , 
  KeyboardAvoidingView , 
  Platform , 
  ScrollView , 
  Text , 
  TextInput , 
  View , 
} from  'react-native' ; 
import { Typing } from  '../../../assets' ; 
importer {getAnswer} depuis  '../../services/api' ; 
importer les styles depuis  './styles' ; const 

d'exportation  Conversation : Réagissez . FC = () => { 
  const [texte, setText] = useState< string >( '' ); 
  const [chargement, setLoading] = useState< boolean >( false ); 
  const [conversation, setConversation] = useState< Enregistrement < chaîne , chaîne >>({}); 
  const scrollRef = useRef< ScrollView >( null ); 

  const handleSubmit = useCallback ( async () => { 
    setTimeout (() => scrollRef ?. actuel ?. scrollToEnd ({ animé : vrai }), 200 ); 
    setConversation ( prev => ({ 
      ...prev, 
      ...{[ `sent ${ Object .keys(prev)?.length} ` ]: text}, 
    })); 
    setText ( '' ); 
    setLoading ( vrai ); 
    réponse const = attendre  getAnswer (texte); 
    setLoading ( faux ); 
    setConversation (prev => ({
      ...prev,
      ...{[ `received ${ Object .keys(prev)?.length} ` ]: answer},
    })); 
    setTimeout ( () => scrollRef?.current ? .scrollToEnd ( { animé : vrai }), 200 ); 
  }, [texte]); 

  return (
    <>
      <ScrollView
        ref={scrollRef}
        keyboardDismissMode="interactive"
        showsVerticalScrollIndicator={false}
        keyboardShouldPersistTaps={'always'}
        contentContainerStyle={styles.scrollView}> 
        {Object?.keys(conversation)?.map(keyName => { 
          if (keyName?.includes('sent')) { 
            return ( 
              <View 
                key={`sent${keyName} `} 
                style={[styles.sent, styles.chatBubble]}> 
                <Text 
                  selectable 
                  selectionColor={'purple'} 
                  style={styles.msgText}> 
                  {conversation?.[keyName]} 
                </Text> 
              </View> 
            ); 
          } 
          return ( 
            <View key={keyName} style={[styles.received, styles.chatbulle]}>
              <Text selectable selectionColor={'yellow'} style={styles.msgText}> 
                {conversation?.[keyName]?.replace('\n', '')?.replace('\n', '')} 
              </Text> 
            </View> 
          ); 
        })} 
        {chargement && ( 
          <View 
            key={'typingLoader'} 
            style={[styles.received, styles.chatBubble]}> 
            <Image 
              resizeMode="contain" 
              source={Typing} 
              style={styles.typingLoader} 
            / > 
          </View> 
        )} 
      </ScrollView>


        behavior={Platform.OS === 'ios' ? 'padding' : 'height'}> 
        <TextInput 
          blurOnSubmit 
          autoCapitalize="none" 
          autoComplete="off" 
          autoCorrect={false} 
          keyboardAppearance={'dark'} 
          keyboardType={'web-search'} 
          style={styles.input} 
          placeholder="Demandez-moi n'importe quoi...." 
          value={text} 
          onChangeText={setText} 
          onSubmitEditing={handleSubmit} 
          placeholderTextColor={'#1116'} 
        /> 
      </KeyboardAvoidingView> 
    </> 
  ); 
} ;
importez {Dimensions, StyleSheet} depuis  'react-native' ; 

export const  LARGEUR = Dimensions. obtenir ( 'fenêtre' ).width; 

exporter la feuille de style par défaut . créer ({ 
  conteneur : { 
    flex : 1 , 
    justifierContent : 'flex-end' , 
    alignItems : 'center' , 
  }, 
  entrée : { 
    borderWidth : 2 , 
    borderColor : '#91D8E4' , 
    width : WIDTH - 40, 
    hauteur : 60 , 
    borderRadius : 12 , 
    backgroundColor : '#EAFDFC' , 
    paddingHorizontal : 14 , 
    fontWeight : '700' , 
    color : '#000' , 
    marginBottom : 20 , 
    shadowColor : '#82AAE3' , 
    shadowOffset : { 
      height : 0 , 
      width : 0 , 
    }, 
    shadowOpacity : 0.4 , 
    shadowRadius: 4 , 
  }, 
  loader : { 
    position : 'absolute' , 
    largeur : '100%' , 
    hauteur : '100%' , 
    zIndex : 999 , 
    backgroundColor : '#fffc' , 
    justifierContent : 'center' , 
    alignItems : 'center' , 
  }, 
  scrollView : { 
    paddingHorizontal : 20 , 
    paddingTop : 60 , 
    paddingBottom : 140 ,
    largeur : LARGEUR, 
  }, 
  envoyé : { 
    backgroundColor : '#04DE71' , 
    alignSelf : 'flex-end' , 
  }, 
  reçu : { 
    backgroundColor : '#2094FA' , 
    alignSelf : 'flex-start' , 
  }, 
  chatBubble : { 
    borderRadius : 20 , 
    paddingVertical : 12 , 
    marginBottom : 8 , 
    maxWidth : WIDTH / 2 + 80 , 
    paddingHorizontal: 16 , 
  }, 
  msgText : { 
    fontWeight : '500' , 
    color : '#FFF' , 
    letterSpacing : 0.2 , 
  }, 
  typingLoader : { 
    width : 80 , 
    height : 20
   } 
});
  1. Nous avons créé trois variables d’état pour stocker et mettre à jour textloadingstate et conversation. Nous avons également créé un objet ref nommé scrollRefque nous utiliserons pour faire défiler vers le bas de notre vue de défilement de chat.
  2. Ensuite, nous avons déclaré une handleSubmitméthode, cette méthode est chargée de définir la fin du texte de l’utilisateur dans conversationpuis d’appeler la getAnswerméthode qui appelle notre API backend et renvoie la réponse de l’API ( nous créerons cette méthode à l’étape suivante ). Ensuite, nous ajoutons la réponse que nous obtenons de l’API dans notre conversationétat var.
  3. Scrollviewest utilisé pour rendre toutes les données en converationvariable. Nous le mappons pour rendre tous les textes que nous avons envoyés et reçus de l’API.
  4. Enfin, nous avons notre TextInputenveloppé dans un KeyBoardAvoidingViewafin qu’il ne se cache pas derrière le clavier de l’appareil. Ceci TextInputest responsable de l’obtention de l’entrée de l’utilisateur et de l’appel de la handleSubmitméthode lorsque l’utilisateur soumet dans le fichier TextInput.
cd src && services mkdir && services cd 
mkdir api && cd api 
touch index.ts
fil ajouter axios 
   OU 
npm i axios
importer des axios depuis  'axios' ; 
const  BASE_URL = 'http://nextjs-chatgpt-be.vercel.app/api/' ; 

export  const  getAnswer = async ( question: string ) => { 
  try { 
    const res = wait axios. poster ( 
      ` ${BASE_URL} poser-une-question` , 
      {question}, 
    ); 
    retour res?. données ?. résultat ; 
  } catch (e) { 
    console . Erreur(e); 
    retour  'Quelque chose s'est mal passé !! ☹️' ; 
  } 
} ; 

export  const  getTranslatedText = async ( requête : chaîne , langue : chaîne ) => { 
  essayer { 
    const res = attendre axios. post ( ` ${BASE_URL} traduire` , {requête, langue}); 
    retour res?. données ?. résultat ; 
  } catch (e) { 
    console . erreur (e); 
    retour  'Quelque chose s'est mal passé !! ☹️';
  }
};
  • getAnswerpour appeler le point de ask-a-questionterminaison
  • getTranslatedTextpour appeler le point de translateterminaison ( nous utiliserons cette méthode dans les étapes ultérieures ).
Chatbot utilisant Chat-GPT (OpenAI)
composants cd && mkdir Translation && cd Translation 
touch index.tsx && touch styles.ts
importez {StyleSheet} depuis  'react-native' ; 
importer {LARGEUR} depuis  '../Conversation/styles' ; 

exporter la feuille de style par défaut . créer ({ 
  conteneur : { 
    flex : 1 , 
    justifierContent : 'flex-start' , 
    alignItems : 'center' , 
    paddingTop : 80 , 
  }, 
  entrée : { 
    borderWidth : 2 , 
    borderColor : '#91D8E4' , 
    width : WIDTH - 40, 
    hauteur : 60 , 
    borderRadius : 12 , 
    backgroundColor : '#EAFDFC' , 
    paddingHorizontal : 14 , 
    fontWeight : '700' , 
    color : '#000' , 
    marginBottom : 20 , 
    shadowColor : '#82AAE3' , 
    shadowOffset : { 
      height : 0 , 
      width : 0 , 
    }, 
    shadowOpacity : 0.4 , 
    shadowRadius: 4 , 
  }, 
  translateText : { 
    fontWeight : '700' , 
    fontSize : 24 , 
    color : '#000' , 
    textAlign : 'left' , 
    alignSelf : 'flex-start' , 
    letterSpacing : 0.4 , 
  } 
});
import { View , Text , TextInput , Button , ActivityIndicator } from  'react-native' ; 
import  React , {useCallback, useState} de  'react' ; 
importer les styles depuis  './styles' ; 
importer {getTranslatedText} depuis  '../../services/api' ; 

export  const  Traduction : React . FC = () => { 
  const [texte, setText] = useState< chaîne>( '' ); 
  const [langue, setLanguage] = useState< string >( 'English' ); 
  const [translatedText, setTranslatedText] = useState< string >( '' ); 
  const [chargement, setLoading] = useState< boolean >( false ); 
  const translateText = useCallback ( async () => { 
    setLoading ( true ); 
    const result = attendre  getTranslatedText (texte, langue); 
    setTranslatedText (résultat); 
    setLoading( faux ); 
  }, [texte, langue]); 
  return ( 
    <View style={styles.container}> 
      <TextInput 
        placeholder="Entrez le texte à traduire" 
        style={styles.input} 
        value={text} 
        onChangeText={setText} 
        placeholderTextColor={'#1116'} 
      /> 
      < TextInput 
        placeholder="Entrez la langue dans laquelle traduire" 
        style={styles.input} 
        value={language} 
        onChangeText={setLanguage} 
        placeholderTextColor={'#1116'} 
      /> 
      {loading ? ( 
        <ActivityIndicator size={'large'} couleur={'
      ) : ( 
        <Button title={`Translate to ${language}`} onPress={translateText} /> 
      )} 
      <Text style={styles.translatedText}>{translatedText}</Text> 
    </View> 
  ); 
} ;
Traduction à l’aide de Chat-GPT (OpenAI)

Conclusion

Fin de ChatGPT 😆
Retour en haut