Integración de características de openAI, comunicación y datos de la organización en una aplicación de línea de negocio
Nivel: intermedio
En este tutorial se muestra cómo Azure OpenAI, Azure Communication Services y Microsoft Graph/Microsoft Graph Toolkit se pueden integrar en una aplicación de línea de negocio (LOB) para mejorar la productividad del usuario, elevar la experiencia del usuario y llevar las aplicaciones de línea de negocio al siguiente nivel. Entre las características clave de la aplicación se incluyen las siguientes:
- IA: permitir a los usuarios formular preguntas en lenguaje natural y convertir sus respuestas a SQL que se pueden usar para consultar una base de datos, permitir que los usuarios definan reglas que se pueden usar para generar mensajes de correo electrónico y SMS automáticamente y obtenga información sobre cómo se puede usar lenguaje natural para recuperar datos de sus propios orígenes de datos personalizados. Azure OpenAI se usa para estas características.
- Comunicación: habilite las llamadas telefónicas desde la aplicación a los clientes y la funcionalidad correo electrónico/SMS mediante Azure Communication Services.
- Datos de la organización: extraiga datos de la organización relacionados que los usuarios puedan necesitar (documentos, chats, correos electrónicos, eventos de calendario) a medida que trabajan con los clientes para evitar el cambio de contexto. Proporcionar acceso a este tipo de datos organizativos reduce la necesidad de que el usuario cambie a Outlook, Teams, OneDrive, otras aplicaciones personalizadas, su teléfono, etc., ya que los datos y la funcionalidad específicos que necesitan se proporcionan directamente en la aplicación. Microsoft Graph y Microsoft Graph Toolkit se usan para esta característica.
La aplicación es una sencilla aplicación de administración de clientes que permite a los usuarios administrar sus clientes y datos relacionados. Consta de un front-end creado mediante TypeScript que llama a las API de back-end para recuperar datos, interactuar con la funcionalidad de inteligencia artificial, enviar mensajes de correo electrónico o SMS y extraer datos de la organización. Esta es una introducción a la solución de aplicación que le guiará en este tutorial:
El tutorial le guiará por el proceso de configuración de los recursos necesarios de Azure y Microsoft 365. También le guiará por el código que se usa para implementar las características de inteligencia artificial, comunicación y datos de la organización. Aunque no será necesario copiar y pegar código, algunos de los ejercicios tendrán que modificar el código para probar diferentes escenarios.
Lo que creará en este tutorial
Elegir su propia aventura
Puede completar todo el tutorial desde el principio hasta el final o completar temas específicos de interés. El tutorial se divide en los temas siguientes:
- Clone el ejercicio del proyecto (ejercicio obligatorio).
- Ejercicios de IA: cree un recurso de Azure OpenAI y úselo para convertir lenguaje natural en SQL, generar mensajes de correo electrónico o SMS y trabajar con sus propios datos y documentos.
- Ejercicios de comunicación: cree un recurso de Azure Communication Services y úselo para realizar llamadas telefónicas desde la aplicación y enviar mensajes de correo electrónico o SMS.
- Ejercicios de datos de la organización: cree un registro de aplicación de Id. de Entra de Microsoft para que Microsoft Graph y Microsoft Graph Toolkit se puedan usar para autenticar y extraer datos de la organización en la aplicación.
Requisitos previos
- Nodo : se usará el nodo 20+ y npm 10+ para este proyecto.
- git
- Visual Studio Code (aunque se recomienda Visual Studio Code, se puede usar cualquier editor)
- Suscripción de Azure
- Inquilino para desarrolladores de Microsoft 365
- Docker Desktop u otro entorno de ejecución de contenedor compatible con OCI (Open Container Initiative), como Podman o nerdctl capaz de ejecutar un contenedor.
Tecnologías en la nube de Microsoft usadas en este tutorial
- Azure Communication Services
- Azure OpenAI Service
- Microsoft Entra ID
- Microsoft Graph
- Kit de herramientas de Microsoft Graph
Clonar el proyecto
El proyecto de código usado en este tutorial está disponible en https://github.com/microsoft/MicrosoftCloud. El repositorio del proyecto incluye código del lado cliente y del lado servidor necesarios para ejecutar el proyecto, lo que le permite explorar las características integradas relacionadas con la inteligencia artificial (IA), la comunicación y los datos de la organización. Además, el proyecto sirve como recurso para guiarle en la incorporación de características similares en sus propias aplicaciones.
En este ejercicio:
- Clone el repositorio de GitHub.
- Agregue un archivo .env al proyecto y actualícelo.
Antes de continuar, asegúrese de que tiene todos los requisitos previos instalados y configurados como se describe en la sección Requisitos previos de este tutorial.
Clonación del repositorio de GitHub y creación de un .env
archivo
Ejecute el comando siguiente para clonar el repositorio de GitHub de Microsoft Cloud en la máquina.
git clone https://github.com/microsoft/MicrosoftCloud
Abra la carpeta MicrosoftCloud/samples/openai-acs-msgraph en Visual Studio Code.
Nota:
Aunque usaremos Visual Studio Code en este tutorial, se puede usar cualquier editor de código para trabajar con el proyecto de ejemplo.
Observe las siguientes carpetas y archivos:
- client: código de aplicación del lado cliente.
- server: código de API del lado servidor.
- docker-compose.yml: se usa para ejecutar una base de datos postgreSQL local.
Cambie el nombre de .env.example en la raíz del proyecto a .env.
Abra el archivo .env y dedique un momento a examinar las claves que se incluyen:
ENTRAID_CLIENT_ID= TEAM_ID= CHANNEL_ID= OPENAI_API_KEY= OPENAI_ENDPOINT= OPENAI_MODEL=gpt-4o OPENAI_API_VERSION=2024-05-01-preview POSTGRES_USER= POSTGRES_PASSWORD= ACS_CONNECTION_STRING= ACS_PHONE_NUMBER= ACS_EMAIL_ADDRESS= CUSTOMER_EMAIL_ADDRESS= CUSTOMER_PHONE_NUMBER= API_PORT=3000 AZURE_AI_SEARCH_ENDPOINT= AZURE_AI_SEARCH_KEY= AZURE_AI_SEARCH_INDEX=
Actualice los valores siguientes en .env. El servidor de API usará estos valores para conectarse a la base de datos de PostgreSQL local.
POSTGRES_USER=web POSTGRES_PASSWORD=web-password
Ahora que tiene el proyecto en su lugar, vamos a probar algunas de las características de la aplicación y a aprender cómo se compilan. Seleccione el botón Siguiente que aparece a continuación para continuar o saltar a un ejercicio específico mediante la tabla de contenido.
AI: Creación de un recurso de Azure OpenAI e implementación de un modelo
Para empezar a usar Azure OpenAI en las aplicaciones, debe crear un servicio Azure OpenAI e implementar un modelo que se pueda usar para realizar tareas como convertir lenguaje natural en SQL, generar contenido de mensajes de correo electrónico o SMS, etc.
En este ejercicio:
- Cree un recurso de servicio OpenAI de Azure.
- Implementación de un modelo.
- Actualice el archivo .env con valores del recurso del servicio Azure OpenAI.
Creación de un recurso de servicio OpenAI de Azure
Visite Azure Portal en el explorador e inicie sesión.
Escriba openai en la barra de búsqueda de la parte superior de la página del portal y seleccione Azure OpenAI en las opciones que aparecen.
Seleccione Crear en la barra de herramientas.
Nota:
Aunque este tutorial se centra en Azure OpenAI, si tiene una clave de API de OpenAI y desea usarla, puede omitir esta sección y ir directamente a la sección Actualizar el archivo .env del proyecto a continuación. Asigne la clave de API de OpenAI a
OPENAI_API_KEY
en el archivo .env (puede omitir cualquier otra.env
instrucción relacionada con OpenAI).Los modelos de Azure OpenAI están disponibles en regiones específicas. Visite el documento de disponibilidad del modelo de Azure OpenAI para obtener información sobre qué regiones admiten el modelo gpt-4o que se usa en este tutorial.
Realice las siguientes tareas:
- Seleccione la suscripción a Azure.
- Seleccione el grupo de recursos que se va a usar (cree uno si es necesario).
- Seleccione una región en la que se admita el modelo gpt-4o en función del documento que miró anteriormente.
- Escriba el nombre del recurso. Debe ser un valor único.
- Seleccione el plan de tarifa Estándar S0 .
Seleccione Siguiente hasta llegar a la pantalla Revisar y enviar . Seleccione Crear.
Una vez creado el recurso de Azure OpenAI, vaya a él y seleccione Administración de recursos :->Claves y punto de conexión.
Busque los valores CLAVE 1 y Punto de conexión . Usará ambos valores en la sección siguiente para copiarlos en un archivo local.
Seleccione Resource Management -->Model deployments (Implementaciones del modelo).
Seleccione el botón Administrar implementaciones para ir a Azure OpenAI Studio.
Seleccione Implementar modelo -->Deploy base model (Implementar modelo base) en la barra de herramientas.
Seleccione gpt-4o en la lista de modelos y seleccione Confirmar.
Nota:
Azure OpenAI admite varios tipos diferentes de modelos. Cada modelo se puede usar para controlar diferentes escenarios.
Se mostrará el cuadro de diálogo siguiente. Dedique un momento a examinar los valores predeterminados proporcionados.
Cambie el valor de Tokens por límite de velocidad de minutos (miles) a 100 000. Esto le permitirá realizar más solicitudes al modelo y evitar alcanzar el límite de velocidad a medida que realice los pasos siguientes.
Seleccione Implementar.
Una vez implementado el modelo, seleccione Áreas de juegos -->Chat.
La lista desplegable Implementación debe mostrar el modelo gpt-4o .
Dedique un momento a leer el texto del mensaje del sistema que se proporciona. Esto indica al modelo cómo actuar a medida que el usuario interactúa con él.
Busque el cuadro de texto en el área de chat y escriba Resumir lo que es generative AI y cómo se puede usar. Seleccione Entrar para enviar el mensaje al modelo y hacer que genere una respuesta.
Experimente con otras solicitudes y respuestas. Por ejemplo, escriba Proporcionar un breve historial sobre la capital de Francia y observe la respuesta generada.
Actualizar el archivo del .env
proyecto
Vuelva a Visual Studio Code y abra el
.env
archivo en la raíz del proyecto.Copie el valor KEY 1 del recurso de Azure OpenAI y asígnelo a
OPENAI_API_KEY
en el archivo .env ubicado en la raíz de la carpeta openai-acs-msgraph :OPENAI_API_KEY=<KEY_1_VALUE>
Copie el valor *Punto de conexión y asígnelo a
OPENAI_ENDPOINT
en el archivo .env . Quite el/
carácter del final del valor si está presente.OPENAI_ENDPOINT=<ENDPOINT_VALUE>
Nota:
Verá que los valores de
OPENAI_MODEL
yOPENAI_API_VERSION
ya están establecidos en el archivo .env . El valor del modelo se establece en gpt-4o que coincide con el nombre de implementación del modelo que creó anteriormente en este ejercicio. La versión de la API se establece en un valor admitido definido en la documentación de referencia de Azure OpenAI.Guarde el archivo .env.
Iniciar los servicios de aplicación
Es el momento de iniciar los servicios de aplicación, como la base de datos, el servidor de API y el servidor web.
En los pasos siguientes, creará tres ventanas de terminal en Visual Studio Code.
Haga clic con el botón derecho en el archivo .env de la lista de archivos de Visual Studio Code y seleccione Abrir en terminal integrado. Asegúrese de que el terminal está en la raíz del proyecto - openai-acs-msgraph - antes de continuar.
Elija una de las siguientes opciones para iniciar la base de datos postgreSQL:
Si tiene Docker Desktop instalado y en ejecución, ejecute
docker-compose up
en la ventana del terminal y presione Entrar.Si tiene Podman con podman-compose instalado y en ejecución, ejecute
podman-compose up
en la ventana del terminal y presione Entrar.Para ejecutar el contenedor de PostgreSQL directamente mediante Docker Desktop, Podman, nerdctl u otro entorno de ejecución de contenedor que haya instalado, ejecute el siguiente comando en la ventana del terminal:
Mac, Linux o Subsistema de Windows para Linux (WSL):
[docker | podman | nerdctl] run --name postgresDb -e POSTGRES_USER=web -e POSTGRES_PASSWORD=web-password -e POSTGRES_DB=CustomersDB -v $(pwd)/data:/var/lib/postgresql/data -p 5432:5432 postgres
Windows con PowerShell:
[docker | podman] run --name postgresDb -e POSTGRES_USER=web -e POSTGRES_PASSWORD=web-password -e POSTGRES_DB=CustomersDB -v ${PWD}/data:/var/lib/postgresql/data -p 5432:5432 postgres
Una vez que se inicia el contenedor de base de datos, presione el + icono de la barra de herramientas del terminal de Visual Studio Code para crear una segunda ventana de terminal.
cd
en la carpeta server/typescript y ejecute los siguientes comandos para instalar las dependencias e iniciar el servidor de API.npm install
npm start
Presione de nuevo el + icono en la barra de herramientas del terminal de Visual Studio Code para crear una tercera ventana de terminal.
cd
en la carpeta cliente y ejecute los siguientes comandos para instalar las dependencias e iniciar el servidor web.npm install
npm start
Se iniciará un explorador y se le llevará a http://localhost:4200.
IA: Lenguaje natural a SQL
La cita "Just because you can't mean you should" es una guía útil al pensar en las funcionalidades de inteligencia artificial. Por ejemplo, la característica lenguaje natural de Azure OpenAI a SQL permite a los usuarios realizar consultas de base de datos en inglés sin formato, lo que puede ser una herramienta eficaz para mejorar su productividad. Sin embargo, la potencia no siempre significa adecuada o segura. En este ejercicio se muestra cómo usar esta característica de IA, al tiempo que se describen consideraciones importantes que se deben tener en cuenta antes de decidir implementarla.
Este es un ejemplo de una consulta de lenguaje natural que se puede usar para recuperar datos de una base de datos:
Get the the total revenue for all companies in London.
Con las indicaciones adecuadas, Azure OpenAI convertirá esta consulta en SQL que se puede usar para devolver los resultados de la base de datos. Como resultado, los usuarios no técnicos, incluidos los analistas de negocios, los vendedores y los ejecutivos, pueden recuperar más fácilmente información valiosa de bases de datos sin lidiar con una sintaxis SQL compleja o confiar en las redes de datos y filtros restringidos. Este enfoque simplificado puede aumentar la productividad eliminando la necesidad de que los usuarios busquen asistencia de expertos técnicos.
En este ejercicio se proporciona un punto de partida que le ayudará a comprender cómo funciona el lenguaje natural a SQL, presentarle algunas consideraciones importantes, pensar en ventajas y desventajas y mostrar el código para empezar.
En este ejercicio, aprenderá a:
- Use avisos de GPT para convertir lenguaje natural en SQL.
- Experimente con diferentes avisos de GPT.
- Use sql generado para consultar la base de datos postgreSQL iniciada anteriormente.
- Devuelve los resultados de la consulta de PostgreSQL y los muestra en el explorador.
Comencemos experimentando con diferentes avisos gpT que se pueden usar para convertir lenguaje natural en SQL.
Uso de la característica Lenguaje natural a SQL
En el ejercicio anterior ha iniciado la base de datos, las API y la aplicación. También ha actualizado el
.env
archivo. Si no ha completado esos pasos, siga las instrucciones al final del ejercicio antes de continuar.Vuelva al explorador (http://localhost:4200) y busque la sección Consulta personalizada de la página debajo de la datagrid. Observe que ya se incluye un valor de consulta de ejemplo: obtenga los ingresos totales de todos los pedidos. Agrupar por empresa e incluir la ciudad.
Seleccione el botón Ejecutar consulta. Esto pasará la consulta de lenguaje natural del usuario a Azure OpenAI que la convertirá en SQL. A continuación, la consulta SQL se usará para consultar la base de datos y devolver los posibles resultados.
Ejecute la siguiente consulta personalizada:
Get the total revenue for Adventure Works Cycles. Include the contact information as well.
Vea la ventana de terminal que ejecuta el servidor de API en Visual Studio Code y observe que muestra la consulta SQL devuelta desde Azure OpenAI. Las API del lado servidor usan los datos JSON para consultar la base de datos postgreSQL. Los valores de cadena incluidos en la consulta se agregan como valores de parámetro para evitar ataques por inyección de código SQL:
{ "sql": "SELECT c.company, c.city, c.email, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.company = $1 GROUP BY c.company, c.city, c.email", "paramValues": ["Adventure Works Cycles"] }
Vuelva al explorador y seleccione Restablecer datos para ver todos los clientes de nuevo en la datagrid.
Exploración del lenguaje natural en código SQL
Sugerencia
Si usa Visual Studio Code, puede abrir archivos directamente seleccionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
A continuación, escriba el nombre del archivo que desea abrir.
Nota:
El objetivo de este ejercicio es mostrar lo que es posible con la funcionalidad de LENGUAJE natural a SQL y demostrar cómo empezar a usarlo. Como se mencionó anteriormente, es importante analizar si este tipo de inteligencia artificial es adecuado para su organización antes de continuar con cualquier implementación. También es imperativo planear las reglas de solicitud adecuadas y las medidas de seguridad de base de datos para evitar el acceso no autorizado y proteger los datos confidenciales.
Ahora que ha visto la característica de lenguaje natural a SQL en acción, vamos a examinar cómo se implementa.
Abra el archivo server/apiRoutes.ts y busque la
generateSql
ruta. La aplicación del lado cliente llama a esta ruta de API que se ejecuta en el explorador y se usa para generar SQL a partir de una consulta de lenguaje natural. Una vez recuperada la consulta SQL, se usa para consultar la base de datos y devolver resultados.router.post('/generateSql', async (req, res) => { const userPrompt = req.body.prompt; if (!userPrompt) { return res.status(400).json({ error: 'Missing parameter "prompt".' }); } try { // Call Azure OpenAI to convert the user prompt into a SQL query const sqlCommandObject = await getSQLFromNLP(userPrompt); let result: any[] = []; // Execute the SQL query if (sqlCommandObject && !sqlCommandObject.error) { result = await queryDb(sqlCommandObject) as any[]; } else { result = [ { query_error : sqlCommandObject.error } ]; } res.json(result); } catch (e) { console.error(e); res.status(500).json({ error: 'Error generating or running SQL query.' }); } });
Observe la funcionalidad siguiente en la
generateSql
ruta:- Recupera el valor de consulta de usuario de
req.body.prompt
y lo asigna a una variable denominadauserPrompt
. Este valor se usará en el símbolo del sistema GPT. - Llama a una
getSQLFromNLP()
función para convertir el lenguaje natural en SQL. - Pasa el CÓDIGO SQL generado a una función denominada
queryDb
que ejecuta la consulta SQL y devuelve los resultados de la base de datos.
- Recupera el valor de consulta de usuario de
Abra el archivo server/openAI.ts en el editor y busque la
getSQLFromNLP()
función. La ruta llamageneratesql
a esta función y se usa para convertir el lenguaje natural en SQL.async function getSQLFromNLP(userPrompt: string): Promise<QueryData> { // Get the high-level database schema summary to be used in the prompt. // The db.schema file could be generated by a background process or the // schema could be dynamically retrieved. const dbSchema = await fs.promises.readFile('db.schema', 'utf8'); const systemPrompt = ` Assistant is a natural language to SQL bot that returns a JSON object with the SQL query and the parameter values in it. The SQL will query a PostgreSQL database. PostgreSQL tables with their columns: ${dbSchema} Rules: - Convert any strings to a PostgreSQL parameterized query value to avoid SQL injection attacks. - Return a JSON object with the following structure: { "sql": "", "paramValues": [] } Examples: User: "Display all company reviews. Group by company." Assistant: { "sql": "SELECT * FROM reviews", "paramValues": [] } User: "Display all reviews for companies located in cities that start with 'L'." Assistant: { "sql": "SELECT r.* FROM reviews r INNER JOIN customers c ON r.customer_id = c.id WHERE c.city LIKE 'L%'", "paramValues": [] } User: "Display revenue for companies located in London. Include the company name and city." Assistant: { "sql": "SELECT c.company, c.city, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.city = $1 GROUP BY c.company, c.city", "paramValues": ["London"] } User: "Get the total revenue for Adventure Works Cycles. Include the contact information as well." Assistant: { "sql": "SELECT c.company, c.city, c.email, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.company = $1 GROUP BY c.company, c.city, c.email", "paramValues": ["Adventure Works Cycles"] } `; let queryData: QueryData = { sql: '', paramValues: [], error: '' }; let results = ''; try { results = await callOpenAI(systemPrompt, userPrompt); if (results) { console.log('results', results); const parsedResults = JSON.parse(results); queryData = { ...queryData, ...parsedResults }; if (isProhibitedQuery(queryData.sql)) { queryData.sql = ''; queryData.error = 'Prohibited query.'; } } } catch (error) { console.log(error); if (isProhibitedQuery(results)) { queryData.sql = ''; queryData.error = 'Prohibited query.'; } else { queryData.error = results; } } return queryData; }
- Un
userPrompt
parámetro se pasa a la función . EluserPrompt
valor es la consulta de lenguaje natural escrita por el usuario en el explorador. - Un
systemPrompt
define el tipo de asistente de IA que se va a usar y las reglas que se deben seguir. Esto ayuda a Azure OpenAI a comprender la estructura de la base de datos, qué reglas aplicar y cómo devolver la consulta SQL generada y los parámetros. - Se llama a una función denominada
callOpenAI()
y lossystemPrompt
valores yuserPrompt
se le pasan. - Los resultados se comprueban para asegurarse de que no se incluyen valores prohibidos en la consulta SQL generada. Si se encuentran valores prohibidos, la consulta SQL se establece en una cadena vacía.
- Un
Veamos el símbolo del sistema con más detalle:
const systemPrompt = ` Assistant is a natural language to SQL bot that returns a JSON object with the SQL query and the parameter values in it. The SQL will query a PostgreSQL database. PostgreSQL tables with their columns: ${dbSchema} Rules: - Convert any strings to a PostgreSQL parameterized query value to avoid SQL injection attacks. - Return a JSON object with the following structure: { "sql": "", "paramValues": [] } Examples: User: "Display all company reviews. Group by company." Assistant: { "sql": "SELECT * FROM reviews", "paramValues": [] } User: "Display all reviews for companies located in cities that start with 'L'." Assistant: { "sql": "SELECT r.* FROM reviews r INNER JOIN customers c ON r.customer_id = c.id WHERE c.city LIKE 'L%'", "paramValues": [] } User: "Display revenue for companies located in London. Include the company name and city." Assistant: { "sql": "SELECT c.company, c.city, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.city = $1 GROUP BY c.company, c.city", "paramValues": ["London"] } User: "Get the total revenue for Adventure Works Cycles. Include the contact information as well." Assistant: { "sql": "SELECT c.company, c.city, c.email, SUM(o.total) AS revenue FROM customers c INNER JOIN orders o ON c.id = o.customer_id WHERE c.company = $1 GROUP BY c.company, c.city, c.email", "paramValues": ["Adventure Works Cycles"] } `;
Se define el tipo de asistente de IA que se va a usar. En este caso, un "lenguaje natural para el bot de SQL".
Se definen los nombres de tabla y las columnas de la base de datos. El esquema de alto nivel incluido en el símbolo del sistema se puede encontrar en el archivo server/db.schema y tiene el aspecto siguiente.
- customers (id, company, city, email) - orders (id, customer_id, date, total) - order_items (id, order_id, product_id, quantity, price) - reviews (id, customer_id, review, date, comment)
Sugerencia
Puede considerar la posibilidad de crear vistas de solo lectura que solo contengan los datos que los usuarios pueden consultar mediante lenguaje natural a SQL.
Se define una regla para convertir los valores de cadena en un valor de consulta con parámetros para evitar ataques por inyección de código SQL.
Una regla se define para devolver siempre un objeto JSON con la consulta SQL y los valores de parámetro en él.
Se proporcionan mensajes de usuario de ejemplo y los valores de parámetro y consulta SQL esperados. Esto se conoce como aprendizaje de "pocos disparos". Aunque las MÁQUINAS VIRTUALES se entrenan en grandes cantidades de datos, se pueden adaptar a nuevas tareas con solo unos pocos ejemplos. Un enfoque alternativo es el aprendizaje de "disparo cero", donde no se proporciona ningún ejemplo y se espera que el modelo genere los valores de parámetro y consulta SQL correctos.
La
getSQLFromNLP()
función envía los mensajes del sistema y del usuario a una función denominadacallOpenAI()
que también se encuentra en el archivo server/openAI.ts . LacallOpenAI()
función determina si se debe llamar al servicio OpenAI de Azure o al servicio OpenAI comprobando las variables de entorno. Si hay una clave, un punto de conexión y un modelo disponibles en las variables de entorno, se llama a Azure OpenAI; de lo contrario, se llama a OpenAI.function callOpenAI(systemPrompt: string, userPrompt: string, temperature = 0, useBYOD = false) { const isAzureOpenAI = OPENAI_API_KEY && OPENAI_ENDPOINT && OPENAI_MODEL; if (isAzureOpenAI) { if (useBYOD) { return getAzureOpenAIBYODCompletion(systemPrompt, userPrompt, temperature); } return getAzureOpenAICompletion(systemPrompt, userPrompt, temperature); } return getOpenAICompletion(systemPrompt, userPrompt, temperature); }
Nota:
Aunque nos centraremos en Azure OpenAI en este tutorial, si solo proporciona un
OPENAI_API_KEY
valor en el archivo .env , la aplicación usará OpenAI en su lugar. Si decide usar OpenAI en lugar de Azure OpenAI, puede ver resultados diferentes en algunos casos.Busque la
getAzureOpenAICompletion()
función .async function getAzureOpenAICompletion(systemPrompt: string, userPrompt: string, temperature: number): Promise<string> { const completion = await createAzureOpenAICompletion(systemPrompt, userPrompt, temperature); let content = completion.choices[0]?.message?.content?.trim() ?? ''; console.log('Azure OpenAI Output: \n', content); if (content && content.includes('{') && content.includes('}')) { content = extractJson(content); } return content; }
Esta función hace lo siguiente:
Parámetros:
systemPrompt
,userPrompt
ytemperature
son los parámetros principales.systemPrompt
: informa al modelo de Azure OpenAI de su rol y de las reglas que se deben seguir.userPrompt
: contiene la información proporcionada por el usuario, como la entrada de lenguaje natural o las reglas para generar la salida.temperature
: dicta el nivel de creatividad de la respuesta del modelo. Un valor más alto da como resultado salidas más creativas.
Generación de finalización:
- La función llama a
createAzureOpenAICompletion()
consystemPrompt
,userPrompt
ytemperature
para generar una finalización. - Extrae el contenido de la primera opción en la finalización, recortando cualquier espacio en blanco adicional.
- Si el contenido contiene estructuras similares a JSON (indicadas por la presencia de
{
y}
), extrae el contenido JSON.
- La función llama a
Registro y valor devuelto:
- La función registra la salida de Azure OpenAI en la consola.
- Devuelve el contenido procesado como una cadena.
Busque la
createAzureOpenAICompletion()
función .async function createAzureOpenAICompletion(systemPrompt: string, userPrompt: string, temperature: number, dataSources?: any[]): Promise<any> { const baseEnvVars = ['OPENAI_API_KEY', 'OPENAI_ENDPOINT', 'OPENAI_MODEL']; const byodEnvVars = ['AZURE_AI_SEARCH_ENDPOINT', 'AZURE_AI_SEARCH_KEY', 'AZURE_AI_SEARCH_INDEX']; const requiredEnvVars = dataSources ? [...baseEnvVars, ...byodEnvVars] : baseEnvVars; checkRequiredEnvVars(requiredEnvVars); const config = { apiKey: OPENAI_API_KEY, endpoint: OPENAI_ENDPOINT, apiVersion: OPENAI_API_VERSION, deployment: OPENAI_MODEL }; const aoai = new AzureOpenAI(config); const completion = await aoai.chat.completions.create({ model: OPENAI_MODEL, // gpt-4o, gpt-3.5-turbo, etc. Pulled from .env file max_tokens: 1024, temperature, response_format: { type: "json_object", }, messages: [ { role: 'system', content: systemPrompt }, { role: 'user', content: userPrompt } ], // @ts-expect-error data_sources is a custom property used with the "Azure Add Your Data" feature data_sources: dataSources }); return completion; } function checkRequiredEnvVars(requiredEnvVars: string[]) { for (const envVar of requiredEnvVars) { if (!process.env[envVar]) { throw new Error(`Missing ${envVar} in environment variables.`); } } }
Esta función hace lo siguiente:
Parámetros:
systemPrompt
,userPrompt
ytemperature
son los parámetros principales descritos anteriormente.- Un parámetro opcional
dataSources
admite la característica "Azure Bring Your Own Data", que se tratará más adelante en este tutorial.
Comprobación de variables de entorno:
- La función comprueba la presencia de variables de entorno esenciales, lo que produce un error si falta alguno.
Objeto de configuración:
- Un
config
objeto se crea mediante valores del.env
archivo (OPENAI_API_KEY
,OPENAI_ENDPOINT
,OPENAI_API_VERSION
,OPENAI_MODEL
). Estos valores se usan para construir la dirección URL para llamar a Azure OpenAI.
- Un
Instancia de AzureOpenAI:
- Se crea una instancia de
AzureOpenAI
mediante el objetoconfig
. ElAzureOpenAI
símbolo forma parte delopenai
paquete, que se debe importar en la parte superior del archivo.
- Se crea una instancia de
Generación de una finalización:
- Se llama a la
chat.completions.create()
función con las siguientes propiedades:model
: especifica el modelo GPT (por ejemplo, gpt-4o, gpt-3.5-turbo) tal como se define en el.env
archivo.max_tokens
: define el número máximo de tokens para la finalización.temperature
: establece la temperatura de muestreo. Los valores más altos (por ejemplo, 0,9) producen respuestas más creativas, mientras que los valores más bajos (por ejemplo, 0) producen respuestas más deterministas.response_format
: define el formato de respuesta. Aquí, se establece para devolver un objeto JSON. Puede encontrar más detalles sobre el modo JSON en la documentación de referencia de Azure OpenAI.messages
: contiene los mensajes para generar finalizaciones de chat. En este ejemplo se incluyen dos mensajes: uno del sistema (definir el comportamiento y las reglas) y otro del usuario (que contiene el texto del mensaje).
- Se llama a la
Valor de retorno:
- La función devuelve el objeto de finalización generado por Azure OpenAI.
Comente las líneas siguientes de la
getSQLFromNLP()
función:// if (isProhibitedQuery(queryData.sql)) { // queryData.sql = ''; // }
Guarde openAI.ts. El servidor de API recompilará automáticamente el código typeScript y reiniciará el servidor.
Vuelva al explorador y escriba Seleccionar todos los nombres de tabla de la base de datos en la entrada Consulta personalizada. Seleccione Ejecutar consulta. ¿Se muestran los nombres de tabla?
Vuelva a la
getSQLFromNLP()
función en el servidor o openAI.ts y agregue la siguiente regla a laRules:
sección del símbolo del sistema y, a continuación, guarde el archivo.- Do not allow the SELECT query to return table names, function names, or procedure names.
Vuelva al explorador y realice las siguientes tareas:
- Escriba Seleccionar todos los nombres de tabla de la base de datos en la entrada Consulta personalizada. Seleccione Ejecutar consulta. ¿Se muestran los nombres de tabla?
- Escriba Seleccionar todos los nombres de función de la base de datos. En la entrada Consulta personalizada y vuelva a seleccionar Ejecutar consulta . ¿Se muestran los nombres de función?
PREGUNTA: ¿Un modelo siempre seguirá las reglas que defina en el mensaje?
RESPUESTA: ¡No! Es importante tener en cuenta que los modelos de OpenAI pueden devolver resultados inesperados en ocasiones que no coincidan con las reglas que haya definido. Es importante planearlo en el código.
Vuelva al servidor o openAI.ts y busque la
isProhibitedQuery()
función. Este es un ejemplo de código posterior al procesamiento que se puede ejecutar después de que Azure OpenAI devuelva resultados. Observe que establece lasql
propiedad en una cadena vacía si se devuelven palabras clave prohibidas en la consulta SQL generada. Esto garantiza que, si se devuelven resultados inesperados desde Azure OpenAI, la consulta SQL no se ejecutará en la base de datos.function isProhibitedQuery(query: string): boolean { if (!query) return false; const prohibitedKeywords = [ 'insert', 'update', 'delete', 'drop', 'truncate', 'alter', 'create', 'replace', 'information_schema', 'pg_catalog', 'pg_tables', 'pg_proc', 'pg_namespace', 'pg_class', 'table_schema', 'table_name', 'column_name', 'column_default', 'is_nullable', 'data_type', 'udt_name', 'character_maximum_length', 'numeric_precision', 'numeric_scale', 'datetime_precision', 'interval_type', 'collation_name', 'grant', 'revoke', 'rollback', 'commit', 'savepoint', 'vacuum', 'analyze' ]; const queryLower = query.toLowerCase(); return prohibitedKeywords.some(keyword => queryLower.includes(keyword)); }
Nota:
Es importante tener en cuenta que esto es solo código de demostración. Puede haber otras palabras clave prohibidas necesarias para cubrir los casos de uso específicos si decide convertir lenguaje natural a SQL. Se trata de una característica que debe planear y usar con cuidado para asegurarse de que solo se devuelven y ejecutan consultas SQL válidas en la base de datos. Además de las palabras clave prohibidas, también tendrá que tener en cuenta la seguridad.
Vuelva al servidor o openAI.ts y quite la marca de comentario del código siguiente en la
getSQLFromNLP()
función . Guarde el archivo.if (isProhibitedQuery(queryData.sql)) { queryData.sql = ''; }
Quite la siguiente regla de
systemPrompt
y guarde el archivo.- Do not allow the SELECT query to return table names, function names, or procedure names.
Vuelva al explorador, escriba Seleccionar todos los nombres de tabla de la base de datos en la entrada Consulta personalizada de nuevo y seleccione el botón Ejecutar consulta .
¿Se muestran los resultados de la tabla? Incluso sin la regla en vigor, el
isProhibitedQuery()
código posterior al procesamiento prohíbe que ese tipo de consulta se ejecute en la base de datos.Como se ha explicado anteriormente, la integración del lenguaje natural en SQL en aplicaciones de línea de negocio puede ser bastante beneficiosa para los usuarios, pero viene con su propio conjunto de consideraciones.
Ventajas:
Facilidad de uso: esta característica puede hacer que la interacción de la base de datos sea más accesible para los usuarios sin conocimientos técnicos, lo que reduce la necesidad de conocimientos de SQL y puede acelerar las operaciones.
Mayor productividad: los analistas de negocios, los vendedores, los ejecutivos y otros usuarios no técnicos pueden recuperar información valiosa de las bases de datos sin tener que confiar en expertos técnicos, lo que aumenta la eficacia.
Aplicación amplia: mediante el uso de modelos de lenguaje avanzados, las aplicaciones se pueden diseñar para satisfacer una amplia gama de usuarios y casos de uso.
Consideraciones:
Seguridad: una de las mayores preocupaciones es la seguridad. Si los usuarios pueden interactuar con bases de datos mediante lenguaje natural, debe haber medidas de seguridad sólidas para evitar el acceso no autorizado o las consultas malintencionadas. Puede considerar la posibilidad de implementar un modo de solo lectura para evitar que los usuarios modifiquen los datos.
Privacidad de los datos: es posible que ciertos datos sean confidenciales y no deben ser fácilmente accesibles, por lo que deberá asegurarse de que están en vigor las medidas de seguridad adecuadas y los permisos de usuario.
Precisión: aunque el procesamiento del lenguaje natural ha mejorado significativamente, no es perfecto. La interpretación incorrecta de las consultas de usuario podría provocar resultados inexactos o un comportamiento inesperado. Deberá planear la forma en que se controlarán los resultados inesperados.
Eficiencia: no hay ninguna garantía de que el CÓDIGO SQL devuelto desde una consulta de lenguaje natural sea eficaz. En algunos casos, es posible que se requieran llamadas adicionales a Azure OpenAI si las reglas posteriores al procesamiento detectan problemas con las consultas SQL.
Entrenamiento y adaptación del usuario: los usuarios deben entrenarse para formular correctamente sus consultas. Aunque es más fácil que aprender SQL, todavía puede haber una curva de aprendizaje implicada.
Algunos puntos finales que se deben tener en cuenta antes de pasar al siguiente ejercicio:
- Recuerde que aquí se aplica "Just because you can't mean you should" (Solo porque no se puede decir que deberías) aquí. Use precaución extrema y planificación cuidadosa antes de integrar el lenguaje natural en SQL en una aplicación. Es importante comprender los posibles riesgos y planearlos.
- Antes de usar este tipo de tecnología, analice posibles escenarios con su equipo, administradores de bases de datos, equipo de seguridad, partes interesadas y cualquier otra parte pertinente para asegurarse de que es adecuado para su organización. Es importante analizar si el lenguaje natural para SQL cumple los requisitos de seguridad, privacidad y cualquier otro requisito que pueda tener su organización.
- La seguridad debe ser una preocupación principal e integrada en el proceso de planeación, desarrollo e implementación.
- Aunque el lenguaje natural para SQL puede ser muy eficaz, la planeación cuidadosa debe ir a ella para asegurarse de que las indicaciones tienen reglas necesarias y que se incluye la funcionalidad posterior al procesamiento. Planee tiempo adicional para implementar y probar este tipo de funcionalidad y tener en cuenta escenarios en los que se devuelven resultados inesperados.
- Con Azure OpenAI, los clientes obtienen las funcionalidades de seguridad de Microsoft Azure mientras ejecutan los mismos modelos que OpenAI. Azure OpenAI ofrece redes privadas, disponibilidad regional y filtrado de contenido de IA responsable. Obtenga más información sobre los datos, la privacidad y la seguridad del servicio Azure OpenAI.
Ahora ha visto cómo usar Azure OpenAI para convertir lenguaje natural en SQL y ha aprendido sobre las ventajas y desventajas de implementar este tipo de funcionalidad. En el ejercicio siguiente, aprenderá cómo se pueden generar mensajes de correo electrónico y SMS mediante Azure OpenAI.
IA: Generación de finalizaciones
Además de la característica de lenguaje natural a SQL, también puede usar el servicio Azure OpenAI para generar mensajes de correo electrónico y SMS para mejorar la productividad del usuario y simplificar los flujos de trabajo de comunicación. Al usar las funcionalidades de generación de lenguajes de Azure OpenAI, los usuarios pueden definir reglas específicas, como "El pedido se retrasa 5 días" y el sistema generará automáticamente mensajes sms y correo electrónico adecuados contextualmente en función de esas reglas.
Esta funcionalidad sirve como un punto de partida para los usuarios, lo que les proporciona una plantilla de mensajes cuidadosamente diseñada que pueden personalizar fácilmente antes de enviarlos. El resultado es una reducción significativa del tiempo y el esfuerzo necesarios para redactar mensajes, lo que permite a los usuarios centrarse en otras tareas importantes. Además, la tecnología de generación de lenguajes de Azure OpenAI se puede integrar en flujos de trabajo de automatización, lo que permite que el sistema genere y envíe mensajes de forma autónoma en respuesta a desencadenadores predefinidos. Este nivel de automatización no solo acelera los procesos de comunicación, sino que también garantiza una mensajería coherente y precisa en varios escenarios.
En este ejercicio, aprenderá a:
- Experimente con mensajes diferentes.
- Use avisos para generar finalizaciones de mensajes de correo electrónico y SMS.
- Explore el código que habilita las finalizaciones de inteligencia artificial.
- Obtenga información sobre la importancia de la ingeniería de avisos e incluir reglas en las solicitudes.
Empecemos experimentando con diferentes reglas que se pueden usar para generar mensajes sms y de correo electrónico.
Uso de la característica de finalizaciones de IA
En un ejercicio anterior ha iniciado la base de datos, las API y la aplicación. También ha actualizado el
.env
archivo. Si no ha completado esos pasos, siga las instrucciones al final del ejercicio antes de continuar.Vuelva al explorador (http://localhost:4200) y seleccione Ponerse en contacto con el cliente en cualquier fila del datagrid seguido de Correo electrónico o cliente sms para ir a la pantalla Generador de mensajes.
Esto usa Azure OpenAI para convertir reglas de mensajes que defina en mensajes de correo electrónico o SMS. Realice las siguientes tareas:
Escriba una regla como Order se retrasa 5 días en la entrada y seleccione el botón Generar mensajes de correo electrónico o SMS.
Verá un asunto y un cuerpo generados para el correo electrónico y un mensaje corto generado para el SMS.
Nota:
Dado que Azure Communication Services aún no está habilitado, no podrá enviar el correo electrónico ni los mensajes SMS.
Cierre la ventana de diálogo correo electrónico/SMS en el explorador. Ahora que ha visto esta característica en acción, vamos a examinar cómo se implementa.
Exploración del código de finalizaciones de IA
Sugerencia
Si usa Visual Studio Code, puede abrir archivos directamente seleccionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
A continuación, escriba el nombre del archivo que desea abrir.
Abra el archivo server/apiRoutes.ts y busque la
completeEmailSmsMessages
ruta. La parte front-end de la aplicación llama a esta API cuando se selecciona el botón Generar mensajes de correo electrónico o SMS. Recupera los valores de solicitud de usuario, empresa y nombre de contacto del cuerpo y los pasa a lacompleteEmailSMSMessages()
función en el archivo de servidor o openAI.ts . A continuación, los resultados se devuelven al cliente.router.post('/completeEmailSmsMessages', async (req, res) => { const { prompt, company, contactName } = req.body; if (!prompt || !company || !contactName) { return res.status(400).json({ status: false, error: 'The prompt, company, and contactName parameters must be provided.' }); } let result; try { // Call OpenAI to get the email and SMS message completions result = await completeEmailSMSMessages(prompt, company, contactName); } catch (e: unknown) { console.error('Error parsing JSON:', e); } res.json(result); });
Abra el archivo server/openAI.ts y busque la
completeEmailSMSMessages()
función .async function completeEmailSMSMessages(prompt: string, company: string, contactName: string) { console.log('Inputs:', prompt, company, contactName); const systemPrompt = ` Assistant is a bot designed to help users create email and SMS messages from data and return a JSON object with the email and SMS message information in it. Rules: - Generate a subject line for the email message. - Use the User Rules to generate the messages. - All messages should have a friendly tone and never use inappropriate language. - SMS messages should be in plain text format and NO MORE than 160 characters. - Start the message with "Hi <Contact Name>,\n\n". Contact Name can be found in the user prompt. - Add carriage returns to the email message to make it easier to read. - End with a signature line that says "Sincerely,\nCustomer Service". - Return a valid JSON object with the emailSubject, emailBody, and SMS message values in it: { "emailSubject": "", "emailBody": "", "sms": "" } - The sms property value should be in plain text format and NO MORE than 160 characters. `; const userPrompt = ` User Rules: ${prompt} Contact Name: ${contactName} `; let content: EmailSmsResponse = { status: true, email: '', sms: '', error: '' }; let results = ''; try { results = await callOpenAI(systemPrompt, userPrompt, 0.5); if (results) { const parsedResults = JSON.parse(results); content = { ...content, ...parsedResults, status: true }; } } catch (e) { console.log(e); content.status = false; content.error = results; } return content; }
Esta función tiene las siguientes características:
systemPrompt
se usa para definir que se requiere un asistente de inteligencia artificial capaz de generar mensajes de correo electrónico y SMS. tambiénsystemPrompt
incluye:- Reglas para que el asistente siga para controlar el tono de los mensajes, el formato de inicio y finalización, la longitud máxima de los mensajes SMS, etc.
- Información sobre los datos que se deben incluir en la respuesta: un objeto JSON en este caso.
userPrompt
se usa para definir las reglas y el nombre de contacto que el usuario final desea incluir a medida que se generan los mensajes sms y de correo electrónico. La regla Order se retrasa 5 días que escribió anteriormente se incluye enuserPrompt
.- La función llama a la
callOpenAI()
función que ha explorado anteriormente para generar las finalizaciones de correo electrónico y SMS.
Vuelva al explorador, actualice la página y seleccione Ponerse en contacto con el cliente en cualquier fila seguida de Correo electrónico o cliente sms para volver a la pantalla Generador de mensajes.
Escriba las reglas siguientes en la entrada Generador de mensajes:
- El pedido está por adelantado.
- Dile al cliente que nunca vuelva a pedirnos, no queremos su negocio.
Seleccione Generar mensajes de correo electrónico o SMS y anote el mensaje. La
All messages should have a friendly tone and never use inappropriate language.
regla del símbolo del sistema reemplaza la regla negativa en el mensaje del usuario.Vuelva al servidor o openAI.ts* en el editor y quite la
All messages should have a friendly tone and never use inappropriate language.
regla del símbolo del sistema en lacompleteEmailSMSMessages()
función. Guarde el archivo.Vuelva al generador de mensajes de correo electrónico o SMS en el explorador y vuelva a ejecutar las mismas reglas:
- El pedido está por adelantado.
- Dile al cliente que nunca vuelva a pedirnos, no queremos su negocio.
Seleccione Generar mensajes de correo electrónico o SMS y observe el mensaje que se devuelve.
¿Qué ocurre en estos escenarios? Al usar Azure OpenAI, se puede aplicar el filtrado de contenido para asegurarse de que siempre se usa el idioma adecuado. Si usa OpenAI, la regla definida en el símbolo del sistema se usa para asegurarse de que el mensaje devuelto es adecuado.
Nota:
Esto ilustra la importancia de diseñar las indicaciones con la información y las reglas adecuadas para asegurarse de que se devuelven los resultados adecuados. Obtenga más información sobre este proceso en la documentación introducción a la ingeniería de solicitud.
Deshaga los cambios realizados
systemPrompt
en encompleteEmailSMSMessages()
, guarde el archivo y vuelva a ejecutarlo de nuevo, pero use solo laOrder is ahead of schedule.
regla (no incluya la regla negativa). Esta vez debería ver los mensajes de correo electrónico y SMS devueltos según lo previsto.Algunos puntos finales que se deben tener en cuenta antes de pasar al siguiente ejercicio:
- Es importante tener un humano en el bucle para revisar los mensajes generados. En este ejemplo, las finalizaciones de Azure OpenAI devuelven mensajes de correo electrónico y SMS sugeridos, pero el usuario puede invalidar los antes de enviarlos. Si planea automatizar correos electrónicos, tener algún tipo de proceso de revisión humana para asegurarse de que los mensajes aprobados se envían es importante. Vea la inteligencia artificial como copiloto, no un piloto automático.
- Las finalizaciones solo serán tan buenas como las reglas que agregue al símbolo del sistema. Dedique tiempo a probar las solicitudes y las finalizaciones que se devuelven. Considere la posibilidad de usar el flujo de mensajes para crear una solución completa que simplifica la creación de prototipos, la experimentación, la iteración e implementación de aplicaciones de inteligencia artificial. Invite también a otras partes interesadas del proyecto a revisar las finalizaciones.
- Es posible que tenga que incluir código posterior al procesamiento para asegurarse de que los resultados inesperados se controlan correctamente.
- Use avisos del sistema para definir las reglas e información que debe seguir el asistente de IA. Use las indicaciones del usuario para definir las reglas y la información que el usuario final desea incluir en las finalizaciones.
IA: Azure OpenAI en los datos
La integración de azure OpenAI Natural Language Processing (NLP) y las funcionalidades de finalización ofrecen un potencial significativo para mejorar la productividad del usuario. Al aprovechar las indicaciones y reglas adecuadas, un asistente de IA puede generar eficazmente diversas formas de comunicación, como mensajes de correo electrónico, mensajes SMS, etc. Esta funcionalidad conduce a un aumento de la eficiencia del usuario y a flujos de trabajo optimizados.
Aunque esta característica es bastante eficaz por sí sola, puede haber casos en los que los usuarios necesiten generar finalizaciones basadas en los datos personalizados de su empresa. Por ejemplo, es posible que tenga una colección de manuales de producto que pueden resultar difíciles para que los usuarios naveguen cuando ayuden a los clientes con problemas de instalación. Como alternativa, puede mantener un conjunto completo de preguntas más frecuentes (P+F) relacionados con los beneficios sanitarios que pueden resultar difíciles para que los usuarios lean y obtengan las respuestas que necesitan. En estos casos y muchos otros, azure OpenAI Service le permite aprovechar sus propios datos para generar finalizaciones, lo que garantiza una respuesta más adaptada y contextualmente precisa a las preguntas del usuario.
Esta es una introducción rápida a cómo funciona la característica "traiga sus propios datos" en la documentación de Azure OpenAI.
Nota:
Una de las características clave de Azure OpenAI en los datos es su capacidad de recuperar y usar datos de forma que mejore la salida del modelo. Azure OpenAI en los datos, junto con Azure AI Search, determina qué datos se van a recuperar del origen de datos designado en función de la entrada del usuario y del historial de conversaciones proporcionado. A continuación, estos datos se aumentan y se vuelven a enviar como una solicitud al modelo de OpenAI, con la información recuperada que se anexa a la solicitud original. Aunque los datos recuperados se anexan a la solicitud, el modelo sigue procesando la entrada resultante como cualquier otra solicitud. Una vez que se han recuperado los datos y la solicitud se ha enviado al modelo, el modelo usa esta información para proporcionar una finalización.
En este ejercicio, aprenderá a:
- Cree un origen de datos personalizado mediante Azure AI Studio.
- Implemente un modelo de inserción mediante Azure AI Studio.
- Cargar documentos personalizados.
- Inicie una sesión de chat en el área de juegos de chat para experimentar con la generación de finalizaciones basadas en sus propios datos.
- Explore el código que usa Azure AI Search y Azure OpenAI para generar finalizaciones basadas en sus propios datos.
Para empezar, implemente un modelo de inserción y agregue un origen de datos personalizado en Azure AI Studio.
Adición de un origen de datos personalizado a Azure AI Studio
Vaya a Azure OpenAI Studio e inicie sesión con credenciales que tengan acceso al recurso de Azure OpenAI.
Seleccione Implementaciones en el menú de navegación.
Seleccione Seleccionar Implementar modelo -->Deploy base model (Implementar modelo base) en la barra de herramientas.
Seleccione el modelo text-embeding-ada-002 en la lista de modelos y seleccione Confirmar.
Selecciona las opciones siguientes:
- Nombre de implementación: inserción de texto-ada-002
- Versión del modelo: valor predeterminado
- Tipo de implementación: Estándar
- Establezca el valor tokens por límite de velocidad de minutos (miles) en 120 000
- Filtro de contenido: DefaultV2
- Habilitar comillas dinámicas: Habilitado
Seleccione el botón Implementar.
Una vez creado el modelo, seleccione Inicio en el menú de navegación para ir a la pantalla de bienvenida.
Busque el icono Bring your own data (Traer sus propios datos ) en la pantalla de bienvenida y seleccione Pruébelo ahora.
Seleccione Agregar los datos seguidos de Agregar un origen de datos.
En la lista desplegable Seleccionar origen de datos , seleccione Cargar archivos.
En la lista desplegable Seleccionar recurso de Azure Blob Storage, seleccione Crear un nuevo recurso de Azure Blob Storage.
Seleccione la suscripción de Azure en la lista desplegable Suscripción .
En la lista desplegable Seleccionar recurso de Azure Blob Storage, seleccione Crear un nuevo recurso de Azure Blob Storage.
Esto le llevará a Azure Portal, donde puede realizar las siguientes tareas:
- Escriba un nombre único para la cuenta de almacenamiento, como byodstorage[Su apellido].
- Seleccione una región cercana a su ubicación.
- Seleccione Revisar seguido de Crear.
Una vez creado el recurso de Blob Storage, vuelva al cuadro de diálogo de Azure AI Studio y seleccione el recurso de Blob Storage recién creado en la lista desplegable Seleccionar recurso de Azure Blob Storage. Si no lo ve en la lista, seleccione el icono de actualización situado junto a la lista desplegable.
Es necesario activar el uso compartido de recursos entre orígenes (CORS) para que se pueda acceder a la cuenta de almacenamiento. Seleccione Activar CORS en el cuadro de diálogo Azure AI Studio.
En la lista desplegable Seleccionar recurso de Azure AI Search, seleccione Crear un nuevo recurso de Azure AI Search.
Esto le llevará de vuelta a Azure Portal, donde puede realizar las siguientes tareas:
- Escriba un nombre único para el recurso de búsqueda de IA, como byodsearch-[Su apellido].
- Seleccione una región cercana a su ubicación.
- En la sección Plan de tarifa , seleccione Cambiar plan de tarifa y seleccione Básico seguido de Seleccionar. No se admite el nivel gratis, por lo que limpiará el recurso de búsqueda de IA al final de este tutorial.
- Seleccione Revisar seguido de Crear.
Una vez creado el recurso ai Search, vaya a la página Información general del recurso y copie el valor de dirección URL en un archivo local.
Seleccione Configuración - ->Claves en el menú de navegación.
En la página Control de acceso de API, seleccione Ambos para habilitar el acceso al servicio mediante identidad administrada o mediante una clave. Seleccione Sí cuando se pida confirmación.
Nota:
Aunque usaremos una clave de API en este ejercicio, ya que agregar asignaciones de roles puede tardar hasta 10 minutos, con un poco de esfuerzo adicional, puede habilitar una identidad administrada asignada por el sistema para acceder al servicio de forma más segura.
Seleccione Claves en el menú de navegación izquierdo y copie el valor de clave de administrador principal en un archivo local. Necesitará los valores de dirección URL y clave más adelante en el ejercicio.
Seleccione Settings --Semantic ranker (Configuración:> clasificador semántico) en el menú de navegación y asegúrese de que Está seleccionado Gratis.
Nota:
Para comprobar si el clasificador semántico está disponible en una región específica, consulte la página Productos disponibles por región en el sitio web de Azure para ver si la región aparece.
Vuelva al cuadro de diálogo Agregar datos de Azure AI Studio y seleccione el recurso de búsqueda recién creado en la lista desplegable Seleccionar recurso de Azure AI Search. Si no lo ve en la lista, seleccione el icono de actualización situado junto a la lista desplegable.
Escriba un valor de byod-search-index para el valor Escriba el nombre del índice.
Active la casilla Agregar búsqueda vectorial a este recurso de búsqueda.
En la lista desplegable Seleccionar un modelo de inserción, seleccione el modelo text-embeding-ada-002 que creó anteriormente.
En el cuadro de diálogo Cargar archivos , seleccione Examinar un archivo.
Vaya a la carpeta de documentos de cliente del proyecto (ubicada en la raíz del proyecto) y seleccione los siguientes archivos:
- Instructions.docx de instalación de Clock A102
- FAQs.docx de empresa
Nota:
Esta característica admite actualmente los siguientes formatos de archivo para la creación de índices locales: .txt, .md, .html, .pdf, .docx y .pptx.
Seleccione Upload files (Cargar archivos). Los archivos se cargarán en un contenedor fileupload-byod-search-index en el recurso de blob storage que creó anteriormente.
Seleccione Siguiente para ir al cuadro de diálogo Administración de datos.
En la lista desplegable Tipo de búsqueda, seleccione Híbrido + semántico.
Nota:
Esta opción proporciona compatibilidad con la búsqueda de palabras clave y vectores. Una vez que se devuelven los resultados, se aplica un proceso de clasificación secundario al conjunto de resultados mediante modelos de aprendizaje profundo que mejora la relevancia de búsqueda para el usuario. Para más información sobre la búsqueda semántica, consulte la documentación búsqueda semántica en Azure AI Search .
Asegúrese de que el valor Seleccionar un tamaño está establecido en 1024.
Seleccione Siguiente.
Para el tipo de autenticación de recursos de Azure, seleccione Clave de API. Obtenga más información sobre cómo seleccionar el tipo de autenticación correcto en la documentación de autenticación de Azure AI Search.
Seleccione Siguiente.
Revise los detalles y seleccione Guardar y cerrar.
Ahora que se han cargado los datos personalizados, los datos se indexarán y estarán disponibles para usarlos en el área de juegos de chat. Este proceso puede tardar unos minutos. Una vez completado, continúe con la sección siguiente.
Uso del origen de datos personalizado en el área de juegos de chat
Busque la sección Sesión de chat de la página en Azure OpenAI Studio y escriba la siguiente consulta de usuario:
What safety rules are required to install a clock?
Después de enviar la consulta de usuario, debería ver un resultado similar al siguiente:
Expanda la sección 1 referencias en la respuesta del chat y observe que aparece el archivo de instalación del reloj A102 Instructions.docx y que puede seleccionarlo para ver el documento.
Escriba el siguiente mensaje de usuario:
What should I do to mount the clock on the wall?
Debería ver un resultado similar al siguiente:
Ahora vamos a experimentar con el documento preguntas más frecuentes de la empresa. Escriba el texto siguiente en el campo Consulta de usuario:
What is the company's policy on vacation time?
Debería ver que no se encontró información para esa solicitud.
Escriba el texto siguiente en el campo Consulta de usuario:
How should I handle refund requests?
Debería ver un resultado similar al siguiente:
Expanda la sección 1 referencias en la respuesta del chat y observe que aparece el archivo FAQs.docx empresa y que puede seleccionarlo para ver el documento.
Seleccione Ver código en la barra de herramientas del área de juegos de chat.
Tenga en cuenta que puede cambiar entre distintos idiomas, ver el punto de conexión y acceder a la clave del punto de conexión. Cierre la ventana de diálogo Código de ejemplo.
Active el botón de alternancia Mostrar JSON sin formato encima de los mensajes de chat. Observe que la sesión de chat comienza con un mensaje similar al siguiente:
{ "role": "system", "content": "You are an AI assistant that helps people find information." }
Ahora que ha creado un origen de datos personalizado y ha experimentado con él en el área de juegos de chat, veamos cómo puede usarlo en la aplicación del proyecto.
Uso de la característica Bring Your Own Data en la aplicación
Vuelva al proyecto en VS Code y abra el archivo .env . Actualice los valores siguientes con el punto de conexión, la clave y el nombre del índice de AI Services. Copió el punto de conexión y la clave en un archivo local anteriormente en este ejercicio.
AZURE_AI_SEARCH_ENDPOINT=<AI_SERVICES_ENDPOINT_VALUE> AZURE_AI_SEARCH_KEY=<AI_SERVICES_KEY_VALUE> AZURE_AI_SEARCH_INDEX=byod-search-index
En un ejercicio anterior ha iniciado la base de datos, las API y la aplicación. También ha actualizado el
.env
archivo. Si no ha completado esos pasos, siga las instrucciones al final del ejercicio anterior antes de continuar.Una vez que la aplicación se haya cargado en el explorador, seleccione el icono Ayuda de chat en la esquina superior derecha de la aplicación.
El texto siguiente debería aparecer en el cuadro de diálogo de chat:
How should I handle a company refund request?
Seleccione el botón Obtener ayuda . Debería ver los resultados devueltos en el documento company FAQs.docx que cargó anteriormente en Azure OpenAI Studio. Si desea leer el documento, puede encontrarlo en la carpeta de documentos del cliente en la raíz del proyecto.
Cambie el texto a lo siguiente y seleccione el botón Obtener ayuda :
What safety rules are required to install a clock?
Debería ver los resultados devueltos en el documento De instalación de Clock A102 Instructions.docx que cargó anteriormente en Azure OpenAI Studio. Este documento también está disponible en la carpeta de documentos del cliente en la raíz del proyecto.
Exploración del código
Sugerencia
Si usa Visual Studio Code, puede abrir archivos directamente seleccionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
A continuación, escriba el nombre del archivo que desea abrir.
Vuelva al código fuente del proyecto en Visual Studio Code.
Abra el archivo server/apiRoutes.ts y busque la
completeBYOD
ruta. Se llama a esta API cuando se selecciona el botón Obtener ayuda en el cuadro de diálogo Ayuda de chat. Recupera el mensaje del usuario del cuerpo de la solicitud y lo pasa a lacompleteBYOD()
función en el archivo server/openAI.ts . A continuación, los resultados se devuelven al cliente.router.post('/completeBYOD', async (req, res) => { const { prompt } = req.body; if (!prompt) { return res.status(400).json({ status: false, error: 'The prompt parameter must be provided.' }); } let result; try { // Call OpenAI to get custom "bring your own data" completion result = await completeBYOD(prompt); } catch (e: unknown) { console.error('Error parsing JSON:', e); } res.json(result); });
Abra el archivo server/openAI.ts y busque la
completeBYOD()
función .async function completeBYOD(userPrompt: string): Promise<string> { const systemPrompt = 'You are an AI assistant that helps people find information in documents.'; return await callOpenAI(systemPrompt, userPrompt, 0, true); }
Esta función tiene las siguientes características:
- El
userPrompt
parámetro contiene la información que el usuario ha escrito en el cuadro de diálogo de ayuda de chat. - la
systemPrompt
variable define que se usará un asistente de IA diseñado para ayudar a las personas a encontrar información. callOpenAI()
se usa para llamar a la API de Azure OpenAI y devolver los resultados. Pasa lossystemPrompt
valores yuserPrompt
, así como los parámetros siguientes:temperature
- La cantidad de creatividad que se va a incluir en la respuesta. El usuario necesita respuestas coherentes (menos creativas) en este caso, por lo que el valor se establece en 0.useBYOD
: valor booleano que indica si se va a usar o no AI Search junto con Azure OpenAI. En este caso, se establecetrue
en para que se use la funcionalidad de búsqueda de IA.
- El
La
callOpenAI()
función acepta unuseBYOD
parámetro que se usa para determinar a qué función openAI llamar. En este caso, estableceuseBYOD
en para que se llame atrue
lagetAzureOpenAIBYODCompletion()
función .function callOpenAI(systemPrompt: string, userPrompt: string, temperature = 0, useBYOD = false) { const isAzureOpenAI = OPENAI_API_KEY && OPENAI_ENDPOINT && OPENAI_MODEL; if (isAzureOpenAI) { if (useBYOD) { return getAzureOpenAIBYODCompletion(systemPrompt, userPrompt, temperature); } return getAzureOpenAICompletion(systemPrompt, userPrompt, temperature); } return getOpenAICompletion(systemPrompt, userPrompt, temperature); }
Busque la
getAzureOpenAIBYODCompletion()
función en el servidor o openAI.ts. Es bastante similar a lagetAzureOpenAICompletion()
función que ha examinado anteriormente, pero se muestra como una función independiente para resaltar algunas diferencias clave que son exclusivas del escenario "Azure OpenAI en los datos" disponible en Azure OpenAI.async function getAzureOpenAIBYODCompletion(systemPrompt: string, userPrompt: string, temperature: number): Promise<string> { const dataSources = [ { type: 'azure_search', parameters: { authentication: { type: 'api_key', key: AZURE_AI_SEARCH_KEY }, endpoint: AZURE_AI_SEARCH_ENDPOINT, index_name: AZURE_AI_SEARCH_INDEX } } ]; const completion = await createAzureOpenAICompletion(systemPrompt, userPrompt, temperature, dataSources) as AzureOpenAIYourDataResponse; console.log('Azure OpenAI Add Your Own Data Output: \n', completion.choices[0]?.message); for (let citation of completion.choices[0]?.message?.context?.citations ?? []) { console.log('Citation Path:', citation.filepath); } return completion.choices[0]?.message?.content?.trim() ?? ''; }
Observe la siguiente funcionalidad en la
getAzureOpenAIBYODCompletion()
función :- Se crea una
dataSources
propiedad que contiene los valores ,endpoint
yindex_name
delkey
recurso de búsqueda de IA que se agregaron al.env
archivo anteriormente en este ejercicio. - Se llama a la
createAzureOpenAICompletion()
función con lossystemPrompt
valores ,userPrompt
,temperature
ydataSources
. Esta función se usa para llamar a la API de Azure OpenAI y devolver los resultados. - Una vez que se devuelve la respuesta, las citas del documento se registran en la consola. A continuación, el contenido del mensaje de finalización se devuelve al autor de la llamada.
- Se crea una
Algunos puntos finales que se deben tener en cuenta antes de pasar al siguiente ejercicio:
- La aplicación de ejemplo usa un único índice en Azure AI Search. Puede usar varios índices y orígenes de datos con Azure OpenAI. La
dataSources
propiedad de lagetAzureOpenAIBYODCompletion()
función se puede actualizar para incluir varios orígenes de datos según sea necesario. - La seguridad debe evaluarse cuidadosamente con este tipo de escenario. Los usuarios no deben poder formular preguntas y obtener resultados de documentos a los que no pueden acceder.
- La aplicación de ejemplo usa un único índice en Azure AI Search. Puede usar varios índices y orígenes de datos con Azure OpenAI. La
Ahora que ha aprendido sobre Azure OpenAI, avisos, finalizaciones y cómo puede usar sus propios datos, vamos al siguiente ejercicio para obtener información sobre cómo se pueden usar las características de comunicación para mejorar la aplicación. Si quiere obtener más información sobre Azure OpenAI, consulte el contenido de aprendizaje Introducción al servicio Azure OpenAI. Puede encontrar información adicional sobre el uso de sus propios datos con Azure OpenAI en la documentación de datos de Azure OpenAI.
Comunicación: Creación de un recurso de Azure Communication Services
La comunicación eficaz es esencial para aplicaciones empresariales personalizadas correctas. Mediante El uso de Azure Communication Services (ACS), puede agregar características como llamadas telefónicas, chat en directo, llamadas de audio/vídeo y mensajes de correo electrónico y SMS a las aplicaciones. Anteriormente, ha aprendido cómo Azure OpenAI puede generar finalizaciones para mensajes sms y de correo electrónico. Ahora, aprenderá a enviar los mensajes. Juntos, ACS y OpenAI pueden mejorar las aplicaciones simplificando la comunicación, mejorando las interacciones y aumentando la productividad empresarial.
En este ejercicio, aprenderá a:
- Cree un recurso de Azure Communication Services (ACS).
- Agregue un número de teléfono gratuito con funcionalidades de llamadas y SMS.
- Conecte un dominio de correo electrónico.
- Actualice el archivo .env del proyecto con valores del recurso de ACS.
Creación de un recurso de Azure Communication Services
Visite Azure Portal en el explorador e inicie sesión si aún no lo ha hecho.
Escriba Communication Services en la barra de búsqueda de la parte superior de la página y seleccione Communication Services en las opciones que aparecen.
Seleccione Crear en la barra de herramientas.
Realice las siguientes tareas:
- Seleccione la suscripción a Azure.
- Seleccione el grupo de recursos que se va a usar (cree uno nuevo si no existe).
- Escriba un nombre de recurso de ACS. Debe ser un valor único.
- Seleccione una ubicación de datos.
Seleccione Revisar y crear seguido de Crear.
Ha creado correctamente un nuevo recurso de Azure Communication Services. A continuación, habilitará las funcionalidades de llamadas telefónicas y SMS. También conectará un dominio de correo electrónico al recurso.
Habilitación de las funcionalidades de llamadas telefónicas y SMS
Agregue un número de teléfono y asegúrese de que el número de teléfono tiene habilitadas las funcionalidades de llamada. Usará este número de teléfono para llamar a un teléfono desde la aplicación.
Seleccione Telefonía y SMS -->Números de teléfono en el menú Recurso.
Seleccione + Obtener en la barra de herramientas (o seleccione el botón Obtener un número ) y escriba la siguiente información:
- País o región:
United States
- Tipo de número:
Toll-free
Nota:
Se requiere una tarjeta de crédito en la suscripción de Azure para crear el número gratuito. Si no tiene una tarjeta en el archivo, no dude en omitir la adición de un número de teléfono y saltar a la sección siguiente del ejercicio que conecta un dominio de correo electrónico. Todavía puede usar la aplicación, pero no podrá llamar a un número de teléfono.
- Número: seleccione Agregar al carro para uno de los números de teléfono enumerados.
- País o región:
Seleccione Siguiente, revise los detalles del número de teléfono y seleccione Comprar ahora.
Nota:
La comprobación de SMS para números gratuitos ahora es obligatoria en el Estados Unidos y Canadá. Para habilitar la mensajería SMS, debe enviar la comprobación después de la compra del número de teléfono. Aunque este tutorial no pasará por ese proceso, puede seleccionar Documentos de telefonía y SMS -->Regulatory en el menú de recursos y agregar la documentación de validación necesaria.
Una vez creado el número de teléfono, selecciónelo para ir al panel Características . Asegúrese de que se establecen los siguientes valores (deben establecerse de forma predeterminada):
- En la sección Llamada , seleccione
Make calls
. - En la sección SMS , seleccione
Send and receive SMS
. - Seleccione Guardar.
- En la sección Llamada , seleccione
Copie el valor del número de teléfono en un archivo para su uso posterior. El número de teléfono debe seguir este patrón general:
+12345678900
.
Conexión de un dominio de correo electrónico
Realice las siguientes tareas para crear un dominio de correo electrónico conectado para el recurso de ACS para que pueda enviar correo electrónico. Se usará para enviar correo electrónico desde la aplicación.
- Seleccione Correo electrónico -->Domains en el menú Recurso.
- Seleccione Conectar dominio en la barra de herramientas.
- Seleccione la suscripción y el grupo de recursos.
- En la lista desplegable Servicio de correo electrónico, seleccione
Add an email service
. - Asigne al servicio de correo electrónico un nombre como
acs-demo-email-service
. - Seleccione Revisar y crear seguido de Crear.
- Una vez completada la implementación, seleccione
Go to resource
y seleccione1-click add
para agregar un subdominio de Azure gratuito. - Después de agregar el subdominio (tardará unos minutos en implementarse), selecciónelo.
- Una vez que esté en la pantalla AzureManagedDomain , seleccione Servicios de correo electrónico -->MailDe direcciones en el menú Recurso.
- Copie el valor MailFrom en un archivo. Lo usará más adelante a medida que actualice el archivo .env .
- Vuelva al recurso de Azure Communication Services y seleccione Correo electrónico -->Domains en el menú de recursos.
- Seleccione
Add domain
y escriba elMailFrom
valor del paso anterior (asegúrese de seleccionar la suscripción correcta, el grupo de recursos y el servicio de correo electrónico). Haz clic en el botónConnect
.
Actualizar el .env
archivo
Ahora que el número de teléfono de ACS (con llamadas y SMS habilitados) y el dominio de correo electrónico están listos, actualice las claves y valores siguientes en el archivo .env del proyecto:
ACS_CONNECTION_STRING=<ACS_CONNECTION_STRING> ACS_PHONE_NUMBER=<ACS_PHONE_NUMBER> ACS_EMAIL_ADDRESS=<ACS_EMAIL_ADDRESS> CUSTOMER_EMAIL_ADDRESS=<EMAIL_ADDRESS_TO_SEND_EMAIL_TO> CUSTOMER_PHONE_NUMBER=<UNITED_STATES_BASED_NUMBER_TO_SEND_SMS_TO>
ACS_CONNECTION_STRING
connection string
: valor de la sección Claves del recurso de ACS.ACS_PHONE_NUMBER
: asigne el número gratuito alACS_PHONE_NUMBER
valor.ACS_EMAIL_ADDRESS
: asigne el valor de dirección "MailTo" de correo electrónico.CUSTOMER_EMAIL_ADDRESS
: asigne una dirección de correo electrónico a la que desea que se envíe desde la aplicación (ya que los datos del cliente de la base de datos de la aplicación solo son datos de ejemplo). Puede usar una dirección de correo electrónico personal.CUSTOMER_PHONE_NUMBER
: deberá proporcionar un número de teléfono basado en Estados Unidos (a partir de hoy) debido a la verificación adicional necesaria en otros países para enviar mensajes SMS. Si no tiene un número basado en EE. UU., puede dejarlo vacío.
Iniciar o reiniciar la aplicación y los servidores de API
Realice uno de los pasos siguientes en función de los ejercicios completados hasta este punto:
Si inició la base de datos, el servidor de API y el servidor web en un ejercicio anterior, debe detener el servidor de API y el servidor web y reiniciarlos para seleccionar los cambios del archivo .env . Puede dejar la base de datos en ejecución.
Busque las ventanas de terminal que ejecutan el servidor de API y el servidor web y presione CTRL + C para detenerlas. Vuelva a iniciarlos escribiendo
npm start
en cada ventana de terminal y presionando Entrar. Continúe con el ejercicio siguiente.Si aún no ha iniciado la base de datos, el servidor de API y el servidor web, complete los pasos siguientes:
En los pasos siguientes, creará tres ventanas de terminal en Visual Studio Code.
Haga clic con el botón derecho en el archivo .env de la lista de archivos de Visual Studio Code y seleccione Abrir en terminal integrado. Asegúrese de que el terminal está en la raíz del proyecto - openai-acs-msgraph - antes de continuar.
Elija una de las siguientes opciones para iniciar la base de datos postgreSQL:
Si tiene Docker Desktop instalado y en ejecución, ejecute
docker-compose up
en la ventana del terminal y presione Entrar.Si tiene Podman con podman-compose instalado y en ejecución, ejecute
podman-compose up
en la ventana del terminal y presione Entrar.Para ejecutar el contenedor de PostgreSQL directamente mediante Docker Desktop, Podman, nerdctl u otro entorno de ejecución de contenedor que haya instalado, ejecute el siguiente comando en la ventana del terminal:
Mac, Linux o Subsistema de Windows para Linux (WSL):
[docker | podman | nerdctl] run --name postgresDb -e POSTGRES_USER=web -e POSTGRES_PASSWORD=web-password -e POSTGRES_DB=CustomersDB -v $(pwd)/data:/var/lib/postgresql/data -p 5432:5432 postgres
Windows con PowerShell:
[docker | podman] run --name postgresDb -e POSTGRES_USER=web -e POSTGRES_PASSWORD=web-password -e POSTGRES_DB=CustomersDB -v ${PWD}/data:/var/lib/postgresql/data -p 5432:5432 postgres
Una vez que se inicia el contenedor de base de datos, presione el + icono de la barra de herramientas del terminal de Visual Studio Code para crear una segunda ventana de terminal.
cd
en la carpeta server/typescript y ejecute los siguientes comandos para instalar las dependencias e iniciar el servidor de API.npm install
npm start
Presione de nuevo el + icono en la barra de herramientas del terminal de Visual Studio Code para crear una tercera ventana de terminal.
cd
en la carpeta cliente y ejecute los siguientes comandos para instalar las dependencias e iniciar el servidor web.npm install
npm start
Se iniciará un explorador y se le llevará a http://localhost:4200.
Comunicación: realizar una llamada telefónica
La integración de las funcionalidades de llamadas telefónicas de Azure Communication Services en una aplicación de línea de negocio (LOB) personalizada ofrece varias ventajas clave para las empresas y sus usuarios:
- Permite la comunicación sin problemas y en tiempo real entre empleados, clientes y asociados, directamente desde dentro de la aplicación loB, lo que elimina la necesidad de cambiar entre varias plataformas o dispositivos.
- Mejora la experiencia del usuario y mejora la eficacia operativa general.
- Facilita la resolución rápida de problemas, ya que los usuarios pueden conectarse rápidamente con equipos de soporte técnico relevantes o expertos en la materia de forma rápida y sencilla.
En este ejercicio, aprenderá a:
- Explore la característica de llamadas telefónicas en la aplicación.
- Recorra el código para obtener información sobre cómo se compila la característica de llamada telefónica.
Uso de la característica llamadas telefónicas
En el ejercicio anterior creó un recurso de Azure Communication Services (ACS) e inició la base de datos, el servidor web y el servidor de API. También ha actualizado los siguientes valores en el archivo .env .
ACS_CONNECTION_STRING=<ACS_CONNECTION_STRING> ACS_PHONE_NUMBER=<ACS_PHONE_NUMBER> ACS_EMAIL_ADDRESS=<ACS_EMAIL_ADDRESS> CUSTOMER_EMAIL_ADDRESS=<EMAIL_ADDRESS_TO_SEND_EMAIL_TO> CUSTOMER_PHONE_NUMBER=<UNITED_STATES_BASED_NUMBER_TO_SEND_SMS_TO>
Asegúrese de que ha completado el ejercicio anterior antes de continuar.
Vuelva al explorador (http://localhost:4200), busque la datagrid y seleccione Ponerse en contacto con el cliente seguido de Llamar al cliente en la primera fila.
Se agregará un componente de llamada telefónica al encabezado . Escriba el número de teléfono al que desea llamar (asegúrese de que empieza por + e incluye el código de país) y seleccione Llamar. Se le pedirá que permita el acceso al micrófono.
Seleccione Colgar hasta finalizar la llamada. Seleccione Cerrar para cerrar el componente de llamada telefónica.
Exploración del código de llamada telefónica
Sugerencia
Si usa Visual Studio Code, puede abrir archivos directamente seleccionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
A continuación, escriba el nombre del archivo que desea abrir.
Abra el archivo customers-list.component.ts . La ruta de acceso completa al archivo es client/src/app/customers-list/customers-list.component.ts.
Tenga en cuenta que
openCallDialog()
envía unCustomerCall
mensaje y el número de teléfono del cliente mediante un bus de eventos.openCallDialog(data: Phone) { this.eventBus.emit({ name: Events.CustomerCall, value: data }); }
Nota:
El código del bus de eventos se puede encontrar en el archivo eventbus.service.ts si le interesa explorarlo más. La ruta de acceso completa al archivo es client/src/app/core/eventbus.service.ts.
La función del componente de
ngOnInit()
encabezado se suscribe alCustomerCall
evento enviado por el bus de eventos y muestra el componente de llamada telefónica. Puede encontrar este código en header.component.ts.ngOnInit() { this.subscription.add( this.eventBus.on(Events.CustomerCall, (data: Phone) => { this.callVisible = true; // Show phone call component this.callData = data; // Set phone number to call }) ); }
Abra phone-call.component.ts. Dedique un momento a exponer el código. La ruta de acceso completa al archivo es client/src/app/phone-call/phone-call.component.ts. Tenga en cuenta las siguientes características clave:
- Recupera un token de acceso de Azure Communication Services llamando a la
acsService.getAcsToken()
función enngOnInit()
; - Agrega un "marcador telefónico" a la página. Para ver el marcador, haga clic en la entrada del número de teléfono en el encabezado.
- Inicia y finaliza una llamada mediante las
startCall()
funciones yendCall()
respectivamente.
- Recupera un token de acceso de Azure Communication Services llamando a la
Antes de examinar el código que realiza la llamada telefónica, vamos a examinar cómo se recupera el token de acceso de ACS y cómo se crean los objetos de llamada telefónica. Busque la
ngOnInit()
función en phone-call.component.ts.async ngOnInit() { if (ACS_CONNECTION_STRING) { this.subscription.add( this.acsService.getAcsToken().subscribe(async (user: AcsUser) => { const callClient = new CallClient(); const tokenCredential = new AzureCommunicationTokenCredential(user.token); this.callAgent = await callClient.createCallAgent(tokenCredential); }) ); } }
Esta función realiza las siguientes acciones:
- Recupera un userId de ACS y un token de acceso llamando a la
acsService.getAcsToken()
función . - Una vez recuperado el token de acceso, el código realiza las siguientes acciones:
- Crea una nueva instancia de y
AzureCommunicationTokenCredential
mediante el token deCallClient
acceso. - Crea una nueva instancia de
CallAgent
mediante losCallClient
objetos yAzureCommunicationTokenCredential
. Más adelante verá queCallAgent
se usa para iniciar y finalizar una llamada.
- Crea una nueva instancia de y
- Recupera un userId de ACS y un token de acceso llamando a la
Abra acs.services.ts y busque la
getAcsToken()
función . La ruta de acceso completa al archivo es client/src/app/core/acs.service.ts. La función realiza una solicitud HTTP GET a la/acstoken
ruta expuesta por el servidor de API.getAcsToken(): Observable<AcsUser> { return this.http.get<AcsUser>(this.apiUrl + 'acstoken') .pipe( catchError(this.handleError) ); }
Una función de servidor de API denominada
createACSToken()
recupera el userId y el token de acceso y lo devuelve al cliente. Se puede encontrar en el archivo server/typescript/acs.ts .import { CommunicationIdentityClient } from '@azure/communication-identity'; const connectionString = process.env.ACS_CONNECTION_STRING as string; async function createACSToken() { if (!connectionString) return { userId: '', token: '' }; const tokenClient = new CommunicationIdentityClient(connectionString); const { user, token } = await tokenClient.createUserAndToken(["voip"]); return { userId: user.communicationUserId, token }; }
Esta función realiza las siguientes acciones:
- Comprueba si hay disponible un valor de ACS
connectionString
. Si no es así, devuelve un objeto con un valor vacíouserId
ytoken
. - Crea una nueva instancia de
CommunicationIdentityClient
y pasa elconnectionString
valor a ella. - Crea un nuevo usuario y un token mediante
tokenClient.createUserAndToken()
con el ámbito "voip". - Devuelve un objeto que contiene los
userId
valores ytoken
.
- Comprueba si hay disponible un valor de ACS
Ahora que ha visto cómo se recupera el identificador de usuario y el token, vuelva a y
phone-call.component.ts
busque lastartCall()
función.Se llama a esta función cuando se selecciona Llamar en el componente de llamada telefónica. Usa el
CallAgent
objeto mencionado anteriormente para iniciar una llamada. LacallAgent.startCall()
función acepta un objeto que representa el número que se va a llamar y el número de teléfono de ACS que se usa para realizar la llamada.startCall() { this.call = this.callAgent?.startCall( [{ phoneNumber: this.customerPhoneNumber }], { alternateCallerId: { phoneNumber: this.fromNumber } }); console.log('Calling: ', this.customerPhoneNumber); console.log('Call id: ', this.call?.id); this.inCall = true; // Adding event handlers to monitor call state this.call?.on('stateChanged', () => { console.log('Call state changed: ', this.call?.state); if (this.call?.state === 'Disconnected') { console.log('Call ended. Reason: ', this.call.callEndReason); this.inCall = false; } }); }
Se llama a la
endCall()
función cuando se selecciona Hang Up en el componente de llamada telefónica.endCall() { if (this.call) { this.call.hangUp({ forEveryone: true }); this.call = undefined; this.inCall = false; } else { this.hangup.emit(); } }
Si hay una llamada en curso, se llama a la
call.hangUp()
función para finalizar la llamada. Si no hay ninguna llamada en curso, elhangup
evento se emite al componente primario del encabezado para ocultar el componente de llamada telefónica.Antes de pasar al ejercicio siguiente, revisemos los conceptos clave que se describen en este ejercicio:
- Un userId de ACS y un token de acceso se recuperan del servidor de API mediante la
acsService.createUserAndToken()
función . - El token se usa para crear un
CallClient
objeto yCallAgent
. - El
CallAgent
objeto se usa para iniciar y finalizar una llamada llamando a lascallAgent.startCall()
funciones ycallAgent.hangUp()
respectivamente.
- Un userId de ACS y un token de acceso se recuperan del servidor de API mediante la
Ahora que ha aprendido cómo se pueden integrar las llamadas telefónicas en una aplicación, vamos a cambiar nuestro enfoque al uso de Azure Communication Services para enviar mensajes SMS y correo electrónico.
Comunicación: Envío de mensajes de correo electrónico y SMS
Además de las llamadas telefónicas, Azure Communication Services también puede enviar mensajes de correo electrónico y SMS. Esto puede ser útil cuando desea enviar un mensaje a un cliente u otro usuario directamente desde la aplicación.
En este ejercicio, aprenderá a:
- Explore cómo se pueden enviar mensajes de correo electrónico y SMS desde la aplicación.
- Recorra el código para aprender cómo se implementa la funcionalidad de correo electrónico y SMS.
Uso de las características de correo electrónico y SMS
En un ejercicio anterior creó un recurso de Azure Communication Services (ACS) e inició la base de datos, el servidor web y el servidor de API. También ha actualizado los siguientes valores en el archivo .env .
ACS_CONNECTION_STRING=<ACS_CONNECTION_STRING> ACS_PHONE_NUMBER=<ACS_PHONE_NUMBER> ACS_EMAIL_ADDRESS=<ACS_EMAIL_ADDRESS> CUSTOMER_EMAIL_ADDRESS=<EMAIL_ADDRESS_TO_SEND_EMAIL_TO> CUSTOMER_PHONE_NUMBER=<UNITED_STATES_BASED_NUMBER_TO_SEND_SMS_TO>
Asegúrese de que ha completado el ejercicio antes de continuar.
Vuelva al explorador (http://localhost:4200) y seleccione Ponerse en contacto con el cliente seguido de Email/SMS Customer en la primera fila.
Seleccione la pestaña Correo electrónico/SMS y realice las siguientes tareas:
- Escriba un asunto de correo electrónico y un cuerpo y seleccione el botón Enviar correo electrónico.
- Escriba un mensaje SMS y seleccione el botón Enviar SMS .
Nota:
La comprobación de SMS para números gratuitos ahora es obligatoria en el Estados Unidos y Canadá. Para habilitar la mensajería SMS, debe enviar la comprobación después de la compra del número de teléfono. Aunque este tutorial no pasará por ese proceso, puede seleccionar Documentos de telefonía y SMS -->Regulatory en el recurso de Azure Communication Services en Azure Portal y agregar la documentación de validación necesaria.
Compruebe que recibió el correo electrónico y los mensajes SMS. La funcionalidad de SMS solo funcionará si envió los documentos normativos mencionados en la nota anterior. Como recordatorio, el mensaje de correo electrónico se enviará al valor definido para
CUSTOMER_EMAIL_ADDRESS
y el mensaje SMS se enviará al valor definido paraCUSTOMER_PHONE_NUMBER
en el archivo .env . Si no pudo proporcionar un número de teléfono basado en Estados Unidos para usarlo para los mensajes SMS, puede omitir ese paso.Nota:
Si no ve el mensaje de correo electrónico en la bandeja de entrada para la dirección que definió en
CUSTOMER_EMAIL_ADDRESS
el archivo .env , compruebe la carpeta de correo no deseado.
Exploración del código de correo electrónico
Sugerencia
Si usa Visual Studio Code, puede abrir archivos directamente seleccionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
A continuación, escriba el nombre del archivo que desea abrir.
Abra el archivo customers-list.component.ts . La ruta de acceso completa al archivo es client/src/app/customers-list/customers-list.component.ts.
Cuando seleccionó Ponerse en contacto con el cliente seguido de Email/SMS Customer en datagrid, el
customer-list
componente muestra un cuadro de diálogo. Esto se controla mediante laopenEmailSmsDialog()
función del archivo customer-list.component.ts .openEmailSmsDialog(data: any) { if (data.phone && data.email) { // Create the data for the dialog let dialogData: EmailSmsDialogData = { prompt: '', title: `Contact ${data.company}`, company: data.company, customerName: data.first_name + ' ' + data.last_name, customerEmailAddress: data.email, customerPhoneNumber: data.phone } // Open the dialog const dialogRef = this.dialog.open(EmailSmsDialogComponent, { data: dialogData }); // Subscribe to the dialog afterClosed observable to get the dialog result this.subscription.add( dialogRef.afterClosed().subscribe((response: EmailSmsDialogData) => { console.log('SMS dialog result:', response); if (response) { dialogData = response; } }) ); } else { alert('No phone number available.'); } }
La
openEmailSmsDialog()
función realiza las siguientes tareas:- Comprueba si el
data
objeto (que representa la fila de datagrid) contiene unaphone
propiedad yemail
. Si lo hace, crea undialogData
objeto que contiene la información que se va a pasar al cuadro de diálogo. - Abre el
EmailSmsDialogComponent
cuadro de diálogo y pasa eldialogData
objeto a él. - Se suscribe al
afterClosed()
evento del cuadro de diálogo. Este evento se desencadena cuando se cierra el cuadro de diálogo. Elresponse
objeto contiene la información especificada en el cuadro de diálogo.
- Comprueba si el
Abra el archivo email-sms-dialog.component.ts . La ruta de acceso completa al archivo es client/src/app/email-sms-dialog/email-sms-dialog.component.ts.
Busque la
sendEmail()
función :sendEmail() { if (this.featureFlags.acsEmailEnabled) { // Using CUSTOMER_EMAIL_ADDRESS instead of this.data.email for testing purposes this.subscription.add( this.acsService.sendEmail(this.emailSubject, this.emailBody, this.getFirstName(this.data.customerName), CUSTOMER_EMAIL_ADDRESS /* this.data.email */) .subscribe(res => { console.log('Email sent:', res); if (res.status) { this.emailSent = true; } }) ); } else { this.emailSent = true; // Used when ACS email isn't enabled } }
La
sendEmail()
función realiza las siguientes tareas:- Comprueba si la marca de
acsEmailEnabled
características está establecidatrue
en . Esta marca comprueba si laACS_EMAIL_ADDRESS
variable de entorno tiene un valor asignado. - Si
acsEmailEnabled
es true, se llama a laacsService.sendEmail()
función y se pasan el asunto del correo electrónico, el cuerpo, el nombre del cliente y la dirección de correo electrónico del cliente. Dado que la base de datos contiene datos de ejemplo, se usa laCUSTOMER_EMAIL_ADDRESS
variable de entorno en lugar dethis.data.email
. En una aplicación real, se usaría elthis.data.email
valor. - Se suscribe a la
sendEmail()
función en elacsService
servicio. Esta función devuelve un observable RxJS que contiene la respuesta del servicio del lado cliente. - Si el correo electrónico se envió correctamente, la
emailSent
propiedad se establece entrue
.
- Comprueba si la marca de
Para proporcionar una mejor encapsulación y reutilización de código, los servicios del lado cliente, como acs.service.ts , se usan en toda la aplicación. Esto permite consolidar todas las funciones de ACS en un solo lugar.
Abra acs.service.ts y busque la
sendEmail()
función . La ruta de acceso completa al archivo es client/src/app/core/acs.service.ts.sendEmail(subject: string, message: string, customerName: string, customerEmailAddress: string) : Observable<EmailSmsResponse> { return this.http.post<EmailSmsResponse>(this.apiUrl + 'sendEmail', { subject, message, customerName, customerEmailAddress }) .pipe( catchError(this.handleError) ); }
La
sendEmail()
función deAcsService
realiza las siguientes tareas:- Llama a la
http.post()
función y pasa el asunto del correo electrónico, el mensaje, el nombre del cliente y la dirección de correo electrónico del cliente. Lahttp.post()
función devuelve un observable RxJS que contiene la respuesta de la llamada API. - Controla los errores devueltos por la
http.post()
función mediante el operador RxJScatchError
.
- Llama a la
Ahora vamos a examinar cómo interactúa la aplicación con la característica de correo electrónico de ACS. Abra el archivo acs.ts y busque la
sendEmail()
función . La ruta de acceso completa al archivo es server/typescript/acs.ts.La
sendEmail()
función realiza las siguientes tareas:Crea un nuevo
EmailClient
objeto y pasa el cadena de conexión de ACS (este valor se recupera de laACS_CONNECTION_STRING
variable de entorno).const emailClient = new EmailClient(connectionString);
Crea un nuevo
EmailMessage
objeto y pasa la información del remitente, el asunto, el mensaje y el destinatario.const msgObject: EmailMessage = { senderAddress: process.env.ACS_EMAIL_ADDRESS as string, content: { subject: subject, plainText: message, }, recipients: { to: [ { address: customerEmailAddress, displayName: customerName, }, ], }, };
Envía el correo electrónico mediante la
emailClient.beginSend()
función y devuelve la respuesta. Aunque la función solo envía a un destinatario en este ejemplo, también se puede usar labeginSend()
función para enviar a varios destinatarios.const poller = await emailClient.beginSend(msgObject);
Espera a que el
poller
objeto indique que se ha realizado y envía la respuesta al autor de la llamada.
Exploración del código SMS
Vuelva al archivo email-sms-dialog.component.ts que abrió anteriormente. La ruta de acceso completa al archivo es client/src/app/email-sms-dialog/email-sms-dialog.component.ts.
Busque la
sendSms()
función :sendSms() { if (this.featureFlags.acsPhoneEnabled) { // Using CUSTOMER_PHONE_NUMBER instead of this.data.customerPhoneNumber for testing purposes this.subscription.add( this.acsService.sendSms(this.smsMessage, CUSTOMER_PHONE_NUMBER /* this.data.customerPhoneNumber */) .subscribe(res => { if (res.status) { this.smsSent = true; } }) ); } else { this.smsSent = true; } }
La
sendSMS()
función realiza las siguientes tareas:- Comprueba si la marca de
acsPhoneEnabled
características está establecidatrue
en . Esta marca comprueba si laACS_PHONE_NUMBER
variable de entorno tiene un valor asignado. - Si
acsPhoneEnabled
es true, se llama a laacsService.SendSms()
función y se pasa el mensaje SMS y el número de teléfono del cliente. Dado que la base de datos contiene datos de ejemplo, se usa laCUSTOMER_PHONE_NUMBER
variable de entorno en lugar dethis.data.customerPhoneNumber
. En una aplicación real, se usaría elthis.data.customerPhoneNumber
valor. - Se suscribe a la
sendSms()
función en elacsService
servicio. Esta función devuelve un observable RxJS que contiene la respuesta del servicio del lado cliente. - Si el mensaje SMS se envió correctamente, establece la
smsSent
propiedadtrue
en .
- Comprueba si la marca de
Abra acs.service.ts y busque la
sendSms()
función . La ruta de acceso completa al archivo es client/src/app/core/acs.service.ts.sendSms(message: string, customerPhoneNumber: string) : Observable<EmailSmsResponse> { return this.http.post<EmailSmsResponse>(this.apiUrl + 'sendSms', { message, customerPhoneNumber }) .pipe( catchError(this.handleError) ); }
La
sendSms()
función realiza las siguientes tareas:- Llama a la
http.post()
función y pasa el mensaje y el número de teléfono del cliente. Lahttp.post()
función devuelve un observable RxJS que contiene la respuesta de la llamada API. - Controla los errores devueltos por la
http.post()
función mediante el operador RxJScatchError
.
- Llama a la
Por último, vamos a examinar cómo interactúa la aplicación con la característica DE SMS de ACS. Abra el archivo acs.ts . La ruta de acceso completa al archivo es server/typescript/acs.ts y busque la
sendSms()
función.La
sendSms()
función realiza las siguientes tareas:Crea un nuevo
SmsClient
objeto y pasa el cadena de conexión de ACS (este valor se recupera de laACS_CONNECTION_STRING
variable de entorno).const smsClient = new SmsClient(connectionString);
Llama a la
smsClient.send()
función y pasa el número de teléfono de ACS (from
), el número de teléfono del cliente (to
) y el mensaje SMS:const sendResults = await smsClient.send({ from: process.env.ACS_PHONE_NUMBER as string, to: [customerPhoneNumber], message: message }); return sendResults;
Devuelve la respuesta al autor de la llamada.
Puede obtener más información sobre la funcionalidad de correo electrónico y SMS de ACS en los siguientes artículos:
Antes de pasar al ejercicio siguiente, revisemos los conceptos clave que se describen en este ejercicio:
- El archivo acs.service.ts encapsula la funcionalidad de correo electrónico y SMS de ACS que usa la aplicación del lado cliente. Controla las llamadas API al servidor y devuelve la respuesta al autor de la llamada.
- La API del lado servidor usa acs
EmailClient
ySmsClient
objetos para enviar mensajes sms y de correo electrónico.
Ahora que ha aprendido cómo se pueden enviar mensajes de correo electrónico y SMS, vamos a cambiar nuestro enfoque para integrar los datos de la organización en la aplicación.
Datos de la organización: creación de un registro de aplicaciones de Microsoft Entra ID
Mejore la productividad del usuario mediante la integración de datos de la organización (correos electrónicos, archivos, chats y eventos de calendario) directamente en sus aplicaciones personalizadas. Mediante el uso de las API de Microsoft Graph y el identificador de Entra de Microsoft, puede recuperar y mostrar sin problemas los datos pertinentes dentro de las aplicaciones, lo que reduce la necesidad de que los usuarios cambien de contexto. Independientemente de si hace referencia a un correo electrónico enviado a un cliente, revisando un mensaje de Teams o accediendo a un archivo, los usuarios pueden encontrar rápidamente la información que necesitan sin salir de la aplicación, lo que simplifica su proceso de toma de decisiones.
En este ejercicio, aprenderá a:
- Cree un registro de aplicación de Id. de Microsoft Entra para que Microsoft Graph pueda acceder a los datos de la organización y incorporarlos a la aplicación.
- Busque
team
echannel
ids de Microsoft Teams necesarios para enviar mensajes de chat a un canal específico. - Actualice el archivo .env del proyecto con valores del registro de la aplicación microsoft Entra ID.
Creación de un registro de aplicaciones de Microsoft Entra ID
Vaya a Azure Portal y seleccione Microsoft Entra ID.
Seleccione Administrar -->Registros de aplicaciones seguido de + Nuevo registro.
Rellene los detalles del nuevo formulario de registro de aplicaciones como se muestra a continuación y seleccione Registrar:
- Nombre: microsoft-graph-app
- Tipos de cuenta admitidos: cuentas en cualquier directorio organizativo (cualquier inquilino de Id. de Microsoft Entra: multiinquilino)
- URI de redireccionamiento:
- Seleccione Aplicación de página única (SPA) y escriba
http://localhost:4200
en el campo URI de redirección.
- Seleccione Aplicación de página única (SPA) y escriba
- Selecciona Registrar para crear el registro de aplicación.
Seleccione Información general en el menú de recursos y copie el valor en el
Application (client) ID
Portapapeles.
Actualizar el archivo .env del proyecto
Abra el archivo .env en el editor y asigne el
Application (client) ID
valor aENTRAID_CLIENT_ID
.ENTRAID_CLIENT_ID=<APPLICATION_CLIENT_ID_VALUE>
Si desea habilitar la capacidad de enviar un mensaje desde la aplicación a un canal de Teams, inicie sesión en Microsoft Teams con su cuenta de inquilino de desarrollo de Microsoft 365 (esto se menciona en las preguntas previas del tutorial).
Una vez que haya iniciado sesión, expanda un equipo y busque un canal al que quiera enviar mensajes desde la aplicación. Por ejemplo, puede seleccionar el equipo de empresa y el canal General (o cualquier equipo o canal que quiera usar).
En el encabezado del equipo, haga clic en los tres puntos (...) y seleccione Obtener vínculo al equipo.
En el vínculo que aparece en la ventana emergente, el identificador de equipo es la cadena de letras y números después
team/
de . Por ejemplo, en el vínculo "https://teams.microsoft.com/l/team/19%3ae9b9.../", el identificador del equipo es 19%3ae9b9... hasta el siguiente/
carácter.Copie el identificador de equipo y asígnelo a
TEAM_ID
en el archivo .env .En el encabezado del canal, haga clic en los tres puntos (...) y seleccione Obtener vínculo al canal.
En el vínculo que aparece en la ventana emergente, el identificador de canal es la cadena de letras y números después
channel/
de . Por ejemplo, en el vínculo "https://teams.microsoft.com/l/channel/19%3aQK02.../", el identificador del canal es 19%3aQK02... hasta el siguiente/
carácter.Copie el identificador del canal y asígnelo a
CHANNEL_ID
en el archivo .env .Guarde el archivo env antes de continuar.
Iniciar o reiniciar la aplicación y los servidores de API
Realice uno de los pasos siguientes en función de los ejercicios completados hasta este punto:
Si inició la base de datos, el servidor de API y el servidor web en un ejercicio anterior, debe detener el servidor de API y el servidor web y reiniciarlos para seleccionar los cambios del archivo .env . Puede dejar la base de datos en ejecución.
Busque las ventanas de terminal que ejecutan el servidor de API y el servidor web y presione CTRL + C para detenerlas. Vuelva a iniciarlos escribiendo
npm start
en cada ventana de terminal y presionando Entrar. Continúe con el ejercicio siguiente.Si aún no ha iniciado la base de datos, el servidor de API y el servidor web, complete los pasos siguientes:
En los pasos siguientes, creará tres ventanas de terminal en Visual Studio Code.
Haga clic con el botón derecho en el archivo .env de la lista de archivos de Visual Studio Code y seleccione Abrir en terminal integrado. Asegúrese de que el terminal está en la raíz del proyecto - openai-acs-msgraph - antes de continuar.
Elija una de las siguientes opciones para iniciar la base de datos postgreSQL:
Si tiene Docker Desktop instalado y en ejecución, ejecute
docker-compose up
en la ventana del terminal y presione Entrar.Si tiene Podman con podman-compose instalado y en ejecución, ejecute
podman-compose up
en la ventana del terminal y presione Entrar.Para ejecutar el contenedor de PostgreSQL directamente mediante Docker Desktop, Podman, nerdctl u otro entorno de ejecución de contenedor que haya instalado, ejecute el siguiente comando en la ventana del terminal:
Mac, Linux o Subsistema de Windows para Linux (WSL):
[docker | podman | nerdctl] run --name postgresDb -e POSTGRES_USER=web -e POSTGRES_PASSWORD=web-password -e POSTGRES_DB=CustomersDB -v $(pwd)/data:/var/lib/postgresql/data -p 5432:5432 postgres
Windows con PowerShell:
[docker | podman] run --name postgresDb -e POSTGRES_USER=web -e POSTGRES_PASSWORD=web-password -e POSTGRES_DB=CustomersDB -v ${PWD}/data:/var/lib/postgresql/data -p 5432:5432 postgres
Una vez que se inicia el contenedor de base de datos, presione el + icono de la barra de herramientas del terminal de Visual Studio Code para crear una segunda ventana de terminal.
cd
en la carpeta server/typescript y ejecute los siguientes comandos para instalar las dependencias e iniciar el servidor de API.npm install
npm start
Presione de nuevo el + icono en la barra de herramientas del terminal de Visual Studio Code para crear una tercera ventana de terminal.
cd
en la carpeta cliente y ejecute los siguientes comandos para instalar las dependencias e iniciar el servidor web.npm install
npm start
Se iniciará un explorador y se le llevará a http://localhost:4200.
Datos de la organización: inicio de sesión de un usuario y obtención de un token de acceso
Los usuarios deben autenticarse con el identificador de Entra de Microsoft para que Microsoft Graph acceda a los datos de la organización. En este ejercicio, verá cómo se puede usar el componente del mgt-login
Kit de herramientas de Microsoft Graph para autenticar a los usuarios y recuperar un token de acceso. A continuación, el token de acceso se puede usar para realizar llamadas a Microsoft Graph.
Nota:
Si no está familiarizado con Microsoft Graph, puede obtener más información sobre ella en la ruta de aprendizaje Aspectos básicos de Microsoft Graph.
En este ejercicio, aprenderá a:
- Obtenga información sobre cómo asociar una aplicación de id. de Entra de Microsoft con el Kit de herramientas de Microsoft Graph para autenticar a los usuarios y recuperar datos de la organización.
- Obtenga información sobre la importancia de los ámbitos.
- Obtenga información sobre cómo se puede usar el componente mgt-login del Kit de herramientas de Microsoft Graph para autenticar a los usuarios y recuperar un token de acceso.
Uso de la característica de inicio de sesión
En el ejercicio anterior, ha creado un registro de aplicación en microsoft Entra ID e inició el servidor de aplicaciones y el servidor de API. También ha actualizado los siguientes valores en el
.env
archivo (TEAM_ID
yCHANNEL_ID
son opcionales):ENTRAID_CLIENT_ID=<APPLICATION_CLIENT_ID_VALUE> TEAM_ID=<TEAMS_TEAM_ID> CHANNEL_ID=<TEAMS_CHANNEL_ID>
Asegúrese de que ha completado el ejercicio anterior antes de continuar.
Vuelva al explorador (http://localhost:4200), seleccione Iniciar sesión en el encabezado e inicie sesión con una cuenta de usuario administrador del inquilino de Microsoft 365 Developer.
Sugerencia
Inicie sesión con su cuenta de administrador de inquilino de desarrollador de Microsoft 365. Para ver otros usuarios del inquilino del desarrollador, vaya al Centro de administración de Microsoft 365.
Si inicia sesión en la aplicación por primera vez, se le pedirá que dé su consentimiento a los permisos solicitados por la aplicación. Obtendrá más información sobre estos permisos (también denominados "ámbitos") en la sección siguiente mientras explora el código. Seleccione Aceptar para continuar.
Una vez que haya iniciado sesión, debería ver el nombre del usuario mostrado en el encabezado.
Exploración del código de inicio de sesión
Ahora que ha iniciado sesión, echemos un vistazo al código que se usa para iniciar sesión en el usuario y recuperar un token de acceso y un perfil de usuario. Obtendrá información sobre el componente web mgt-login que forma parte del Kit de herramientas de Microsoft Graph.
Sugerencia
Si usa Visual Studio Code, puede abrir archivos directamente seleccionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
A continuación, escriba el nombre del archivo que desea abrir.
Abra el cliente o package.json y observe que los
@microsoft/mgt
paquetes y@microsoft/mgt-components
se incluyen en las dependencias. El@microsoft/mgt
paquete contiene características del proveedor msAL (biblioteca de autenticación de Microsoft) y componentes web, como mgt-login y otros que se pueden usar para iniciar sesión a los usuarios y recuperar y mostrar datos de la organización.Abra client/src/main.ts y observe las siguientes importaciones del
@microsoft/mgt-components
paquete. Los símbolos importados se usan para registrar los componentes del Kit de herramientas de Microsoft Graph que se usan en la aplicación.import { registerMgtLoginComponent, registerMgtSearchResultsComponent, registerMgtPersonComponent, } from '@microsoft/mgt-components';
Desplácese hasta la parte inferior del archivo y anote el código siguiente:
registerMgtLoginComponent(); registerMgtSearchResultsComponent(); registerMgtPersonComponent();
Este código registra los
mgt-login
componentes web ,mgt-search-results
ymgt-person
y los habilita para su uso en la aplicación.Para usar el componente mgt-login para iniciar sesión en los usuarios, es necesario hacer referencia al identificador de cliente de la aplicación de id. de microsoft Entra (almacenado en el archivo .env como
ENTRAID_CLIENT_ID
) y usarse.Abra graph.service.ts y busque la
init()
función . La ruta de acceso completa al archivo es client/src/app/core/graph.service.ts. Verá la siguiente importación y código:import { Msal2Provider, Providers, ProviderState } from '@microsoft/mgt'; init() { if (!this.featureFlags.microsoft365Enabled) return; if (!Providers.globalProvider) { console.log('Initializing Microsoft Graph global provider...'); Providers.globalProvider = new Msal2Provider({ clientId: ENTRAID_CLIENT_ID, scopes: ['User.Read', 'Presence.Read', 'Chat.ReadWrite', 'Calendars.Read', 'ChannelMessage.Read.All', 'ChannelMessage.Send', 'Files.Read.All', 'Mail.Read'] }); } else { console.log('Global provider already initialized'); } }
Este código crea un nuevo
Msal2Provider
objeto, pasando el identificador de cliente de Id. de Entra de Microsoft desde el registro de la aplicación y el para elscopes
que la aplicación solicitará acceso.scopes
se usan para solicitar acceso a los recursos de Microsoft Graph a los que accederá la aplicación. Una vez creado elMsal2Provider
objeto, se asigna alProviders.globalProvider
objeto , que los componentes del Kit de herramientas de Microsoft Graph usan para recuperar datos de Microsoft Graph.Abra header.component.html en el editor y busque el componente mgt-login . La ruta de acceso completa al archivo es client/src/app/header/header.component.html.
@if (this.featureFlags.microsoft365Enabled) { <mgt-login class="mgt-dark" (loginCompleted)="loginCompleted()"></mgt-login> }
El componente mgt-login habilita el inicio de sesión del usuario y proporciona acceso a un token que se usa con Microsoft Graph. Tras iniciar sesión correctamente, se desencadena el
loginCompleted
evento , que llama a laloginCompleted()
función . Aunque mgt-login se usa dentro de un componente de Angular en este ejemplo, es compatible con cualquier aplicación web.La presentación del componente mgt-login depende del
featureFlags.microsoft365Enabled
valor que se establecetrue
en . Esta marca personalizada comprueba la presencia de laENTRAID_CLIENT_ID
variable de entorno para confirmar que la aplicación está configurada correctamente y puede autenticarse en el identificador de Microsoft Entra. La marca se agrega para dar cabida a los casos en los que los usuarios eligen completar solo los ejercicios de inteligencia artificial o comunicación en el tutorial, en lugar de seguir toda la secuencia de ejercicios.Abra header.component.ts y busque la
loginCompleted
función . Se llama a esta función cuando se emite elloginCompleted
evento y controla la recuperación del perfil del usuario que ha iniciado sesión medianteProviders.globalProvider
.async loginCompleted() { const me = await Providers.globalProvider.graph.client.api('me').get(); this.userLoggedIn.emit(me); }
En este ejemplo, se realiza una llamada a Microsoft Graph
me
API para recuperar el perfil del usuario (me
representa el usuario que inició sesión actual). Lathis.userLoggedIn.emit(me)
instrucción de código emite un evento del componente para pasar los datos de perfil al componente primario. El componente primario es app.component.ts archivo en este caso, que es el componente raíz de la aplicación.Para obtener más información sobre el componente mgt-login , visite la documentación del Kit de herramientas de Microsoft Graph.
Ahora que ha iniciado sesión en la aplicación, veamos cómo se pueden recuperar los datos de la organización.
Datos de la organización: recuperar archivos, chats y enviar mensajes a Teams
En el entorno digital actual, los usuarios trabajan con una amplia gama de datos de la organización, incluidos correos electrónicos, chats, archivos, eventos de calendario, etc. Esto puede dar lugar a cambios de contexto frecuentes( cambiar entre tareas o aplicaciones), lo que puede interrumpir el foco y reducir la productividad. Por ejemplo, un usuario que trabaja en un proyecto podría necesitar cambiar de su aplicación actual a Outlook para encontrar detalles cruciales en un correo electrónico o cambiar a OneDrive para la Empresa para encontrar un archivo relacionado. Esta acción de ida y vuelta interrumpe el foco y pierde el tiempo que podría dedicarse mejor a la tarea en cuestión.
Para mejorar la eficacia, puede integrar los datos de la organización directamente en las aplicaciones que los usuarios usan todos los días. Al incorporar datos de la organización a las aplicaciones, los usuarios pueden acceder a la información y administrarla de forma más fluida, minimizando los cambios de contexto y mejorando la productividad. Además, esta integración proporciona información valiosa y contexto, lo que permite a los usuarios tomar decisiones informadas y trabajar de forma más eficaz.
En este ejercicio, aprenderá a:
- Obtenga información sobre cómo se puede usar el componente web mgt-search-results del kit de herramientas de Microsoft Graph para buscar archivos.
- Obtenga información sobre cómo llamar directamente a Microsoft Graph para recuperar archivos de OneDrive para la Empresa y mensajes de chat de Microsoft Teams.
- Obtenga información sobre cómo enviar mensajes de chat a canales de Microsoft Teams mediante Microsoft Graph.
Uso de la característica de datos de la organización
En un ejercicio anterior, creó un registro de aplicación en el identificador de Microsoft Entra e inició el servidor de aplicaciones y el servidor de API. También ha actualizado los siguientes valores en el
.env
archivo.ENTRAID_CLIENT_ID=<APPLICATION_CLIENT_ID_VALUE> TEAM_ID=<TEAMS_TEAM_ID> CHANNEL_ID=<TEAMS_CHANNEL_ID>
Asegúrese de que ha completado el ejercicio anterior antes de continuar.
Vuelva al explorador (http://localhost:4200). Si aún no ha iniciado sesión, seleccione Iniciar sesión en el encabezado e inicie sesión con un usuario del inquilino de Microsoft 365 Developer.
Nota:
Además de autenticar al usuario, el componente web mgt-login también recupera un token de acceso que Microsoft Graph puede usar para acceder a archivos, chats, correos electrónicos, eventos de calendario y otros datos de la organización. El token de acceso contiene los ámbitos (permisos), como
Chat.ReadWrite
,Files.Read.All
y otros que vio anteriormente:Providers.globalProvider = new Msal2Provider({ clientId: ENTRAID_CLIENT_ID, // retrieved from .env file scopes: ['User.Read', 'Presence.Read', 'Chat.ReadWrite', 'Calendars.Read', 'ChannelMessage.Read.All', 'ChannelMessage.Send', 'Files.Read.All', 'Mail.Read'] });
Seleccione Ver contenido relacionado para la fila de Adatum Corporation en datagrid. Esto hará que los datos de la organización, como archivos, chats, correos electrónicos y eventos de calendario se recuperen mediante Microsoft Graph. Una vez que se carguen los datos, se mostrará debajo de la datagrid en una interfaz con pestañas. Es importante mencionar que es posible que no vea ningún dato en este momento, ya que aún no ha agregado ningún archivo, chats, correos electrónicos o eventos de calendario para el usuario en el inquilino de desarrollador de Microsoft 365. Vamos a corregirlo en el paso siguiente.
Es posible que su inquilino de Microsoft 365 no tenga ningún dato organizativo relacionado para Adatum Corporation en esta fase. Para agregar algunos datos de ejemplo, realice al menos una de las siguientes acciones:
Agregue archivos visitando https://onedrive.com e iniciando sesión con sus credenciales de inquilino de Microsoft 365 Developer.
- Seleccione Mis archivos en el panel de navegación izquierdo.
- Seleccione + Agregar nuevo y, a continuación, Cargar carpeta en el menú.
- Seleccione la carpeta openai-acs-msgraph/customer documents del proyecto que ha clonado.
Agregue mensajes de chat y eventos de calendario visitando https://teams.microsoft.com e iniciando sesión con sus credenciales de inquilino de Microsoft 365 Developer.
Seleccione Teams en el panel de navegación izquierdo.
Seleccione un equipo y un canal.
Seleccione Iniciar una publicación.
Escriba Nuevo pedido realizado para Adatum Corporation para el asunto y cualquier texto adicional que desee agregar en el cuerpo del mensaje. Seleccione el botón Registrar.
No dude en agregar mensajes de chat adicionales que mencionen a otras empresas que se usan en la aplicación, como Adventure Works Cycles, Contoso Pharmaceuticals y Tailwind Traders.
Seleccione Calendario en el panel de navegación izquierdo.
Seleccione Nueva reunión.
Escriba "Meet with Adatum Corporation about project schedule" (Reunirse con Adatum Corporation sobre la programación del proyecto) para el título y el cuerpo.
Seleccione Guardar.
Agregue correos electrónicos visitando https://outlook.com e iniciando sesión con sus credenciales de inquilino de Microsoft 365 Developer.
Seleccione Nuevo correo.
Escriba su dirección de correo electrónico personal en el campo Para .
Escriba Nuevo pedido realizado para Adatum Corporation para el sujeto y todo lo que le gustaría para el cuerpo.
Seleccione Enviar.
Vuelva a la aplicación en el explorador y actualice la página. Seleccione Ver contenido relacionado de nuevo para la fila Adatum Corporation . Ahora debería ver los datos mostrados en las pestañas en función de las tareas que haya realizado en el paso anterior.
Vamos a explorar el código que habilita la característica de datos de la organización en la aplicación. Para recuperar los datos, la parte del lado cliente de la aplicación usa el token de acceso recuperado por el componente mgt-login que miró anteriormente para realizar llamadas a las API de Microsoft Graph.
Exploración del código de búsqueda de archivos
Sugerencia
Si usa Visual Studio Code, puede abrir archivos directamente seleccionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
A continuación, escriba el nombre del archivo que desea abrir.
Empecemos examinando cómo se recuperan los datos de archivo de OneDrive para la Empresa. Abra files.component.html y dedique un momento a examinar el código. La ruta de acceso completa al archivo es client/src/app/files/files.component.html.
Busque el componente mgt-search-results y anote los atributos siguientes:
<mgt-search-results class="search-results" entity-types="driveItem" [queryString]="searchText" (dataChange)="dataChange($any($event))" />
El componente mgt-search-results forma parte del Kit de herramientas de Microsoft Graph y, como su nombre indica, se usa para mostrar los resultados de búsqueda de Microsoft Graph. El componente usa las siguientes características en este ejemplo:
El
class
atributo se usa para especificar que lasearch-results
clase CSS se debe aplicar al componente.El
entity-types
atributo se usa para especificar el tipo de datos que se va a buscar. En este caso, el valor esdriveItem
que se usa para buscar archivos en OneDrive para la Empresa.El
queryString
atributo se usa para especificar el término de búsqueda. En este caso, el valor se enlaza a lasearchText
propiedad que se pasa al componente de archivos cuando el usuario selecciona Ver contenido relacionado para una fila en la datagrid. Los corchetes alrededorqueryString
indican que la propiedad está enlazada alsearchText
valor .El
dataChange
evento se desencadena cuando cambian los resultados de la búsqueda. En este caso, se llama a una función de cliente denominadadataChange()
en el componente de archivos y los datos del evento se pasan a la función. El paréntesis alrededordataChange
indica que el evento está enlazado a ladataChange()
función.Dado que no se proporciona ninguna plantilla personalizada, la plantilla predeterminada integrada
mgt-search-results
se usa para mostrar los resultados de la búsqueda.
Una alternativa al uso de componentes como mgt-search-results es llamar a las API de Microsoft Graph directamente mediante código. Para ver cómo funciona, abra el archivo graph.service.ts y busque la
searchFiles()
función . La ruta de acceso completa al archivo es client/src/app/core/graph.service.ts.Observará que se pasa un
query
parámetro a la función . Este es el término de búsqueda que se pasa cuando el usuario selecciona Ver contenido relacionado para una fila de datagrid. Si no se pasa ningún término de búsqueda, se devuelve una matriz vacía.async searchFiles(query: string) { const files: DriveItem[] = []; if (!query) return files; ... }
A continuación, se crea un filtro que define el tipo de búsqueda que se va a realizar. En este caso, el código busca archivos en OneDrive para la Empresa, por lo que
driveItem
se usa tal como se vio anteriormente con elmgt-search-results
componente . Esto es lo mismo que pasardriveItem
alentity-types
componente mgt-search-results que vio anteriormente. Aquery
continuación, el parámetro se agrega alqueryString
filtro junto conContentType:Document
.const filter = { "requests": [ { "entityTypes": [ "driveItem" ], "query": { "queryString": `${query} AND ContentType:Document` } } ] };
A continuación, se realiza una llamada a
/search/query
Microsoft Graph API mediante laProviders.globalProvider.graph.client.api()
función . Elfilter
objeto se pasa a lapost()
función que envía los datos a la API.const searchResults = await Providers.globalProvider.graph.client.api('/search/query').post(filter);
A continuación, los resultados de la búsqueda se recorren en iteración para buscar
hits
. Cadahit
contiene información sobre un documento que se encontró. Una propiedad denominadaresource
contiene los metadatos del documento y se agrega a lafiles
matriz.if (searchResults.value.length !== 0) { for (const hitContainer of searchResults.value[0].hitsContainers) { if (hitContainer.hits) { for (const hit of hitContainer.hits) { files.push(hit.resource); } } } }
A
files
continuación, la matriz se devuelve al autor de la llamada.return files;
Al examinar este código, puede ver que el componente web mgt-search-results que ha explorado anteriormente hace mucho trabajo para usted y reduce significativamente la cantidad de código que tiene que escribir. Sin embargo, puede haber escenarios en los que quiera llamar directamente a Microsoft Graph para tener más control sobre los datos que se envían a la API o cómo se procesan los resultados.
Abra el archivo files.component.ts y busque la
search()
función . La ruta de acceso completa al archivo es client/src/app/files/files.component.ts.Aunque el cuerpo de esta función se comenta debido a que se usa el componente mgt-search-results , la función podría usarse para realizar la llamada a Microsoft Graph cuando el usuario selecciona Ver contenido relacionado para una fila en la red de datos. La
search()
función llamasearchFiles()
a en graph.service.ts y le pasa elquery
parámetro (el nombre de la empresa en este ejemplo). A continuación, los resultados de la búsqueda se asignan a ladata
propiedad del componente.override async search(query: string) { this.data = await this.graphService.searchFiles(query); }
Después, el componente de archivos puede usar la
data
propiedad para mostrar los resultados de la búsqueda. Puede controlarlo mediante enlaces HTML personalizados o mediante otro control del Kit de herramientas de Microsoft Graph denominadomgt-file-list
. Este es un ejemplo de enlazar ladata
propiedad a una de las propiedades del componente denominadasfiles
y controlar elitemClick
evento a medida que el usuario interactúa con un archivo.<mgt-file-list (itemClick)="itemClick($any($event))" [files]="data"></mgt-file-list>
Tanto si decide usar el componente mgt-search-results mostrado anteriormente como si escribe código personalizado para llamar a Microsoft Graph dependerá de su escenario específico. En este ejemplo, el componente mgt-search-results se usa para simplificar el código y reducir la cantidad de trabajo que tiene que hacer.
Exploración del código de búsqueda de mensajes de chat de Teams
Vuelva a graph.service.ts y busque la
searchChatMessages()
función. Verá que es similar a lasearchFiles()
función que miró anteriormente.- Envía datos de filtro a la API de
/search/query
Microsoft Graph y convierte los resultados en una matriz de objetos que tienen información sobreteamId
,channelId
ymessageId
que coinciden con el término de búsqueda. - Para recuperar los mensajes del canal de Teams, se realiza una segunda llamada a la
/teams/${chat.teamId}/channels/${chat.channelId}/messages/${chat.messageId}
API yteamId
,channelId
ymessageId
se pasan. Esto devuelve los detalles completos del mensaje. - Se realizan tareas de filtrado adicionales y los mensajes resultantes se devuelven del
searchChatMessages()
autor de la llamada.
- Envía datos de filtro a la API de
Abra el archivo chats.component.ts y busque la
search()
función . La ruta de acceso completa al archivo es client/src/app/chats/chats.component.ts. Lasearch()
función llamasearchChatMessages()
a en graph.service.ts y pasa elquery
parámetro a él.override async search(query: string) { this.data = await this.graphService.searchChatMessages(query); }
Los resultados de la búsqueda se asignan a la
data
propiedad del componente y el enlace de datos se usa para recorrer en iteración la matriz de resultados y representar los datos. En este ejemplo se usa un componente de tarjeta material de Angular para mostrar los resultados de la búsqueda.@if (this.data.length) { <div> @for (chatMessage of this.data;track chatMessage.id) { <mat-card> <mat-card-header> <mat-card-title [innerHTML]="chatMessage.summary"></mat-card-title> <!-- <mat-card-subtitle [innerHTML]="chatMessage.body"></mat-card-subtitle> --> </mat-card-header> <mat-card-actions> <a mat-stroked-button color="basic" [href]="chatMessage.webUrl" target="_blank">View Message</a> </mat-card-actions> </mat-card> } </div> }
Envío de un mensaje a un canal de Microsoft Teams
Además de buscar mensajes de chat de Microsoft Teams, la aplicación también permite al usuario enviar mensajes a un canal de Microsoft Teams. Esto se puede hacer llamando al
/teams/${teamId}/channels/${channelId}/messages
punto de conexión de Microsoft Graph.En el código siguiente verá que se crea una dirección URL que incluye los
teamId
valores ychannelId
. Los valores de las variables de entorno se usan para el identificador de equipo y el identificador de canal en este ejemplo, pero esos valores se pueden recuperar dinámicamente, así como con Microsoft Graph. Labody
constante contiene el mensaje que se va a enviar. A continuación, se realiza una solicitud POST y los resultados se devuelven al autor de la llamada.async sendTeamsChat(message: string): Promise<TeamsDialogData> { if (!message) new Error('No message to send.'); if (!TEAM_ID || !CHANNEL_ID) new Error('Team ID or Channel ID not set in environment variables. Please set TEAM_ID and CHANNEL_ID in the .env file.'); const url = `https://graph.microsoft.com/v1.0/teams/${TEAM_ID}/channels/${CHANNEL_ID}/messages`; const body = { "body": { "contentType": "html", "content": message } }; const response = await Providers.globalProvider.graph.client.api(url).post(body); return { id: response.id, teamId: response.channelIdentity.teamId, channelId: response.channelIdentity.channelId, message: response.body.content, webUrl: response.webUrl, title: 'Send Teams Chat' }; }
El aprovechamiento de este tipo de funcionalidad en Microsoft Graph proporciona una excelente manera de mejorar la productivbidad del usuario al permitir que los usuarios interactúen con Microsoft Teams directamente desde la aplicación que ya usan.
Datos de la organización: recuperación de correos electrónicos y eventos de calendario
En el ejercicio anterior ha aprendido a recuperar archivos de OneDrive para la Empresa y chats de Microsoft Teams mediante Microsoft Graph y el componente mgt-search-results del kit de herramientas de Microsoft Graph. También ha aprendido a enviar mensajes a los canales de Microsoft Teams. En este ejercicio, aprenderá a recuperar mensajes de correo electrónico y eventos de calendario de Microsoft Graph e integrarlos en la aplicación.
En este ejercicio, aprenderá a:
- Obtenga información sobre cómo se puede usar el componente web mgt-search-results del kit de herramientas de Microsoft Graph para buscar correos electrónicos y eventos de calendario.
- Obtenga información sobre cómo personalizar el componente mgt-search-results para representar los resultados de búsqueda de forma personalizada.
- Obtenga información sobre cómo llamar directamente a Microsoft Graph para recuperar correos electrónicos y eventos de calendario.
Exploración del código de búsqueda de mensajes de correo electrónico
Sugerencia
Si usa Visual Studio Code, puede abrir archivos directamente seleccionando:
- Windows/Linux: Ctrl + P
- Mac: Cmd + P
A continuación, escriba el nombre del archivo que desea abrir.
En un ejercicio anterior, creó un registro de aplicación en el identificador de Microsoft Entra e inició el servidor de aplicaciones y el servidor de API. También ha actualizado los siguientes valores en el
.env
archivo.ENTRAID_CLIENT_ID=<APPLICATION_CLIENT_ID_VALUE> TEAM_ID=<TEAMS_TEAM_ID> CHANNEL_ID=<TEAMS_CHANNEL_ID>
Asegúrese de que ha completado el ejercicio anterior antes de continuar.
Abra emails.component.html y dedique un momento a examinar el código. La ruta de acceso completa al archivo es client/src/app/emails/emails.component.html.
Busque el componente mgt-search-results :
<mgt-search-results class="search-results" entity-types="message" [queryString]="searchText" (dataChange)="dataChange($any($event))"> <template data-type="result-message"></template> </mgt-search-results>
Este ejemplo del componente mgt-search-results se configura de la misma manera que la que miró anteriormente. La única diferencia es que el atributo se establece
message
en elentity-types
que se usa para buscar mensajes de correo electrónico y se proporciona una plantilla vacía.- El
class
atributo se usa para especificar que lasearch-results
clase CSS se debe aplicar al componente. - El
entity-types
atributo se usa para especificar el tipo de datos que se va a buscar. En este caso, el valor esmessage
. - El
queryString
atributo se usa para especificar el término de búsqueda. - El
dataChange
evento se desencadena cuando cambian los resultados de la búsqueda. Se llama a la función deldataChange()
componente de correos electrónicos, los resultados se le pasan y se actualiza una propiedad denominadadata
en el componente. - Se define una plantilla vacía para el componente. Este tipo de plantilla se usa normalmente para definir cómo se representarán los resultados de la búsqueda. Sin embargo, en este escenario se indica al componente que no represente ningún dato de mensaje. En su lugar, se representarán los datos mediante el enlace de datos estándar (Angular se usa en este caso, pero puede usar cualquier biblioteca o marco que desee).
- El
Busque debajo del componente mgt-search-results en emails.component.html para buscar los enlaces de datos usados para representar los mensajes de correo electrónico. En este ejemplo se recorre en iteración la
data
propiedad y se escribe el asunto del correo electrónico, la vista previa del cuerpo y un vínculo para ver el mensaje de correo electrónico completo.@if (this.data.length) { <div> @for (email of this.data;track $index) { <mat-card> <mat-card-header> <mat-card-title>{{email.resource.subject}}</mat-card-title> <mat-card-subtitle [innerHTML]="email.resource.bodyPreview"></mat-card-subtitle> </mat-card-header> <mat-card-actions> <a mat-stroked-button color="basic" [href]="email.resource.webLink" target="_blank">View Email Message</a> </mat-card-actions> </mat-card> } </div> }
Además de usar el componente mgt-search-results para recuperar mensajes, Microsoft Graph proporciona varias API que también se pueden usar para buscar correos electrónicos. La
/search/query
API que vio anteriormente podría usarse, pero una opción más sencilla es lamessages
API.Para ver cómo llamar a esta API, vuelva a graph.service.ts y busque la
searchEmailMessages()
función. Crea una dirección URL que se puede usar para llamar almessages
punto de conexión de Microsoft Graph y asigna elquery
valor al$search
parámetro . A continuación, el código realiza una solicitud GET y devuelve los resultados al autor de la llamada. El$search
operador busca automáticamente elquery
valor en los campos asunto, cuerpo y remitente.async searchEmailMessages(query:string) { if (!query) return []; // The $search operator will search the subject, body, and sender fields automatically const url = `https://graph.microsoft.com/v1.0/me/messages?$search="${query}"&$select=subject,bodyPreview,from,toRecipients,receivedDateTime,webLink`; const response = await Providers.globalProvider.graph.client.api(url).get(); return response.value; }
El componente de correos electrónicos ubicado en emails.component.ts llama
searchEmailMessages()
a y muestra los resultados en la interfaz de usuario.override async search(query: string) { this.data = await this.graphService.searchEmailMessages(query); }
Exploración del código de búsqueda de eventos de calendario
La búsqueda de eventos de calendario también se puede realizar mediante el componente mgt-search-results . Puede controlar la representación de los resultados, pero también puede definir su propia plantilla que verá más adelante en este ejercicio.
Abra calendar-events.component.html y dedique un momento a examinar el código. La ruta de acceso completa al archivo es client/src/app/calendar-events/calendar-events.component.html. Verá que es muy similar a los archivos y los componentes de correos electrónicos que miró anteriormente.
<mgt-search-results class="search-results" entity-types="event" [queryString]="searchText" (dataChange)="dataChange($any($event))"> <template data-type="result-event"></template> </mgt-search-results>
Este ejemplo del componente mgt-search-results se configura de la misma manera que los que miró anteriormente. La única diferencia es que el atributo se establece
event
en elentity-types
que se usa para buscar eventos de calendario y se proporciona una plantilla vacía.- El
class
atributo se usa para especificar que lasearch-results
clase CSS se debe aplicar al componente. - El
entity-types
atributo se usa para especificar el tipo de datos que se va a buscar. En este caso, el valor esevent
. - El
queryString
atributo se usa para especificar el término de búsqueda. - El
dataChange
evento se desencadena cuando cambian los resultados de la búsqueda. Se llama a la función del componente de evento dedataChange()
calendario, los resultados se le pasan y se actualiza una propiedad denominadadata
en el componente. - Se define una plantilla vacía para el componente. En este escenario se indica al componente que no represente ningún dato. En su lugar, se representarán los datos mediante el enlace de datos estándar.
- El
Inmediatamente debajo del
mgt-search-results
componente de calendar-events.component.html encontrará los enlaces de datos usados para representar los eventos del calendario. En este ejemplo se recorre en iteración ladata
propiedad y se escribe la fecha de inicio, la hora y el asunto del evento. Las funciones personalizadas incluidas en el componente comodayFromDateTime()
ytimeRangeFromEvent()
se llaman para dar formato a los datos correctamente. Los enlaces HTML también incluyen un vínculo para ver el evento de calendario en Outlook y la ubicación del evento si se especifica uno.@if (this.data.length) { <div> @for (event of this.data;track $index) { <div class="root"> <div class="time-container"> <div class="date">{{ dayFromDateTime(event.resource.start.dateTime)}}</div> <div class="time">{{ timeRangeFromEvent(event.resource) }}</div> </div> <div class="separator"> <div class="vertical-line top"></div> <div class="circle"> @if (!this.event.resource.bodyPreview?.includes('Join Microsoft Teams Meeting')) { <div class="inner-circle"></div> } </div> <div class="vertical-line bottom"></div> </div> <div class="details"> <div class="subject">{{ event.resource.subject }}</div> @if (this.event.resource.location?.displayName) { <div class="location"> at <a href="https://bing.com/maps/default.aspx?where1={{event.resource.location.displayName}}" target="_blank" rel="noopener"><b>{{ event.resource.location.displayName }}</b></a> </div> } @if (this.event.resource.attendees?.length) { <div class="attendees"> @for (attendee of this.event.resource.attendees;track attendee.emailAddress.name) { <span class="attendee"> <mgt-person person-query="{{attendee.emailAddress.name}}"></mgt-person> </span> } </div> } @if (this.event.resource.bodyPreview?.includes('Join Microsoft Teams Meeting')) { <div class="online-meeting"> <img class="online-meeting-icon" src="https://img.icons8.com/color/48/000000/microsoft-teams.png" title="Online Meeting" /> <a class="online-meeting-link" href="{{ event.resource.onlineMeetingUrl }}"> Join Teams Meeting </a> </div> } </div> </div> } </div> }
Además de buscar eventos de calendario mediante la
search/query
API, Microsoft Graph también proporciona unaevents
API que también se puede usar para buscar eventos de calendario. Busque lasearchCalendarEvents()
función en graph.service.ts.La
searchCalendarEvents()
función crea valores de fecha y hora de inicio y finalización que se usan para definir el período de tiempo que se va a buscar. A continuación, crea una dirección URL que se puede usar para llamar alevents
punto de conexión de Microsoft Graph e incluye el parámetro y lasquery
variables de fecha y hora de inicio y finalización. A continuación, se realiza una solicitud GET y los resultados se devuelven al autor de la llamada.async searchCalendarEvents(query:string) { if (!query) return []; const startDateTime = new Date(); const endDateTime = new Date(startDateTime.getTime() + (7 * 24 * 60 * 60 * 1000)); const url = `/me/events?startdatetime=${startDateTime.toISOString()}&enddatetime=${endDateTime.toISOString()}&$filter=contains(subject,'${query}')&orderby=start/dateTime`; const response = await Providers.globalProvider.graph.client.api(url).get(); return response.value; }
Este es un desglose de la dirección URL que se crea:
- La
/me/events
parte de la dirección URL se usa para especificar que se deben recuperar los eventos del usuario que ha iniciado sesión. - Los
startdatetime
parámetros yenddatetime
se usan para definir el período de tiempo que se va a buscar. En este caso, la búsqueda devolverá eventos que se inician en los próximos 7 días. - El
$filter
parámetro de consulta se usa para filtrar los resultados por elquery
valor (el nombre de la compañía seleccionado en el datagrid en este caso). Lacontains()
función se usa para buscar elquery
valor en lasubject
propiedad del evento de calendario. - El
$orderby
parámetro de consulta se usa para ordenar los resultados por lastart/dateTime
propiedad .
- La
url
Una vez creado, se realiza una solicitud GET a Microsoft Graph API mediante el valor deurl
y los resultados se devuelven al autor de la llamada.Al igual que con los componentes anteriores, el componente calendar-events (calendar-events.component.ts archivo) llama
search()
a y muestra los resultados.override async search(query: string) { this.data = await this.graphService.searchCalendarEvents(query); }
Nota:
También puede realizar llamadas de Microsoft Graph desde una API personalizada o una aplicación del lado servidor. Consulte el siguiente tutorial para ver un ejemplo de llamada a Microsoft Graph API desde una función de Azure.
Ahora ha visto un ejemplo de uso de Microsoft Graph para recuperar archivos, chats, mensajes de correo electrónico y eventos de calendario. También se pueden aplicar los mismos conceptos a otras API de Microsoft Graph. Por ejemplo, podría usar la API de usuarios de Microsoft Graph para buscar usuarios de su organización. También puede usar la API de grupos de Microsoft Graph para buscar grupos en su organización. Puede ver la lista completa de las API de Microsoft Graph en la documentación.
Felicidades.
Ha completado este tutorial
Felicidades. En este tutorial ha aprendido cómo:
- Azure OpenAI se puede usar para mejorar la productividad del usuario.
- Azure Communication Services se puede usar para integrar las características de comunicación.
- Las API y componentes de Microsoft Graph se pueden usar para recuperar y mostrar datos de la organización.
Mediante el uso de estas tecnologías, puede crear soluciones eficaces que aumenten la productividad del usuario minimizando los cambios de contexto y proporcionando información necesaria sobre la toma de decisiones.
Limpieza de recursos de Azure
Limpie los recursos de Azure para evitar más cargos en su cuenta. Vaya a Azure Portal y elimine los siguientes recursos:
- Recurso de Azure AI Search
- Recurso de Azure Storage
- Recurso de Azure OpenAI (asegúrese de eliminar primero los modelos y, después, el recurso de Azure OpenAI)
- Recurso de Azure Communication Services
Pasos siguientes
Documentación
- Documentación de Azure OpenAI
- Azure OpenAI en los datos
- Documentación de Azure Communication Services
- Documentación de Microsoft Graph
- Documentación del kit de herramientas de Microsoft Graph
- Documentación para desarrolladores de Microsoft Teams
Contenido de formación
- Aplicación de ingeniería de solicitudes con Azure OpenAI Service
- Introducción a Azure OpenAI Service
- Introducción a Azure Communication Services
- Aspectos básicos de Microsoft Graph
- Curso de vídeo: Aspectos básicos de Microsoft Graph para principiantes
- Exploración de escenarios de Microsoft Graph para el desarrollo de JavaScript
- Exploración de escenarios de Microsoft Graph para el desarrollo de ASP.NET Core
- Introducción al kit de herramientas de Microsoft Graph
- Compilación e implementación de aplicaciones para Microsoft Teams con El kit de herramientas de Teams para Visual Studio Code
¿Tiene algún problema con esta sección? Si es así, envíenos sus comentarios para que podamos mejorarla.