Crea un flusso di lavoro human-in-the-loop utilizzando i callback


Questo tutorial mostra come creare un flusso di lavoro di traduzione che attende human-in-the-loop, che collega un database Firestore, due funzioni Cloud Run, l'API Cloud Translation e una pagina web che utilizza SDK Firebase da aggiornare in tempo reale.

Con Workflows, puoi supportare un endpoint di callback (o webhook) che attende l'arrivo di richieste HTTP a quell'endpoint, ripristinando l'esecuzione del flusso di lavoro in un secondo momento. In questo caso, il flusso di lavoro attende il tuo input per rifiutare o convalidare la traduzione di un testo, ma potrebbe anche attenderemo un processo esterno. Per ulteriori informazioni, vedi Attendi utilizzando i callback.

Architettura

Questo tutorial crea un'app web che ti consente di:

  1. Nella pagina web della traduzione, inserisci il testo che vuoi tradurre dall'inglese in francese. Fai clic su Traduci.
  2. Dalla pagina web, viene visualizzata una funzione Cloud Run che avvia l'esecuzione del flusso di lavoro. Il testo da tradurre viene passato come parametro sia alla funzione che al flusso di lavoro.
  3. Il testo viene salvato in un file Cloud Firestore. per configurare un database. L'API Cloud Translation chiamato. La traduzione restituita viene archiviata nel database. L'app web è implementato mediante Firebase Hosting si aggiorna in tempo reale per visualizzare il testo tradotto.
  4. Il passaggio create_callback nel flusso di lavoro crea un URL di endpoint di callback che viene salvato anche nel database Firestore. La pagina web ora mostra un pulsante Convalida e un pulsante Rifiuta.
  5. Il flusso di lavoro è ora in pausa e attende una richiesta POST HTTP esplicita all'indirizzo URL dell'endpoint di callback.
  6. Puoi decidere se convalidare o rifiutare la traduzione. Facendo clic su chiama una seconda funzione Cloud Run che a sua volta chiama endpoint di callback creato dal flusso di lavoro, trasmettendo lo stato di approvazione. L'esecuzione del flusso di lavoro riprende e salva lo stato di approvazione true oppure false nel database Firestore.

Questo diagramma fornisce una panoramica della procedura:

Flusso di lavoro con callback

Obiettivi

  • Esegui il deployment di un'app web.
  • Crea un database Firestore per archiviare le richieste di traduzione.
  • Eseguire il deployment delle funzioni di Cloud Run per eseguire il flusso di lavoro.
  • Esegui il deployment ed esegui un flusso di lavoro per orchestrare l’intero processo.

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi basata sull'utilizzo previsto, utilizza il Calcolatore prezzi. I nuovi utenti di Google Cloud potrebbero essere idonei per una prova gratuita.

Prima di iniziare

I vincoli di sicurezza definiti dalla tua organizzazione potrebbero impedirti di completare i passaggi seguenti. Per informazioni sulla risoluzione dei problemi, vedi Sviluppare applicazioni in un ambiente Google Cloud vincolato.

  1. Accedi al tuo account Google Cloud. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. Install the Google Cloud CLI.
  3. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  5. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  6. Enable the App Engine, Cloud Build, Cloud Run functions, Firestore, Translation, and Workflows APIs:

    gcloud services enable appengine.googleapis.com cloudbuild.googleapis.com cloudfunctions.googleapis.com firestore.googleapis.com translate.googleapis.com workflows.googleapis.com
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

    gcloud init
  9. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  10. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  11. Enable the App Engine, Cloud Build, Cloud Run functions, Firestore, Translation, and Workflows APIs:

    gcloud services enable appengine.googleapis.com cloudbuild.googleapis.com cloudfunctions.googleapis.com firestore.googleapis.com translate.googleapis.com workflows.googleapis.com
  12. Aggiorna i componenti di Google Cloud CLI:
    gcloud components update
  13. Accedi con il tuo account:
    gcloud auth login
  14. Imposta l'ID progetto e la località predefinita utilizzati in questo tutorial:
    export GOOGLE_CLOUD_PROJECT=PROJECT_ID
    export REGION=REGION
    gcloud config set workflows/location ${REGION}
    

    Sostituisci quanto segue:

    • PROJECT_ID: l'ID del tuo progetto Google Cloud. Puoi cerca il tuo ID progetto Ti diamo il benvenuto della console Google Cloud.
    • REGION: i Workflows supportati posizione di tua scelta.

