Skip to main content

Cloud Functions (OCR & Facial Recognition)

Este documento describe 7 Cloud Functions creadas en Node.js.

Se dividen en **Funciones de OCR**OCR y **Funciones de Reconocimiento Facial**Facial para su mejor entendimiento.

---


Índice

  1. ## Índice

    1. **Funciones de OCR**  
       - [ocrReadAndWriteImage](#1-ocrreadandwriteimage)  
       - [saveMinimalBotConversations](#2-saveminimalbotconversations)  
       - [sendOCRdataToCreatePerson](#3-sendocrdatatocreateperson)OCR

  2. 2. **Funciones de Reconocimiento Facial**  
       - [createPerson](#4-createperson)  
       - [facialRecognition](#5-facialrecognition)  
       - [searchPersonInDB](#6-searchpersonindb)  
       - [verifyPersonIdentity](#7-verifypersonidentity)Facial

    ---


Funciones de OCR

1. ocrReadAndWriteImage

### 1. **ocrReadAndWriteImage**

**Endpoint**Endpoint : https://us-west1-servicios-350819.cloudfunctions.net/ocrReadAndWriteImage

**Función Exportada**Exportada


```js
functions.http('processImage', async (req, res) => { ... })
```

####

Descripción

Esta función recibe la **URL de una imagen**imagen, la procesa usando **Google Generative AI**AI para extraer datos de identificación en un formato JSON y los **normaliza**normaliza (ajusta campos como `name`name`first_name`first_name y `last_name`last_name, direcciones, fechas, etc.).

Finalmente, envía el JSON normalizado a la ruta configurada en `CONFIG.RECEIVER_URL`RECEIVER_URL.

####

Flujo Principal

1.

    **
  1. Obtener la URL**URL de la imagen (por `req.query.url`url o `req.body.url`url).
    2.
  2. **Descargar**
  3. Descargar la imagen y convertirla a Base64.
    3.
  4. **Invocar**
  5. Invocar el modelo generativo (por ejemplo, `"gemini-1.5-flash"`).
    4.
  6. **Limpiar**
  7. Limpiar y **parsear**parsear la respuesta para extraer el JSON.
    5.
  8. **Normalizar**
  9. Normalizar campos (separar `first_name`first_name, `last_name`last_name, unificar direcciones, etc.).
    6.
  10. **Enviar**
  11. Enviar el JSON resultante a la función receptora (por POST).
    7.
  12. **Retornar**
  13. Retornar el JSON normalizado al cliente.

  14. ####

Parámetros de Entrada

  • - **Body JSON**JSON (o Query Params):


    • url   - `url` _((string, requerido)_:: URL de la imagen a procesar.

**Ejemplo Body:**

```JSON

{
  "url": "https://example.com/my-id-image.jpg"
}
```
-
  • No requiere otros campos. Si se omite `url`url, retorna error 400.
    ####

Respuesta

-

    **
  • 200 OK**  OK
      Devuelve un objeto JSON con los campos extraídos y normalizados:

  • ```JSON

{
  "first_name": "Jane",
  "last_name": "Smith",
  "driver_license_number": "ABC12345",
  "date_of_birth": "1992-02-02",
  "expiration_date": "2032-02-02",
  ...
}
```

-

**
  • 400 Bad Request**  Request
      Si no se proporciona `url`url.
    -
  • **
  • 422 Unprocessable Entity**  Entity
      Si la respuesta de la AI no es un JSON válido.
    -
  • **
  • 500 Internal Server Error**  Error
      Cualquier otro error en el procesamiento o en la llamada a la función receptora.

  • ####

Dependencias

-

    **
  • @google-cloud/functions-framework**framework (para exponer la función como HTTP).
    -
  • **
  • node-fetch**fetch (para descargar la imagen y enviar datos).
    -
  • **
  • @google/generative-ai**ai (cliente de Google Generative AI).
    -
  • **dotenv**
  • dotenv (para leer variables de entorno como `API_KEY`API_KEY, `PROMPT`PROMPT, etc.).

  • ####

Variables de Entorno

-

    `API_KEY`
  • API_KEY — Clave para Google Generative AI.
    -
  • `PROMPT`
  • PROMPT — Texto base para el modelo.
    -
  • `RECEIVER_URL`
  • RECEIVER_URL — URL destino donde se envía el JSON resultante.
    -
  • `MODEL_NAME`
  • MODEL_NAME — Nombre del modelo a usar (por defecto `"gemini-1.5-flash"`).


2. saveMinimalBotConversations

_______________________________________________________________________

### 2. **saveMinimalBotConversations**

**Endpoint**Endpoint : https://us-central1-servicios-350819.cloudfunctions.net/saveMinimalBotConversations

**Función Exportada**
```js
Exportada

functions.http('sendDataToGoogleSheet', async (req, res) => { ... })
```

####

Descripción

Esta función toma datos relacionados con OCR (o similar) y los **almacena**almacena en Google Sheets mediante el servicio de **SheetDB**SheetDB:

1.

  1. Determina **en qué hoja**hoja (sheet) colocar la información según si los datos están en **español**ol (`data.nombre`nombre) o **inglés**s (`data.first_name`first_name).
    2.
  2. Construye el objeto `sheetData`sheetData (con `sheet`sheet y `data`data) y realiza una llamada `POST`POST a la URL de SheetDB (`API_URL`API_URL).
    3.
  3. Retorna al cliente la respuesta de la API de SheetDB.

  4. ####

Parámetros de Entrada

-

    **
  • Body JSON**JSON (requerido):
      -
    • nombre `nombre` _((string, opcional)_:: si existe, se guardará en la hoja "OCR Esp".
    • first_name - `first_name` _((string, opcional)_:: si existe, se guardará en la hoja "OCR Eng".
    •   -
    • Otros campos libres (apellidos, dirección, etc.) también se guardan.

    **

Ejemplo Body en Español:**

```JSON

{
  "nombre": "Juan Perez",
  "fecha_nacimiento": "1985-01-01",
  "direccion": "Av. Principal 123"
}
```

**Ejemplo Body en Inglés:

```JSON

{
  "first_name": "John",
  "last_name": "Doe",
  "date_of_birth": "1990-05-15"
}
```

-

**Importante**
  • Importante: Debe existir **al menos**menos `nombre`nombre **o**o `first_name`first_name. De lo contrario, responde `400 JSON format not recognized`recognized.

  • ####

Respuesta

-

    **
  • 200 OK**  OK
      Devuelve el resultado de la API de SheetDB:

```JSON
{
  "first_name": "John",
  "last_name": "Doe",
  "date_of_birth": "1990-05-15"
}
```

-

**
  • 400 Bad Request**  Request
      Si no encuentra ni `nombre`nombre ni `first_name`first_name.
    -
  • **
  • 500 Internal Server Error**  Error
      Cualquier otro error interno o fallo en la llamada a SheetDB.

  • ####

Flujo Principal

1.

    **Validar**
  1. Validar que la petición sea `POST`POST.
    2.
  2. **Leer**
  3. Leer el objeto `data`data del `body`body de la petición.
    3.
  4. **Definir**
  5. Definir la hoja destino (`"OCR Esp"` si se detecta `nombre`nombre, `"OCR Eng"` si se detecta `first_name`first_name).
    4.
  6. **Enviar**
  7. Enviar los datos a la API de SheetDB.
    5.
  8. **Retornar**
  9. Retornar la respuesta de la API.

  10. ####

Dependencias

-

    **
  • @google-cloud/functions-framework**
    -framework
  • **axios**

  • axios
  • ####

Consideraciones

-

  • Si no se detectan `nombre`nombre o `first_name`first_name, se responde con `400 JSON format not recognized`recognized.
    -
  • El endpoint de SheetDB se encuentra en la variable `API_URL`API_URL (en el código).


3. sendOCRdataToCreatePerson

_______________________________________________________________________

### 3. **sendOCRdataToCreatePerson**

**Endpoint**Endpoint : https://us-central1-servicios-350819.cloudfunctions.net/sendOCRdataToCreatePerson

**Función Exportada**
```js
Exportada

functions.http('processImages', async (req, res) => { ... })
```

####

Descripción

Orquesta el **flujo OCR → creación de persona**persona:

1.

  1. Recibe **dos URLs**URLs: `idImageUrl`idImageUrl (imagen de identificación) y `selfieUrl`selfieUrl.
    2.
  2. Llama a la función **ocrReadAndWriteImage**ocrReadAndWriteImage con la imagen de identificación.
    3.
  3. **Normaliza**
  4. Normaliza y **transforma**transforma los datos recibidos del OCR para ajustarlos a la estructura que requiere **createPerson**createPerson.
    4.
  5. Invoca **createPerson**createPerson con esos datos y la `selfieUrl`selfieUrl.
    5.
  6. Retorna la respuesta de `createPerson`createPerson y los datos enviados (sin la URL de la selfie).

  7. ####

Parámetros de Entrada

  • - **Body JSON**JSON (o Query Params):


    • idImageUrl   - `idImageUrl` _((string, requerido)_:: URL de la imagen de la identificación.
    • selfieUrl - `selfieUrl` _((string, requerido)_:: URL de la imagen tipo selfie.

    **

Ejemplo Body**Body

```JSON

{
  "idImageUrl": "https://example.com/my-id.jpg",
  "selfieUrl": "https://example.com/my-selfie.jpg"
}
```
-
  • Si faltan `idImageUrl`idImageUrl o `selfieUrl`selfieUrl, retorna `400`400.

  • ####

Respuesta
-

**
  • 200 OK**
    ```JSON
    OK
{
  "response": {
  "message": "Person Created Successfully",
  "supabase_id": 123
  },
  "savedData": {
  "name": "Juan Perez",
  "date_of_birth": "1985-01-01",
  "gender": "M"
  ...
  }
}
```
- **
  • 400 Bad Request**  Request
      Si faltan URLs en los parámetros.
    -
  • **
  • 500 Internal Server Error**  Error
      Cualquier error al procesar la OCR o la creación de persona.

  • ####

Flujo Principal

1.

    **Validar**
  1. Validar que existan `idImageUrl`idImageUrl y `selfieUrl`selfieUrl.
    2.
  2. **Invocar**
  3. Invocar `ocrReadAndWriteImage`ocrReadAndWriteImage, obteniendo los datos OCR.
    3.
  4. **Formatear**
  5. Formatear la respuesta OCR (INE vs Licencia, etc.).
    4.
  6. **Llamar**
  7. Llamar a `createPerson`createPerson con el objeto resultante.
    5.
  8. **Retornar**
  9. Retornar la respuesta de creación y los datos utilizados.

  10. ####

Dependencias

-

    **
  • @google-cloud/functions-framework**
    -framework
  • **axios**

  • axios
  • ####

Funciones Auxiliares

-

    `
  • formatPersonData(ocrData, selfieUrl)`: Combina campos para ajustarlos al formato requerido por `createPerson`createPerson.
    -
  • `
  • formatDate(dateString)`: Formatea fechas `DD/MM/YYYY`YYYY a `YYYY-MM-DD`DD.

  • _______________________________________________________________________
    ##


Funciones de Reconocimiento Facial

###

Consideraciones:

Consideraciones:
-
  • Un "match" corresponde a un puntaje de 0.7 o superior para considerar que las selfies de la o las personas coinciden y se trata de la misma.
    -
  • Para mayor referencia revisar la documentación oficial de openCV:

  • ```cardlink
url: https://us.opencv.fr/docs#/
title: "OpenCV Face Recognition - Swagger UI"
host: us.opencv.fr
```
-
  • Los ids que proporciona openCV son el formato uuid y los ids proporcionados por supase son int8.

4. createPerson

### 4. **createPerson**

**Endpoint**Endpoint : https://us-central1-servicios-350819.cloudfunctions.net/createPerson

**Función Exportada**
```js
Exportada

functions.http('createPerson', async (req, res) => { ... })
```

####

Descripción

Crea un registro de persona en la base de datos de **OpenCV**OpenCV y luego **almacena**almacena el `opencv_id`opencv_id en **Supabase**Supabase:

1.

  1. Convierte la imagen a Base64.
    2.
  2. Llama a `https://us.opencv.fr/person`person para crear la persona y obtener un `id`id (llamado `opencv_id`opencv_id).
    3.
  3. Guarda ese `opencv_id`opencv_id en la tabla `people`people de **Supabase**Supabase.
    4.
  4. Retorna el `id`id de Supabase y un mensaje de éxito.

  5. ####

Parámetros de Entrada

  • - **Body JSON**JSON (o Query Params):


    • date_of_birth   - `date_of_birth` _((string, requerido)_:: fecha de nacimiento en formato `YYYY-MM-DD`DD (o similar).
    • gender - `gender` _((string, requerido)_:: "M" o "F" (o "H" vs "M" según la convención).
    • imageUrl - `imageUrl` _((string, requerido)_:: URL de la foto a enrolar.
    • name - `name` _((string, requerido)_:: nombre completo o nombre de la persona.
    • nationality - `nationality` _((string, opcional)_:: nacionalidad.

Ejemplo Body

**Ejemplo Body**

```JSON

{
  "date_of_birth": "1990-05-15",
  "gender": "M",
  "imageUrl": "https://example.com/person-face.jpg",
  "name": "John Doe",
  "nationality": "US"
}
```
-
  • Si falta alguno de los campos requeridos, retorna 400.

  • ####

Respuesta

-

    **
  • 200 OK**
    ```JSON
    OK
{
  "message": "Person Created Successfully",
  "supabase_id": 17
}
```
- **
  • 400 Bad Request**  Request
      Si faltan parámetros obligatorios (`date_of_birth`date_of_birth, `gender`gender, `imageUrl`imageUrl, `name`name).
    -
  • **
  • 500 Internal Server Error**  Error
      Cualquier error al comunicarse con OpenCV o Supabase.

  • ####

Flujo Principal

1.

    **Leer**
  1. Leer parámetros obligatorios (`date_of_birth`date_of_birth, `gender`gender, `imageUrl`imageUrl, `name`name…).
    2.
  2. **Validar**
  3. Validar que existan. Retornar `400`400 si faltan.
    3.
  4. **Descargar**
  5. Descargar la imagen y convertirla a Base64.
    4.
  6. **Invocar**
  7. Invocar la API de OpenCV para crear la persona.
    5.
  8. **Insertar**
  9. Insertar en Supabase el registro con el `opencv_id`opencv_id devuelto.
    6.
  10. **Retornar**
  11. Retornar el `supabase_id`supabase_id y un mensaje de confirmación.

  12. ####

Dependencias

-

    **
  • @google-cloud/functions-framework**
    -framework
  • **axios**
    -
  • axios
  • **dotenv**
  • dotenv (para leer `OPENCV_API_KEY`OPENCV_API_KEY, `SUPABASE_API_KEY`SUPABASE_API_KEY, etc.)

  • ####

Variables de Entorno

-

    `OPENCV_API_KEY`
  • OPENCV_API_KEY — Clave de la API de OpenCV.
    -
  • `SUPABASE_API_KEY`
  • SUPABASE_API_KEY — Clave de la API de Supabase.
    -
  • `SUPABASE_URL`
  • SUPABASE_URL — URL base del proyecto Supabase.


5. facialRecognition

_______________________________________________________________________

### 5. **facialRecognition**

**Endpoint**Endpoint : https://us-central1-servicios-350819.cloudfunctions.net/facialRecognition

**Función Exportada**
```js
Exportada

functions.http('compareImages', async (req, res) => { ... })
```
####

Descripción

Compara **dos imágenes**genes (una llamada “gallery” y otra “probe”) usando la API de OpenCV:

1.

  1. Recibe sus URLs (`gallery_url`gallery_url y `probe_url`probe_url).
    2.
  2. Descarga ambas y las transforma a Base64.
    3.
  3. Llama a `https://us.opencv.fr/compare`compare con el modo `"ACCURATE"`.
    4.
  4. Devuelve al cliente la respuesta de la API (score, match, etc.).

  5. ####

Parámetros de Entrada

  • - **Body JSON**JSON (o Query Params):


    • gallery_url   - `gallery_url` _((string, requerido)_:: URL de la imagen de galería.
    • probe_url - `probe_url` _((string, requerido)_:: URL de la imagen a comparar.

Ejemplo Body

**Ejemplo Body**

```JSON

{
  "gallery_url": "https://example.com/gallery.jpg",
  "probe_url": "https://example.com/probe.jpg"
}
```
####

Respuesta

-

    **
  • 200 OK**  OK
      Devuelve el objeto JSON directamente desde la API de OpenCV, por ejemplo:
    ```JSON
{
  "match": {
  "score": 0.87,
  "bounding_box": ...
  ...
  },
  "status": "success"
}
```
- **
  • 400 Bad Request**  Request
      Si faltan `gallery_url`gallery_url o `probe_url`probe_url.
    -
  • **
  • 500 Internal Server Error**  Error
      Si hay un error en la llamada a OpenCV.

  • ####

Flujo Principal

1.

    **Verificar**
  1. Verificar la existencia de `gallery_url`gallery_url y `probe_url`probe_url.
    2.
  2. **Descargar**
  3. Descargar ambas imágenes en formato binario.
    3.
  4. **Convertir**
  5. Convertir a Base64.
    4.
  6. **Enviar**
  7. Enviar a la API `compare`compare de OpenCV.
    5.
  8. **Retornar**
  9. Retornar la respuesta completa de OpenCV al cliente.

  10. ####

Dependencias

-

    **
  • @google-cloud/functions-framework**
    -framework
  • **axios**
    -
  • axios
  • **dotenv**

  • dotenv
  • ####

Variables de Entorno

-

    `OPENCV_API_KEY`
  • OPENCV_API_KEY — Clave para la API de OpenCV.


6. searchPersonInDB

_______________________________________________________________________

### 6. **searchPersonInDB**

**Endpoint**Endpoint : https://us-central1-servicios-350819.cloudfunctions.net/searchPersonInDB

**Función Exportada**
```js
Exportada

functions.http('searchImage', async (req, res) => { ... })
```

####

Descripción

Busca posibles coincidencias de una persona en la base de **OpenCV**OpenCV a partir de la **imagen**imagen recibida:

1.

  1. Recibe la URL de la imagen (`imageUrl`imageUrl).
    2.
  2. Convierte la imagen a Base64.
    3.
  3. Llama a `https://us.opencv.fr/search`search especificando un `max_results`max_results y un `min_score`min_score.
    4.
  4. Retorna la lista de coincidencias que OpenCV considere válidas.

  5. ####

Parámetros de Entrada

  • - **Body JSON**JSON (o Query Params):


    • url   - `url` _((string, requerido)_:: URL de la imagen a buscar  
        (en el código, también se admite `req.body.imageUrl`imageUrl).

    • **

Ejemplo Body**Body

```JSON

{
  "url": "https://example.com/face_to_search.jpg"
}
```
-
  • Si falta la URL, retorna 400.
    ####

Respuesta

-

    **
  • 200 OK**
    ```JSON
    OK
[
  {
  "id": "123",
  "score": 0.92
  },
  {
  "id": "456",
  "score": 0.85
  }
]
```
- **
  • 400 Bad Request**  Request
      Si no se proporciona la URL de la imagen.
    -
  • **
  • 500 Internal Server Error**  Error
      Si ocurre un error al llamar a OpenCV o procesar la imagen.

  • ####

Flujo Principal

1.

    **Validar**
  1. Validar que `imageUrl`imageUrl exista (req.body o req.query).
    2.
  2. **Descargar**
  3. Descargar y **codificar**codificar la imagen.
    3.
  4. **Enviar**
  5. Enviar la petición a `search`search en OpenCV.
    4.
  6. **Retornar**
  7. Retornar los resultados.

  8. ####

Dependencias

-

    **
  • @google-cloud/functions-framework**
    -framework
  • **axios**
    -
  • axios
  • **dotenv**

  • dotenv
  • ####

Variables de Entorno

-

    `OPENCV_API_KEY`
  • OPENCV_API_KEY — Clave para la API de OpenCV.


7. verifyPersonIdentity

_______________________________________________________________________

### 7. **verifyPersonIdentity**

**Endpoint**Endpoint : https://us-central1-servicios-350819.cloudfunctions.net/verifyPersonIdentity

**Función Exportada**Exportada

```js

functions.http('verifyFace', async (req, res) => { ... })
```

####

Descripción

Verifica la identidad de una persona comparando una **selfie**selfie con el registro previo en OpenCV:

1.

  1. Recibe el `id`id (de Supabase) y una `imageUrl`imageUrl.
    2.
  2. Busca en la tabla `people`people de Supabase para obtener el `opencv_id`opencv_id.
    3.
  3. Llama a `https://us.opencv.fr/verify`verify con la imagen y el `opencv_id`opencv_id.
    4.
  4. Retorna el `score`score de similitud y el `name`name registrado.

  5. ####

Parámetros de Entrada

  • - **Body JSON**JSON (o Query Params):


    • id   - `id` _((number, requerido)_:: ID de la persona en Supabase (campo `id`id de la tabla `people`people).
    • imageUrl - `imageUrl` _((string, requerido)_:: URL de la selfie a comparar.

Ejemplo Body

**Ejemplo Body**

```JSON

{
  "id": 42,
  "imageUrl": "https://example.com/selfie.jpg"
}
```
####

Respuesta

-

    **
  • 200 OK**
    ```JSON
    OK
{
  "score": 0.85,
  "name": "John Doe"
}
```

-

**
  • 400 Bad Request**  Request
      Si faltan `id`id o `imageUrl`imageUrl, o la imagen no se pudo descargar.
    -
  • **
  • 404 Not Found**  Found
      Si la persona con ese `id`id no existe en Supabase.
    -
  • **
  • 500 Internal Server Error**  Error
      Si hay un problema interno (llamadas a OpenCV o a Supabase fallidas).

  • ####

Flujo Principal

1.

    **Validar**
  1. Validar parámetros: `id`id y `imageUrl`imageUrl.
    2.
  2. **Descargar**
  3. Descargar la imagen y convertirla a Base64.
    3.
  4. **Consultar**
  5. Consultar en Supabase para obtener `opencv_id`opencv_id y `name`name.
    4.
  6. **Invocar**
  7. Invocar la API `verify`verify en OpenCV con el `opencv_id`opencv_id.
    5.
  8. **Retornar**
  9. Retornar `score`score y `name`name.

  10. ####

Dependencias

-

    **
  • @google-cloud/functions-framework**
    -framework
  • **axios**
    -
  • axios
  • **dotenv**

  • dotenv
  • ####

Variables de Entorno

-

    `OPENCV_API_KEY`
  • OPENCV_API_KEY — Clave para la API de OpenCV.
    -
  • `SUPABASE_API_KEY`
  • SUPABASE_API_KEY — Clave para la API de Supabase.