Esegui il deployment della prima funzione Cloud Run

Questa funzione di Cloud Run avvia l'esecuzione del flusso di lavoro. Il testo da tradurre viene passato come parametro sia alla funzione che alla un flusso di lavoro di machine learning.

  1. Crea una directory denominata callback-translation e con sottodirectory chiamati invokeTranslationWorkflow,translationCallbackCall e public:

    mkdir -p ~/callback-translation/{invokeTranslationWorkflow,translationCallbackCall,public}
    
  2. Passa alla directory invokeTranslationWorkflow:

    cd ~/callback-translation/invokeTranslationWorkflow
    
  3. Crea un file di testo con il nome index.js che contenga quanto segue. Codice Node.js:

    const cors = require('cors')({origin: true});
    const {ExecutionsClient} = require('@google-cloud/workflows');
    const client = new ExecutionsClient();
    
    exports.invokeTranslationWorkflow = async (req, res) => {
      cors(req, res, async () => {
        const text = req.body.text;
        console.log(`Translation request for "${text}"`);
    
        const PROJECT_ID = process.env.PROJECT_ID;
        const CLOUD_REGION = process.env.CLOUD_REGION;
        const WORKFLOW_NAME = process.env.WORKFLOW_NAME;
    
        const execResponse = await client.createExecution({
          parent: client.workflowPath(PROJECT_ID, CLOUD_REGION, WORKFLOW_NAME),
          execution: {
            argument: JSON.stringify({text})
          }
        });
        console.log(`Translation workflow execution request: ${JSON.stringify(execResponse)}`);
    
        const execName = execResponse[0].name;
        console.log(`Created translation workflow execution: ${execName}`);
    
        res.set('Access-Control-Allow-Origin', '*');
        res.status(200).json({executionId: execName});
      });
    };
  4. Crea un file di testo con il nome package.json che contenga la sezione seguenti metadati npm:

    {
      "name": "launch-translation-workflow",
      "version": "0.0.1",
      "dependencies": {
        "@google-cloud/workflows": "^1.2.5",
        "cors": "^2.8.5"
      }
    }
    
  5. Esegui il deployment della funzione con un trigger HTTP e consenti l'accesso non autenticato:

    gcloud functions deploy invokeTranslationWorkflow \
    --region=${REGION} \
    --runtime nodejs14 \
    --entry-point=invokeTranslationWorkflow \
    --set-env-vars PROJECT_ID=${GOOGLE_CLOUD_PROJECT},CLOUD_REGION=${REGION},WORKFLOW_NAME=translation_validation \
    --trigger-http \
    --allow-unauthenticated
    

    Il deployment della funzione potrebbe richiedere alcuni minuti. In alternativa, puoi usa l'interfaccia delle funzioni di Cloud Run nella console Google Cloud per eseguire il deployment della funzione.

  6. Una volta eseguito il deployment della funzione, puoi confermare la proprietà httpsTrigger.url:

    gcloud functions describe invokeTranslationWorkflow
    

    Prendi nota dell'URL che viene restituito, in modo da poterlo utilizzare in un passaggio successivo.

Esegui il deployment della seconda funzione Cloud Run

Questa funzione Cloud Run invia una richiesta POST HTTP al callback creato dal flusso di lavoro, trasmettendo uno stato di approvazione che riflette se la traduzione è convalidata o rifiutata.

  1. Passa alla directory translationCallbackCall:

    cd ../translationCallbackCall
    
  2. Crea un file di testo con il nome index.js che contenga quanto segue. Codice Node.js:

    const cors = require('cors')({origin: true});
    const fetch = require('node-fetch');
    
    exports.translationCallbackCall = async (req, res) => {
      cors(req, res, async () => {
        res.set('Access-Control-Allow-Origin', '*');
    
        const {url, approved} = req.body;
        console.log("Approved? ", approved);
        console.log("URL = ", url);
        const {GoogleAuth} = require('google-auth-library');
        const auth = new GoogleAuth();
        const token = await auth.getAccessToken();
        console.log("Token", token);
    
        try {
          const resp = await fetch(url, {
              method: 'POST',
              headers: {
                  'accept': 'application/json',
                  'content-type': 'application/json',
                  'authorization': `Bearer ${token}`
              },
              body: JSON.stringify({ approved })
          });
          console.log("Response = ", JSON.stringify(resp));
    
          const result = await resp.json();
          console.log("Outcome = ", JSON.stringify(result));
    
          res.status(200).json({status: 'OK'});
        } catch(e) {
          console.error(e);
    
          res.status(200).json({status: 'error'});
        }
      });
    };
  3. Crea un file di testo con il nome package.json che contenga la sezione seguenti metadati npm:

    {
      "name": "approve-translation-workflow",
      "version": "0.0.1",
      "dependencies": {
        "cors": "^2.8.5",
        "node-fetch": "^2.6.1",
        "google-auth-library": "^7.1.1"
      }
    }
    
  4. Esegui il deployment della funzione con un trigger HTTP e consenti l'accesso non autenticato:

    gcloud functions deploy translationCallbackCall \
    --region=${REGION} \
    --runtime nodejs14 \
    --entry-point=translationCallbackCall \
    --trigger-http \
    --allow-unauthenticated
    

    Il deployment della funzione potrebbe richiedere alcuni minuti. In alternativa, puoi usa l'interfaccia delle funzioni di Cloud Run nella console Google Cloud per eseguire il deployment della funzione.

  5. Una volta eseguito il deployment della funzione, puoi confermare la proprietà httpsTrigger.url:

    gcloud functions describe translationCallbackCall
    

    Prendi nota dell'URL che viene restituito, in modo da poterlo utilizzare in un passaggio successivo.

Esegui il deployment del flusso di lavoro

Un flusso di lavoro è costituito da una serie di passaggi descritti utilizzando Sintassi di Workflows, che può essere scritta in formato YAML o JSON formato. Questa è la definizione del flusso di lavoro. Dopo aver creato un flusso di lavoro, e renderlo disponibile per l'esecuzione.

  1. Passa alla directory callback-translation:

    cd ..
    
  2. Crea un file di testo con il nome file translation-validation.yaml e con i seguenti contenuti:

    main:
        params: [translation_request]
        steps:
            - log_request:
                call: sys.log
                args:
                    text: ${translation_request}
            - vars:
                assign:
                    - exec_id: ${sys.get_env("GOOGLE_CLOUD_WORKFLOW_EXECUTION_ID")}
                    - text_to_translate: ${translation_request.text}
                    - database_root: ${"projects/" + sys.get_env("GOOGLE_CLOUD_PROJECT_ID") + "/databases/(default)/documents/translations/"}
            - log_translation_request:
                call: sys.log
                args:
                    text: ${text_to_translate}
    
            - store_translation_request:
                call: googleapis.firestore.v1.projects.databases.documents.patch
                args:
                    name: ${database_root + exec_id}
                    updateMask:
                        fieldPaths: ['text']
                    body:
                        fields:
                            text:
                                stringValue: ${text_to_translate}
                result: store_translation_request_result
    
            - translate:
                call: googleapis.translate.v2.translations.translate
                args:
                    query:
                        q: ${text_to_translate}
                        target: "FR"
                        format: "text"
                        source: "EN"
                result: translation_result
            - assign_translation:
                assign:
                    - translation: ${translation_result.data.translations[0].translatedText} 
            - log_translation_result:
                call: sys.log
                args:
                    text: ${translation}
    
            - store_translated_text:
                call: googleapis.firestore.v1.projects.databases.documents.patch
                args:
                    name: ${database_root + exec_id}
                    updateMask:
                        fieldPaths: ['translation']
                    body:
                        fields:
                            translation:
                                stringValue: ${translation}
                result: store_translation_request_result   
    
            - create_callback:
                call: events.create_callback_endpoint
                args:
                    http_callback_method: "POST"
                result: callback_details
            - log_callback_details:
                call: sys.log
                args:
                    text: ${callback_details}
    
            - store_callback_details:
                call: googleapis.firestore.v1.projects.databases.documents.patch
                args:
                    name: ${database_root + exec_id}
                    updateMask:
                        fieldPaths: ['callback']
                    body:
                        fields:
                            callback:
                                stringValue: ${callback_details.url}
                result: store_callback_details_result
    
            - await_callback:
                call: events.await_callback
                args:
                    callback: ${callback_details}
                    timeout: 3600
                result: callback_request
            - assign_approval:
                assign:
                    - approved: ${callback_request.http_request.body.approved}
    
            - store_approval:
                call: googleapis.firestore.v1.projects.databases.documents.patch
                args:
                    name: ${database_root + exec_id}
                    updateMask:
                        fieldPaths: ['approved']
                    body:
                        fields:
                            approved:
                                booleanValue: ${approved}
                result: store_approval_result
    
            - return_outcome:
                return:
                    text: ${text_to_translate}
                    translation: ${translation}
                    approved: ${approved}
  3. Dopo aver creato il flusso di lavoro, puoi eseguirne il deployment, ma non eseguire il flusso di lavoro personalizzato:

    gcloud workflows deploy translation_validation --source=translation-validation.yaml
    

Crea la tua app web

Crea un'app web che chiami una Cloud Function che avvia l'esecuzione del un flusso di lavoro di machine learning. La pagina web si aggiorna in tempo reale per visualizzare il risultato di una richiesta di traduzione.

  1. Passa alla directory public:

    cd public
    
  2. Crea un file di testo con il nome index.html che contenga quanto segue. markup HTML. In un passaggio successivo, modificherai il file index.html e aggiungerai il metodo script dell'SDK Firebase.

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width">
    
        <title>Frenglish translation — Feature Workflows callbacks</title>
    
        <link rel="stylesheet"
            href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.42/dist/themes/base.css">
        <script type="module"
            src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.42/dist/shoelace.js"></script>
        <link rel="stylesheet" href="./style.css">
    </head>
    
    <body>
        <h1>Translate from English to French</h1>
    
        <sl-form class="form-overview">
            <sl-textarea id="text" placeholder="The quick brown fox jumps over the lazy dog."
                label="English text to translate"></sl-textarea>
            <p></p>
            <sl-button id="translateBtn" type="primary">Translate</sl-button>
            <p></p>
            <sl-alert id="translation" type="primary">
                Le rapide renard brun saute au dessus du chien paresseux.
            </sl-alert>
            <p></p>
            <div id="buttonRow" style="display: none;">
                <sl-button id="validateBtn" type="success">Validate</sl-button>
                <sl-button id="rejectBtn" type="danger">Reject</sl-button>
            </div>
            <p></p>
            <sl-alert id="validationAlert" type="success">
                <sl-icon slot="icon" name="check2-circle"></sl-icon>
                <strong>The translation has been validated</strong><br>
                Glad that you liked our translation! We'll save it in our database.
            </sl-alert>
            <sl-alert id="rejectionAlert" type="danger">
                <sl-icon slot="icon" name="exclamation-octagon"></sl-icon>
                <strong>The translation has been rejected</strong><br>
                A pity the translation isn't good! We'll do better next time!
            </sl-alert>
            <p></p>
            <sl-button id="newBtn" style="display: none;" type="primary">New translation</sl-button>
        </sl-form>
    
        <script src="https://www.gstatic.com/firebasejs/8.6.3/firebase-app.js"></script>
        <script src="https://www.gstatic.com/firebasejs/8.6.3/firebase-firestore.js"></script>
    
        <script>
            var firebaseConfig = {
                apiKey: "XXXX",
                authDomain: "XXXX",
                projectId: "XXXX",
                storageBucket: "XXXX",
                messagingSenderId: "XXXX",
                appId: "XXXX",
                measurementId: "XXXX"
            };
            // Initialize Firebase
            firebase.initializeApp(firebaseConfig);
        </script>
        <script src="./script.js" type="module"></script>
    </body>
    
    </html>
    
  3. Crea un file di testo con il nome script.js che contenga quanto segue. Codice JavaScript:

    document.addEventListener("DOMContentLoaded", async function (event) {
        const textArea = document.getElementById("text");
        textArea.focus();
    
        const newBtn = document.getElementById("newBtn");
        newBtn.addEventListener("sl-focus", event => {
            event.target.blur();
            window.location.reload();
        });
    
        const translationAlert = document.getElementById("translation");
        const buttonRow = document.getElementById("buttonRow");
    
        var callbackUrl = "";
    
        const validationAlert = document.getElementById("validationAlert");
        const rejectionAlert = document.getElementById("rejectionAlert");
        const validateBtn = document.getElementById("validateBtn");
        const rejectBtn = document.getElementById("rejectBtn");
    
        const translateBtn = document.getElementById("translateBtn");
        translateBtn.addEventListener("sl-focus", async event => {
            event.target.disabled = true;
            event.target.loading = true;
            textArea.disabled = true;
    
            console.log("Text to translate = ", textArea.value);
    
            const fnUrl = UPDATE_ME;
    
            try {
                console.log("Calling workflow executor function...");
                const resp = await fetch(fnUrl, {
                    method: "POST",
                    headers: {
                        "accept": "application/json",
                        "content-type": "application/json"
                    },
                    body: JSON.stringify({ text: textArea.value })
                });
                const executionResp = await resp.json();
                const executionId = executionResp.executionId.slice(-36);
                console.log("Execution ID = ", executionId);
    
                const db = firebase.firestore();
                const translationDoc = db.collection("translations").doc(executionId);
    
                var translationReceived = false;
                var callbackReceived =  false;
                var approvalReceived = false;
                translationDoc.onSnapshot((doc) => {
                    console.log("Firestore update", doc.data());
                    if (doc.data()) {
                        if ("translation" in doc.data()) {
                            if (!translationReceived) {
                                console.log("Translation = ", doc.data().translation);
                                translationReceived = true;
                                translationAlert.innerText = doc.data().translation;
                                translationAlert.open = true;
                            }
                        }
                        if ("callback" in doc.data()) {
                            if (!callbackReceived) {
                                console.log("Callback URL = ", doc.data().callback);
                                callbackReceived = true;
                                callbackUrl = doc.data().callback;
                                buttonRow.style.display = "block";
                            }
                        }
                        if ("approved" in doc.data()) {
                            if (!approvalReceived) {
                                const approved = doc.data().approved;
                                console.log("Approval received = ", approved);
                                if (approved) {
                                    validationAlert.open = true;
                                    buttonRow.style.display = "none";
                                    newBtn.style.display = "inline-block";   
                                } else {
                                    rejectionAlert.open = true;
                                    buttonRow.style.display = "none";
                                    newBtn.style.display = "inline-block";
                                }
                                approvalReceived = true;
                            }
                        }
                    }
                });
            } catch (e) {
                console.log(e);
            }
            event.target.loading = false;
        });
    
        validateBtn.addEventListener("sl-focus", async event => {
            validateBtn.disabled = true;
            rejectBtn.disabled = true;
            validateBtn.loading = true;
            validateBtn.blur();
    
            // call callback
            await callCallbackUrl(callbackUrl, true);
        });
    
        rejectBtn.addEventListener("sl-focus", async event => {
            rejectBtn.disabled = true;
            validateBtn.disabled = true;
            rejectBtn.loading = true;
            rejectBtn.blur();
    
            // call callback
            await callCallbackUrl(callbackUrl, false);
        });
    
    });
    
    async function callCallbackUrl(url, approved) {
        console.log("Calling callback URL with status = ", approved);
    
        const fnUrl = UPDATE_ME;
        try {
            const resp = await fetch(fnUrl, {
                method: "POST",
                headers: {
                    "accept": "application/json",
                    "content-type": "application/json"
                },
                body: JSON.stringify({ url, approved })
            });
            const result = await resp.json();
            console.log("Callback answer = ", result);
        } catch(e) {
            console.log(e);
        }
    }
  4. Modifica il file script.js sostituendo i segnaposto UPDATE_ME con gli URL delle funzioni Cloud Run annotati in precedenza.

    1. Nel metodo translateBtn.addEventListener, sostituisci const fnUrl = UPDATE_ME; con:

      const fnUrl = "https://REGION-PROJECT_ID.cloudfunctions.net/invokeTranslationWorkflow";

    2. Nella funzione callCallbackUrl, sostituisci const fnUrl = UPDATE_ME; con:

      const fnUrl = "https://REGION-PROJECT_ID.cloudfunctions.net/translationCallbackCall";

  5. Crea un file di testo con il nome style.css che contenga quanto segue. stili a cascata:

    * {
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    }
    
    body {
        margin: 20px;
    }
    
    h1, h2, h3, h4 {
        color: #0ea5e9;
    }
    

Aggiungi Firebase all'applicazione web

In questo tutorial, la pagina HTML, lo script JavaScript e il foglio di stile CSS vengono distribuiti come asset statici tramite Firebase Hosting, ma possono essere ospitati ovunque e pubblicati localmente sul tuo computer a scopo di test.

Crea un progetto Firebase

Prima di poter aggiungere Firebase alla tua app, devi creare un account Firebase per connetterti alla tua app.

  1. Nella console Firebase, fai clic su Crea un progetto, quindi seleziona la tua progetto Google Cloud dal menu a discesa per aggiungere Firebase. a quel progetto.

  2. Fai clic su Continua fino a quando non viene visualizzata l'opzione per aggiungere Firebase.

  3. Salta la configurazione di Google Analytics per il tuo progetto.

  4. Fai clic su Aggiungi Firebase.

Firebase esegue automaticamente il provisioning delle risorse per il tuo progetto Firebase. Quando Completata la procedura, verrà visualizzata la pagina Panoramica del progetto nella console Firebase.

Registra la tua app con Firebase

Dopo aver creato un progetto Firebase, puoi aggiungervi la tua app web.

  1. Al centro della pagina di panoramica del progetto, fai clic sull'icona Web (</>). per avviare il flusso di lavoro di configurazione.

  2. Inserisci un nickname per la tua app.

    Solo tu puoi vedere questa informazione nella console Firebase.

  3. Salta per ora la configurazione di Firebase Hosting.

  4. Fai clic su Registra app e vai alla console.

Attiva Cloud Firestore

L'app web utilizza Cloud Firestore per ricevere e salvare dati. Ti serviranno per abilitare Cloud Firestore.

  1. Nella sezione Crea della console Firebase, fai clic su Database Firestore.

    (Potrebbe essere necessario prima espandere il riquadro di navigazione a sinistra per visualizzare la scheda Crea section.)

  2. Nel riquadro Cloud Firestore, fai clic su Crea database.

  3. Seleziona Avvia in modalità di test utilizzando una regola di sicurezza come la seguenti:

    rules_version = '2';
    service cloud.firestore {
    match /databases/{database}/documents {
      match /{document=**} {
        allow read, write;
      }
    }
    }
    
  4. Fai clic su Avanti dopo aver letto il disclaimer sulle regole di sicurezza.

  5. Imposta la località in cui sono archiviati i dati di Cloud Firestore. Puoi accettare l'impostazione predefinita o scegliere una regione vicina a te.

  6. Fai clic su Abilita per eseguire il provisioning di Firestore.

Aggiungi l'SDK Firebase e inizializza Firebase

Firebase fornisce librerie JavaScript per la maggior parte dei prodotti Firebase. Prima dell'utilizzo Firebase Hosting, devi aggiungere gli SDK Firebase all'app web.

  1. Per inizializzare Firebase nella tua app, devi fornire i dati Firebase dell'app la configurazione del progetto.
    1. Nella console Firebase, vai a Impostazioni progetto. .
    2. Nel riquadro Le tue app, seleziona la tua app.
    3. Nel riquadro Configurazione e configurazione dell'SDK, per caricare le librerie dell'SDK Firebase dalla rete CDN, seleziona CDN.
    4. Copia lo snippet nel file index.html in fondo all'elemento <body> sostituendo i valori segnaposto XXXX.
  2. Installa l'SDK Firebase JavaScript.

    1. Se non hai ancora un file package.json, creane uno eseguendo il comando seguente comando dalla directory callback-translation:

      npm init
    2. Installa il pacchetto npm firebase e salvalo nel file package.json eseguendo:

      npm install --save firebase

Inizializza ed esegui il deployment del progetto

Per collegare i file di progetto locali al progetto Firebase, devi per inizializzare il progetto. Poi potrai eseguire il deployment della tua app web.

  1. Dalla directory callback-translation, esegui questo comando:

    firebase init
  2. Seleziona l'opzione Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys.

  3. Scegli di utilizzare un progetto esistente e inserisci il tuo ID progetto.

  4. Accetta public come directory root pubblica predefinita.

  5. Scegli di configurare un'app a pagina singola.

  6. Salta la configurazione di build e deployment automatici con GitHub.

  7. Nel prompt di File public/index.html already exists. Overwrite?, digita No.

  8. Passa alla directory public:

    cd public
  9. Dalla directory public, esegui questo comando per eseguire il deployment del progetto al tuo sito:

    firebase deploy --only hosting

Testa l'app web in locale

Firebase Hosting ti consente di visualizzare e testare le modifiche localmente e interagire con le risorse del progetto backend emulate. Quando usi firebase serve, la tua app interagisce con un backend emulato per i tuoi contenuti di hosting e ma il backend reale per tutte le altre risorse del progetto. In questo tutorial, può utilizzare firebase serve, ma è sconsigliato test.

  1. Dalla directory public, esegui questo comando:

    firebase serve
  2. Apri l'app web all'URL locale restituito (di solito http://localhost:5000).

  3. Inserisci del testo in inglese, quindi fai clic su Traduci.

    Dovrebbe essere visualizzata una traduzione del testo in francese.

  4. Ora puoi fare clic su Convalida o Rifiuta.

    Nel database Firestore, puoi verificare i contenuti. Dovrebbe essere simile al seguente:

    approved: true
    callback: "https://workflowexecutions.googleapis.com/v1/projects/26811016474/locations/us-central1/workflows/translation_validation/executions/68bfce75-5f62-445f-9cd5-eda23e6fa693/callbacks/72851c97-6bb2-45e3-9816-1e3dcc610662_1a16697f-6d90-478d-9736-33190bbe222b"
    text: "The quick brown fox jumps over the lazy dog."
    translation: "Le renard brun rapide saute par-dessus le chien paresseux."
    

    Lo stato di approved è true o false, a seconda che tu convalidare o rifiutare la traduzione.

Complimenti! Hai creato un flusso di lavoro di traduzione human-in-the-loop che utilizza i callback di Workflows.

Esegui la pulizia

Se hai creato un nuovo progetto per questo tutorial, elimina il progetto. Se hai utilizzato un progetto esistente e vuoi mantenerlo senza l'aggiunta delle modifiche In questo tutorial, elimina le risorse create per il tutorial.

Elimina il progetto

Il modo più semplice per eliminare la fatturazione creato per il tutorial.

Per eliminare il progetto:

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Elimina le risorse del tutorial

  1. Rimuovi la configurazione predefinita della gcloud CLI che hai aggiunto durante configurazione del tutorial:

    gcloud config unset workflows/location
    
  2. Elimina il flusso di lavoro creato in questo tutorial:

    gcloud workflows delete WORKFLOW_NAME
    
  3. Elimina le funzioni di Cloud Run che hai creato in questo tutorial:

    gcloud functions delete FUNCTION_NAME
    

    Puoi eliminare le funzioni Cloud Run anche dalla console Google Cloud.

Passaggi successivi